【问题标题】:How to Intercept Android Device Volume Up/Down Buttons to Open Camera in Xamarin Forms App?如何拦截 Android 设备音量增大/减小按钮以在 Xamarin Forms 应用程序中打开相机?
【发布时间】:2019-10-10 13:17:00
【问题描述】:

我正在开发一个 Xamarin Forms 应用程序,该应用程序使用蓝牙快门点击器来拍照。目前,蓝牙快门在被点击时会激活音量增大/减小按钮。我试图拦截音量按钮,以便在单击答题器时打开设备摄像头。

我正在尝试让 Android 版本正常工作。 我可以在我的 MainActivity.cs 文件中成功拦截我的 Android 代码中的音量按钮。我想我必须使用依赖服务,以便我的 CameraButton_Clicked 事件由音量按钮触发,但我不知道如何正确执行此操作。任何帮助将不胜感激。

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

【问题讨论】:

    标签: c# .net xamarin xamarin.forms xamarin.android


    【解决方案1】:

    如果你只是想在 android 中实现。你可以像下面的GIF一样直接打开相机。

    您可以在android中拍照,然后使用消息中心将您的图像上传到PCL中,如followcode。

    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

    【讨论】:

    • 非常感谢您的帮助,这对我有用!我最初想使用 DependencyService 以便可以使用媒体插件,但从 Android 活动中打开相机也可以。再次感谢!
    猜你喜欢
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多