简体   繁体   English

检测闪光灯是否已经打开

[英]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?你想达到如下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. MyForegroundServiceDemo:无论是否启用,使用广播来监控flashlight ,为了让广播接收器始终运行在后台或前台,我使用了 forground 服务来实现它。 then register the broadcastRecevier in foreground serivice.然后在前台服务中注册broadcastRecevier。

  2. XAndroidBroadcastRece: just open/close the flashlight. XAndroidBroadcastRece:只需打开/关闭手电筒。

Here is my MyForegroundServiceDemo code.这是我的 MyForegroundServiceDemo 代码。

First of all, you need add and grand Camera& Flashlightpermission in the AndroidManifest.xml .首先,您需要在AndroidManifest.xml添加和 Grand Camera& Flashlightpermission。

Then, Here is my layout.xml然后,这是我的 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 .这是我的MainActivity.cs I used Button1 to enable the forground service.我使用Button1来启用前台服务。 And expose the Switch that we can control it in the broadcastReceiver.并在broadcastReceiver中暴露我们可以控制它的Switch

   [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以下是有关的代码MyForegroundService.cs 。当我们接收器广播在MyReceiver(BroadcastReceiver) ,我们mintor手电筒与地位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这是 XAndroidBroadcastRece 演示代码

  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();
                }
            };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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