安卓系统android使用C# .NET Xamarin框架调用相机拍照
引言
Xamarin始创于2011年,旨在使移动开发变得难以置信地迅捷和简单。Xamarin的产品简化了针对多种平台的应用开发,包括iOS、Android、Universal Windows Platform、Watch OS、tvOS和Mac App。Xamarin由许多著名的开源社区开发者创立和参与,而且也是Mono项目的主导者——C#与·NET框架的开源、跨平台实现。(摘自“百度百科”)
本文参考Ufinix的视频教程 “ Xamarin Android Tutorials - Capture Image from Camera ”完成。
一、用到的软件、包
1.1 VS2019 community 安装.Net桌面开和使用.Net移动开发;
2.2 安装这两个勾选项后,我这里的组件有.NET Framework4.7.2和Android SDK API 28。
1.3 安装安卓模拟器,勾选“使用c++进行移动开发”,在应用详情里找到Google Android Emulator和Intel硬件加速HAXM两个组件,用来创建安卓模拟器使用。
二、创建Android应用(Xamarin),
安装完,按图中模板创建新项目,当然,第一项Xamarin.Forms肯定也是可以的,它是有点像asp.netcore的MVC架构,即模型,视图,控制器分离,业务逻辑更清晰;
三、增加Nuget中库Xam.Plugin.Media的引用
四、参考引用包Xam.Plugin.Media的readme文件操作;
Android
This library uses Xamarin.Essentials for permissions and other funcationality. Please ensure that you have sset it up correctly:
https://docs.microsoft.com/xamarin/essentials/get-started
protected override void OnCreate(Bundle savedInstanceState) {
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
And for permissions:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
NB: The WRITE_EXTERNAL_STORAGE
, READ_EXTERNAL_STORAGE
permissions are required, but the library will automatically add this for you. Additionally, if your users are running Marshmallow the Plugin will automatically prompt them for runtime permissions. The following has also been added for you: [assembly: UsesFeature(“android.hardware.camera”, Required = false)] [assembly: UsesFeature(“android.hardware.camera.autofocus”, Required = false)] You must also add a few additional configuration files to adhere to the new strict mode:
a1. Add the following to your AndroidManifest.xml inside the tags:
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
a2. Add a new folder called xml into your Resources folder
a3. Add a new XML file called file_paths.xml
and add the following code:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures" />
<external-files-path name="my_movies" path="Movies" />
</paths>
You can read more at: https://developer.android.com/training/camera/photobasics.html
Android:
This plugin uses the Xamarin.Essentials, please follow the setup guide.
Xamarin.Essentials.Platform.Init(this, bundle);
五、搭建Andoid的程序界面和程序逻辑,
5.1 在Resources>layout>activity_main.xml文件/页面中增加一个Button按钮“CaptureButton”和ImageView控件“imageView1”:
<ImageView
android:contentDescription="@string/Photo1"
android:src="@android:drawable/ic_menu_gallery"
android:layout_width="match_parent"
android:layout_height="337.5dp"
android:id="@+id/imageView1" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seekBar1" />
<Button
android:text="@string/Capture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/CaptureButton" />
5.2 在MainActivity.cs中写按钮函数,这里附上该文件的全部源码以供大家参考:
using System;
using Android;
using Android.App;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using Plugin.Media;
namespace XamarinCamera
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
ImageView ImgView1;
Button CaptureButton;
readonly string[] permissionGroup =
{
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.WriteExternalStorage,
Manifest.Permission.Camera
};
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
RequestPermissions(permissionGroup, 0);
CaptureButton = (Button)FindViewById(Resource.Id.CaptureButton);
ImgView1 = (ImageView)FindViewById(Resource.Id.imageView1);
CaptureButton.Click += (object sender, System.EventArgs e) =>
{
TakePhoto();
};
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
fab.Click += FabOnClick;
}
async void TakePhoto()
{
await CrossMedia.Current.Initialize();
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize=Plugin.Media.Abstractions.PhotoSize.Medium,
CompressionQuality=40,
Name="myImage.jpg",
Directory="sample"
});
if (file == null)
{
return;
}
byte[] imageArray = System.IO.File.ReadAllBytes(file.Path);
Bitmap bitmap = BitmapFactory.DecodeByteArray(imageArray, 0, imageArray.Length);
ImgView1.SetImageBitmap(bitmap);
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.action_settings)
{
return true;
}
return base.OnOptionsItemSelected(item);
}
private void FabOnClick(object sender, EventArgs eventArgs)
{
View view = (View) sender;
Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
.SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
}
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);
}
}
}