[英]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,它会有所不同。
我是这样做的:在 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.