简体   繁体   中英

Detect if flash light is already turned on

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:

  1. 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.

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM