I have an app with a simple toggle switch that turns the flashlight on and off, I needed code I can use to check if the Flashlight is already on and then use that to change the toggle state of the switch... If the service reports the Flashlight to be on, i will send a broadcast intent to turn it off and vice versa... My app logic is here
class SecondActivity : AppCompatActivity{
protected override void OnCreate(Bundle onSavedInstanceState){
//Switch definition
Switch switch1 = this.FindViewById<Switch>(Resource.Id.switch2);
//Setting the intial status of the switch to be unchecked by default
switch1.Checked=false;
//Adding delegate method to handle switch checked event
switch1.CheckedChange += delegate (object sender, CompoundButton.CheckedChangeEventArgs e)
{
if (e.IsChecked==true)
{
//Switch is on so turn on Flahlight
Flashlight.TurnOnAsync();
Toast.MakeText(Application.Context, "Switch is ON", ToastLength.Long).Show();
}
else
{
//Switch is unchecked so turn off flashlight
Flashlight.TurnOffAsync();
Toast.MakeText(Application.Context, "Switch is OFF", ToastLength.Long).Show();
}
};
//Code to check if flashlight was turned on by an extra app activity
}
}
A user could turn the flashlight on outside the app, so i just need that code to check if its already on, afterwards I will implement broadcast intent to make changes to my switch appropriately, Thanks for your time and contribution
A user could turn the flashlight on outside the app, so i just need that code to check if its already on, afterwards I will implement broadcast intent to make changes to my switch appropriately,
Do you want to achieve the result like following gif?
I wirte two application to achieved:
MyForegroundServiceDemo: Use Broadcast to mintor the flashlight
if is enable or not, to keep the broadcastReceiver always running at the background or foreground, I used forground service to achieve it. then register the broadcastRecevier in foreground serivice.
XAndroidBroadcastRece: just open/close the flashlight.
Here is my MyForegroundServiceDemo code.
First of all, you need add and grand Camera& Flashlightpermission in the AndroidManifest.xml
.
Then, Here is my layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="Please see following switch"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/switch1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button1"
android:text="start"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="Stop"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="123@456"/>
</LinearLayout>
Here is my MainActivity.cs
. I used Button1
to enable the forground service. And expose the Switch
that we can control it in the broadcastReceiver.
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
public static MainActivity Instance;
public static Switch switch1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
Instance = this;
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Button button1 = FindViewById<Button>(Resource.Id.button1);
Button button2 = FindViewById<Button>(Resource.Id.button2);
switch1 = FindViewById<Switch>(Resource.Id.switch1);
button2.Click += Button2_Click;
button1.Click += Button1_Click;
}
Intent intent;
private void Button2_Click(object sender, System.EventArgs e)
{
// throw new System.NotImplementedException();
Android.App.Application.Context.StopService(intent);
}
private void Button1_Click(object sender, System.EventArgs e)
{
intent = new Intent(Android.App.Application.Context, typeof(MyForegroundService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
StartForegroundService(intent);
// Android.App.Application.Context.StartForegroundService(intent);
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Here is code about MyForegroundService.cs
.When we receiver the broadcast In the MyReceiver(BroadcastReceiver)
, we mintor the flashlight's status with MyTorchRegister
using Android.Hardware.Camera2;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Essentials;
namespace ForegroundServiceDemo
{
[Service]
class MyForegroundService : Service
{
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
CreateNotificationChannel();
string messageBody = "service starting";
Clipboard.ClipboardContentChanged += Clipboard_ClipboardContentChanged;
// / Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this,typeof(Activity1));
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this);
stackBuilder.AddNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, PendingIntentFlags.UpdateCurrent);
var notification = new Notification.Builder(this, "10111")
.SetContentIntent(resultPendingIntent)
.SetContentTitle("Foreground")
.SetContentText(messageBody)
.SetSmallIcon(Resource.Drawable.main)
.SetOngoing(true)
.Build();
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
MyReceiver receiver = new MyReceiver();
RegisterReceiver(receiver, new IntentFilter("com.Java_Tutorial.CUSTOM_INTENT"));
return StartCommandResult.Sticky;
}
private async void Clipboard_ClipboardContentChanged(object sender, EventArgs e)
{
//throw new NotImplementedException();
var text = await Clipboard.GetTextAsync();
Toast.MakeText(this, text, ToastLength.Long).Show();
if (text.Contains("@"))
{
await Clipboard.SetTextAsync(text.Replace("@", ""));
}
}
public override void OnDestroy()
{
base.OnDestroy();
Clipboard.ClipboardContentChanged -= Clipboard_ClipboardContentChanged;
StopForeground(true);
}
public override IBinder OnBind(Intent intent)
{
return null;
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
return;
}
var channelName = Resources.GetString(Resource.String.channel_name);
var channelDescription = GetString(Resource.String.channel_description);
var channel = new NotificationChannel("10111", channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
}
//do you work
[BroadcastReceiver(Enabled = true, Exported = true)]
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
CameraManager cameraManager = (CameraManager)context.GetSystemService(Context.CameraService);
var flashAvailable = cameraManager.GetCameraCharacteristics("0").Get(CameraCharacteristics.FlashInfoAvailable);
cameraManager.RegisterTorchCallback(new MyTorchRegister(), null);
if (MyTorchRegister.isFlashlightOn) {
MainActivity.switch1.Checked = false;
// Toast.MakeText(context, "FlashLight is disabled", ToastLength.Long).Show();
}
else
{
MainActivity.switch1.Checked = true;
// Toast.MakeText(context, "FlashLight is Opened", ToastLength.Long).Show();
}
}
internal class MyTorchRegister : CameraManager.TorchCallback
{
public static bool isFlashlightOn = false;
public override void OnTorchModeChanged(string cameraId, bool enabled)
{
base.OnTorchModeChanged(cameraId, enabled);
isFlashlightOn = enabled;
}
}
}
}
Here is XAndroidBroadcastRece demo code
Switch switch1 = this.FindViewById<Switch>(Resource.Id.switch1);
//Setting the intial status of the switch to be unchecked by default
switch1.Checked = false;
//Adding delegate method to handle switch checked event
switch1.CheckedChange += delegate (object sender, CompoundButton.CheckedChangeEventArgs e)
{
if (e.IsChecked == true)
{
//Switch is on so turn on Flahlight
Flashlight.TurnOnAsync();
Intent intent = new Intent();
intent.SetAction("com.Java_Tutorial.CUSTOM_INTENT");
SendBroadcast(intent);
Toast.MakeText(Application.Context, "Switch is ON", ToastLength.Long).Show();
}
else
{
//Switch is unchecked so turn off flashlight
Flashlight.TurnOffAsync();
Intent intent = new Intent();
intent.SetAction("com.Java_Tutorial.CUSTOM_INTENT");
SendBroadcast(intent);
Toast.MakeText(Application.Context, "Switch is OFF", ToastLength.Long).Show();
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.