Xamarin.Andorid 调用相机拍照
https://www.jianshu.com/p/29b349ff7f1a
第一步:XML布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/take_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="调用摄像头拍照"
android:textSize="20sp" />
<ImageView
android:id="@+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="description"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
第二步:添加权限
<uses-permission android:name=”android.permission.INTERNET” />
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
<uses-permission android:name=”android.permission.CAMERA” />
<uses-permission android:name=”android.permission.MANAGE_DOCUMENTS” />
<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” />
<uses-permission android:name=”android.permission.READ_USER_DICTIONARY” />
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />
<uses-permission android:name=”android.permission.WRITE_USER_DICTIONARY” />
第三步:application添加内容提供者
说明:在<application></application>中,但不在<Activity></Activity>中
<!-- 为调用相机拍照设置内容提供者 --> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.example.mydemo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
第四步:为application添加属性值
<!-- android:requestLegacyExternalStorage="true"--> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true" > <!-- 为调用相机拍照设置内容提供者 --> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.example.mydemo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
第五步:在Resources中新建文件夹xml并创建file_paths.xml布局文件
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="."/> </paths>
第六步:activity实现
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)] public class MainActivity : AppCompatActivity { public const int TAKE_PHOTO = 1;//声明一个请求码,用于识别返回的结果 private ImageView picture; private Android.Net.Uri imageUri; private Button CaptureButton; private String filePath = Android.OS.Environment.ExternalStorageDirectory + File.Separator + "output_image.jpg"; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); SetContentView(Resource.Layout.activity_main); RequestPermissions(LuoPermission.LuoPermissionList, 0); CaptureButton = (Button)FindViewById(Resource.Id.take_photo); picture = (ImageView)FindViewById(Resource.Id.picture); CaptureButton.Click += (object sender, System.EventArgs e) => { TakePhoto(); }; SetDefualtImage(); } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } void TakePhoto() { requestPermission(); } //动态请求权限 private void requestPermission() { if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != Permission.Granted) { //请求权限 ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.WriteExternalStorage, Manifest.Permission.Camera }, 1); } else { //调用 requestCamera(); } } private void requestCamera() { File outputImage = new File(filePath); /* 创建一个File文件对象,用于存放摄像头拍下的图片,我们把这个图片命名为output_image.jpg 并把它存放在应用关联缓存目录下,调用getExternalCacheDir()可以得到这个目录,为什么要 用关联缓存目录呢?由于android6.0开始,读写sd卡列为了危险权限,使用的时候必须要有权限, 应用关联目录则可以跳过这一步 */ try//判断图片是否存在,存在则删除在创建,不存在则直接创建 { if (!outputImage.ParentFile.Exists()) { outputImage.ParentFile.Mkdirs(); } if (outputImage.Exists()) { outputImage.Delete(); } outputImage.CreateNewFile(); if (Build.VERSION.SdkInt >= (BuildVersionCodes)24) { imageUri = FileProvider.GetUriForFile(this, "com.example.mydemo.fileprovider", outputImage); } else { imageUri = Android.Net.Uri.FromFile(outputImage); } //使用隐示的Intent,系统会找到与它对应的活动,即调用摄像头,并把它存储 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); intent.PutExtra(MediaStore.ExtraOutput, imageUri); StartActivityForResult(intent, TAKE_PHOTO); //调用会返回结果的开启方式,返回成功的话,则把它显示出来 } catch (IOException e) { e.PrintStackTrace(); } } protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); switch (requestCode) { case TAKE_PHOTO: if (resultCode == Result.Ok) { try { Bitmap bitmap = BitmapFactory.DecodeStream(ContentResolver.OpenInputStream(imageUri)); picture.SetImageBitmap(bitmap); //将图片解析成Bitmap对象,并把它显现出来 } catch (FileNotFoundException e) { e.PrintStackTrace(); } } break; default: break; } } //处理返回结果的函数,下面是隐示Intent的返回结果的处理方式,具体见以前我所发的intent讲解 public override void OnActivityReenter(int resultCode, Intent data) { base.OnActivityReenter(resultCode, data); } //设置保存拍照图片——>再次关闭app重新打开显示为上次拍照照片 private void SetDefualtImage() { File outputImage = new File(filePath); if (!outputImage.Exists()) { return; } picture.SetImageBitmap(BitmapFactory.DecodeFile(filePath)); } }
Github 地址:https://github.com/LuoCoreTestDeom/Android-PaiZhao-Photograph
不能放在gitee :因为这个东西太坑了,比github 还要坑,C坑C 是最狠的,比老美狠多了