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 是最狠的,比老美狠多了

浙公网安备 33010602011771号