最近在项目中有用到相机的功能,通常用法
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标记,如果想监听是否取消另想办法喽。。