使用 targetSdkVersion 25 访问相机时出现问题?
Problems with accessing camera with targetSdkVersion 25?
我有一个使用相机的应用程序,当我用 targetSdkVersion 23
编译它时它工作正常,但是当我尝试使用 version 25
时我得到这个错误:
android.os.FileUriExposedException:
file:///storage/emulated/0/DCIM/IMG_1093948364.jpg exposed beyond app
through ClipData.Item.getUri()
这是我正在使用的代码:
private void showCameraAction() {
if(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
getString(R.string.mis_permission_rationale_write_storage),
REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
}else {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
try {
mTmpFile = FileUtils.createTmpFile(getActivity());
} catch (IOException e) {
e.printStackTrace();
}
if (mTmpFile != null && mTmpFile.exists()) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
startActivityForResult(intent, REQUEST_CAMERA);
} else {
Toast.makeText(getActivity(), R.string.mis_error_image_not_exist, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getActivity(), R.string.mis_msg_no_camera, Toast.LENGTH_SHORT).show();
}
}
}
private void requestPermission(final String permission, String rationale, final int requestCode){
if(shouldShowRequestPermissionRationale(permission)){
new AlertDialog.Builder(getContext())
.setTitle(R.string.mis_permission_dialog_title)
.setMessage(rationale)
.setPositiveButton(R.string.mis_permission_dialog_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, requestCode);
}
})
.setNegativeButton(R.string.mis_permission_dialog_cancel, null)
.create().show();
}else{
requestPermissions(new String[]{permission}, requestCode);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == REQUEST_STORAGE_WRITE_ACCESS_PERMISSION){
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
showCameraAction();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
我该怎么办?谢谢
您的 FileUtils.createTmpFile(getActivity());
可能使用 file:// URI 与其他应用程序(在您的情况下是相机)共享文件。
Android 大于 24 的版本使用 content:// URI,当您尝试使用 file:// URI 直接共享文件时将抛出此异常。
内容 URI 允许您使用临时访问权限授予读写权限
看看FileProvider。
解决方案:
更改了这个:
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
为此:
//getActivity() because its a fragment
Uri uri = FileProvider.getUriForFile(getActivity(),
getActivity().getPackageName()
, mTmpFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
成功了。
我有一个使用相机的应用程序,当我用 targetSdkVersion 23
编译它时它工作正常,但是当我尝试使用 version 25
时我得到这个错误:
android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_1093948364.jpg exposed beyond app through ClipData.Item.getUri()
这是我正在使用的代码:
private void showCameraAction() {
if(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
getString(R.string.mis_permission_rationale_write_storage),
REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
}else {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
try {
mTmpFile = FileUtils.createTmpFile(getActivity());
} catch (IOException e) {
e.printStackTrace();
}
if (mTmpFile != null && mTmpFile.exists()) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
startActivityForResult(intent, REQUEST_CAMERA);
} else {
Toast.makeText(getActivity(), R.string.mis_error_image_not_exist, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getActivity(), R.string.mis_msg_no_camera, Toast.LENGTH_SHORT).show();
}
}
}
private void requestPermission(final String permission, String rationale, final int requestCode){
if(shouldShowRequestPermissionRationale(permission)){
new AlertDialog.Builder(getContext())
.setTitle(R.string.mis_permission_dialog_title)
.setMessage(rationale)
.setPositiveButton(R.string.mis_permission_dialog_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, requestCode);
}
})
.setNegativeButton(R.string.mis_permission_dialog_cancel, null)
.create().show();
}else{
requestPermissions(new String[]{permission}, requestCode);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == REQUEST_STORAGE_WRITE_ACCESS_PERMISSION){
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
showCameraAction();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
我该怎么办?谢谢
您的 FileUtils.createTmpFile(getActivity());
可能使用 file:// URI 与其他应用程序(在您的情况下是相机)共享文件。
Android 大于 24 的版本使用 content:// URI,当您尝试使用 file:// URI 直接共享文件时将抛出此异常。
内容 URI 允许您使用临时访问权限授予读写权限
看看FileProvider。
解决方案:
更改了这个:
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
为此:
//getActivity() because its a fragment
Uri uri = FileProvider.getUriForFile(getActivity(),
getActivity().getPackageName()
, mTmpFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
成功了。