安卓调用系统相机进行拍照,并指定路径保存照片(解决Android7.0之后调用相机程序崩溃问题)

本文记录安卓开发关于调用系统相机问题,以及7.0之后调用相机崩溃问题

一、安卓调用系统相机需要的权限


 
 
<!-- 读写sd卡的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 调用相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />


二、调用相机进行拍照

方式1:这种方式所得的图不会保存在图库中,且得到的图为缩略图

 
 
 
 
public void imageCapture(View view){
    Intent intent = new Intent();
    intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent,MEDIA_TYPE_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case MEDIA_TYPE_IMAGE:
                Bundle bundle = data.getExtras();
                //获取相机返回的数据,并转换为图片格式
                Bitmap photo = (Bitmap)bundle.get("data");
                // TODO:  可以将photo用来显示
                break;
        }
    }
}


方式二:指定路径保存照片,得到的是原图

 
 
public void imageCapture(View view){
    Intent intent = new Intent();
    intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,getOutPutMediaFilePath(MEDIA_TYPE_IMAGE));
    //让照片输出到指定路径
    startActivityForResult(intent,MEDIA_TYPE_IMAGE);
}
@Override 

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

      super.onActivityResult(requestCode, resultCode, data); 

      if (resultCode == RESULT_OK){ 

          switch (requestCode){ 

               case MEDIA_TYPE_IMAGE: 

                 Bitmap bitmap = BitmapFactory.decodeFile(path); 

                 imageView.setImageBitmap(bitmap); break; 

                 } 

         } 

 }

//安卓7.0之后崩溃的问题就在这里,我通过使用fileprovider。Uri uri = Uri.parse("file://"+ path); 按照Android 7.0的要求,若要在应用间共享文件,应发送一项content://uri,并授予 URI 临时访问权限。 

public Uri getOutPutMediaFilePath(int type){ 

     File file = getOutPutMediaFile(type); 

     path=file.getAbsolutePath(); 

     if (Build.VERSION.SDK_INT>=24) { 

            return FileProvider.getUriForFile(this, getPackageName() + ".provider", file); 

     }else { 

            return Uri.fromFile(file); 

     } 

 } 

public File getOutPutMediaFile(int type){ 

     File file = null; 

     String rootPath = null; 

     switch (type){ 

        case MEDIA_TYPE_IMAGE: 

            rootPath=Environment.getExternalStoragePublicDirectory(

                Environment.DIRECTORY_PICTURES).getPath(); 

             file = new File(rootPath+"/"+System.currentTimeMillis()+".jpg"); 

            break; 

     } 

return file; 

 }



fileprovider的使用:

在AndroidManifest中添加

 
 
<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">
……
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"  
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_path" />
</provider>
//exported应设为false,否则会报安全异常
  //grantURIPermissions为true,表示授予URI临时访问权限

……

</application>
创建xml/file_path文件

 
 
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="camera_photo"
        path="Pictures"/>
</paths>


当然调用相机还需要添加动态权限,百度有方法。

还有个问题就是刚跳转到相机就调用了onActivityResult方法,这是因为intent的flag设置了Intent.FLAG_ACTIVITY_NEW_TASK(之前我遇到的问题)。

学习记录,刚刚处理完问题,逻辑写的还有点乱,如有错误和不足,欢迎大家指出 。

猜你喜欢

转载自blog.csdn.net/qq_40861368/article/details/80171339