簡體   English   中英

如何在 Xamarin Forms App 中攔截 Android 設備音量增大/減小按鈕以打開相機?

[英]How to Intercept Android Device Volume Up/Down Buttons to Open Camera in Xamarin Forms App?

我正在開發一個 Xamarin Forms 應用程序,該應用程序使用藍牙快門點擊器拍照。 目前,藍牙快門在被點擊時會激活音量增大/減小按鈕。 我正在嘗試攔截音量按鈕,以便在單擊答題器時打開設備攝像頭。

我正在嘗試使 Android 版本正常工作。 我可以成功攔截 MainActivity.cs 文件中 Android 代碼中的音量按鈕。 我想我必須使用依賴服務,以便我的 CameraButton_Clicked 事件由音量按鈕觸發,但我不知道如何正確 go 這樣做。 任何幫助將不勝感激。

MainActivity.CS:

//override the volume up/down buttons for bluetooth shutter clicker
        public override bool OnKeyUp(Keycode keyCode, KeyEvent e)
        {
            if (keyCode == Keycode.VolumeDown)
            {
                return true;
            }

            if (keyCode == Keycode.VolumeUp)
            {
                return true;
            }
            return base.OnKeyUp(keyCode, e);
        }
        public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
        {
            if (keyCode == Keycode.VolumeDown)
            {
                return true;
            }

            if (keyCode == Keycode.VolumeUp)
            {
                return true;
            }
            return base.OnKeyDown(keyCode, e);
        }

界面:

namespace MyApp
{
    public interface IBluetoothClicker 
    {
       object GetVolumeOverride();

    }
}

BluetoothClicker_Droid.cs:

[assembly: Xamarin.Forms.Dependency (typeof (BluetoothClicker_Droid))]
namespace MyApp.Droid
{
    public class BluetoothClicker_Droid: IBluetoothClicker
    {

        public BluetoothClicker_Droid ()
        {
        }

        public object GetVolumeOverride()
        {         
            //CameraButton_Clicked = true;

            return true;

        }
    }
}

CameraPage.xaml.cs:

public CameraPage()
        {
            InitializeComponent();

            CameraImage.Source = "CameraImage.png";
            TakePhotoButton.Clicked += CameraButton_Clicked; //opens camera

            Func<object> func = () =>
            {
                var obj = DependencyService.Get<IBluetoothClicker>().GetVolumeOverride();
                //obj += CameraButton_Clicked;
                return obj;
            };
        }

如果您只想在 android 中實現這一點。 你可以像下面的GIF一樣直接打開相機。

在此處輸入圖像描述

您可以在 android 中拍照,然后使用消息中心將您的圖像上傳到 PCL 中,如跟隨代碼。

MainPage.xaml.cs

      public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        CameraImage.Source = "CameraImage.png";


        MessagingCenter.Subscribe<App, string>(App.Current, "OpenPage", (snd, arg) =>
        {
            Device.BeginInvokeOnMainThread(() => {
                CameraImage.Source = arg;
            });
        });
    }   
}

MainActivity.cs

       public static class App_test
{
    public static File _file;
    public static File _dir;
    public static Bitmap bitmap;
}

[Activity(Label = "InterceptButton", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.SetVmPolicy(builder.Build());
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);


        LoadApplication(new App());

        if (IsThereAnAppToTakePictures())
        {
            CreateDirectoryForPictures();
        }
    }
    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);
    }

    public override bool OnKeyUp([GeneratedEnum] Keycode keyCode, KeyEvent e)
    {
        if (keyCode == Keycode.VolumeDown)
        {
            Toast.MakeText(this, "OnKeyUp-VolumeDown", ToastLength.Short).Show();


            return true;
        }

        if (keyCode == Keycode.VolumeUp)
        {
          //  Toast.MakeText(this, "OnKeyUp-VolumeUp", ToastLength.Short).Show();
            return true;
        }

        return base.OnKeyUp(keyCode, e);
    }
    public override bool OnKeyDown([GeneratedEnum] Keycode keyCode, KeyEvent e)
    {
        if (keyCode == Keycode.VolumeDown)
        {
            Toast.MakeText(this, "OnKeyDown-VolumeDown", ToastLength.Short).Show();
            return true;
        }

        if (keyCode == Keycode.VolumeUp)
        {
            Intent intent = new Intent(MediaStore.ActionImageCapture);
               App_test._file = new File(App_test._dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid()));
               intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App_test._file));
            StartActivityForResult(intent, 0);
            Toast.MakeText(this, "OnKeyDown-VolumeUp", ToastLength.Short).Show();
            return true;
        }
        return base.OnKeyDown(keyCode, e);
    }


    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
        Uri contentUri = Uri.FromFile(App_test._file);
        mediaScanIntent.SetData(contentUri);
        SendBroadcast(mediaScanIntent);

        App_test.bitmap = App_test._file.Path.LoadAndResizeBitmap(100, 100);
       string path= App_test._file.Path;
        if (App_test.bitmap != null)
        {
            MessagingCenter.Send<App, string>(App.Current as App, "OpenPage", path);

            App_test.bitmap = null;
        }
        GC.Collect();
    }

    private void CreateDirectoryForPictures()
    {
        App_test._dir = new File(
            Environment.GetExternalStoragePublicDirectory(
                Environment.DirectoryPictures), "CameraAppDemo");
        if (!App_test._dir.Exists())
        {
            App_test._dir.Mkdirs();
        }
    }

    private bool IsThereAnAppToTakePictures()
    {
        Intent intent = new Intent(MediaStore.ActionImageCapture);
        IList<ResolveInfo> availableActivities =
            PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
        return availableActivities != null && availableActivities.Count > 0;
    }
}

所以我不知道你為什么要使用DependencyService 。也許你有更好的方法來實現這一點。

有我的演示。 我使用的是 VS 2019,如果你使用的是 VS 2017,它會有所不同。

https://github.com/851265601/InterceptButton

我是這樣做的:在 MainActivity.cs 中:

public override bool OnKeyUp([GeneratedEnum] Keycode keyCode, KeyEvent e)
    {
        if (keyCode == Keycode.VolumeDown)
        {
            var vm = MainViewModel.GetInstance().YourPageName;
            if (vm != null && App.Navigator.CurrentPage.GetType().Name == "YourPagePage")
            {
                vm.GuardarRecorrido();
                return true;
            }
        }

        return base.OnKeyUp(keyCode, e);
    }

我詢問了名稱,因此音量鍵僅在該頁面中運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM