Android 7.0使用相机功能

最近在项目中有用到相机的功能,通常用法

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        |Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
   //file是图片路劲
    Uri uri = Uri.fromFile(file);
    intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
    //设置MediaStore.EXTRA_OUTPUT的输出路径为imageFileUri
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    activity.startActivityForResult(intent, requestCode);

这样就可以调转相机,前两天还好好的呢,可是今天发现不行了,直接就崩溃了。。错误日志如下,权限异常了。。。

android.os.FileUriExposedException:         file:///storage/emulated/0/DCIM/IMG_1041503431.jpg

看了下源码,在targetSdk>=24的时候就得使用content://了

//创建一个图片保存的Uri 在7.0上必须使用contentProvider创建,否则会崩

ContentValues contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());          uri=activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

这时候在7.0手机上运行发现没事了,可是在低版本上运行,就又不行了,所以还得做下区分,最终的使用姿势

  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
            | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    Uri uri;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        //创建一个图片保存的Uri 在7.0上必须使用contentProvider创建,否则会崩
        ContentValues contentValues = new ContentValues(1);
        contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
        uri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
    } else {
        uri = Uri.fromFile(file);
    }
    intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
    //设置MediaStore.EXTRA_OUTPUT的输出路径为imageFileUri
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    activity.startActivityForResult(intent, requestCode);

就是判断下版本>=24的时候就使用contentValues这种方式,当然还有一种就是在清单文件中注册contentProvider的方式,如下:


     //在res目录下定义的filepaths.xml文件,名字可以自定义

还需要在res文件夹下创建xml文件夹,在创建filePath.xml









   
    

上面注释各个标签的意思已经写清楚了。用哪个看你自己了。。

使用的姿势如下,代替了contentValues那些

一定要注意这里的com.test.test.fileprovider一定要与清单文件中的一样,否则会报错滴。。
 Uri uriForFile = FileProvider.getUriForFile(getActivity(), "com.renwohua.conch.fileprovider", mCameraFile);    intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, uriForFile);          intentFromCapture.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);      intentFromCapture.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

还有一个就是安装apk,这是都会用的吧。也是前两天用

 Intent installIntent = new Intent(Intent.ACTION_VIEW);
 installIntent.addCategory(Intent.CATEGORY_DEFAULT);
 installIntent.setDataAndType(Uri.fromFile(apkFile),"application/vnd.android.package-archive");
 activity.startActivityForResult(installIntent,0x1001);

这样使用没有问题,问了监听是否安装使用了forResult,可是今天在7.0上就完蛋了。。。。一看还是一样的错误,又不行了,需要使用contentProvider来获取路径,真坑啊,忽然就改了,,,幸好还没上线。。。解决办法如下:

  Intent installIntent = new Intent(Intent.ACTION_VIEW);          installIntent.addCategory(Intent.CATEGORY_DEFAULT);        installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {        installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  String providerString = getFileProviderString(activity);
 Uri uri = FileProvider.getUriForFile(activity.getApplicationContext(), providerString, apkFile);
        installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
    } else {
        installIntent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
    }
    activity.getApplication().startActivity(installIntent);

在这里不能使用forResult了,因为使用了Intent.FLAG_ACTIVITY_NEW_TASK标记,如果想监听是否取消另想办法喽。。

你可能感兴趣的:(android)