本文共 2570 字,大约阅读时间需要 8 分钟。
背景
针对API 24或更高版本,开发人员需要使用FileProvider(或他们自己的ContentProvider),而不是使用简单的“ Uri.fromFile”命令,才能让其他应用访问该应用的文件.
问题
我尝试使用以下代码打开相机应用程序,使其将文件保存到应用程序的私有存储中:
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final File photoFile = FileHelper.generateTempCameraFile(this);
mCameraCachedImageURI = FileProvider.getUriForFile(this, getPackageName()+ ".provider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraCachedImageURI);
takePictureIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(takePictureIntent, REQ_CODE_PICK_IMAGE_FROM_CAMERA);
provider_paths.xml
清单文件
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
当启动照相机应用程序时,这开始很好,但是在返回的结果中,我无法使用以前可以正常工作的代码来获取图像文件的方向:
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int orientation = getOrientation(this,mCameraCachedImageURI );
...
public static int getOrientation(final Context context, final Uri photoUri) {
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(photoUri,
new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null);
} catch (final Exception ignored) {
}
if (cursor == null) {
// fallback
return getOrientation(photoUri.getPath());
}
int result = 0;
if (cursor.getCount() > 0) {
cursor.moveToFirst();
result = cursor.getInt(0);
}
cursor.close();
return result;
}
public static int getOrientation(final String filePath) {
if (TextUtils.isEmpty(filePath))
return 0;
try {
final ExifInterface exifInterface = new ExifInterface(filePath);
final int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
return rotate;
} catch (final IOException ignored) {
}
return 0;
}
这将崩溃,因为在运行此代码时光标没有任何列.
不仅如此,即使回退功能(在更改代码以使用它时)也不起作用,因为它向文件路径添加了额外的部分(在这种情况下为“外部”).
我发现了什么
似乎contentResolver在这里使用了FileProvider,而不是以前版本的Android所使用的文件.
问题是,我需要此URI的ContentProvider才能授予相机应用访问该文件的权限…
问题
如何使用新的FileProvider Uri使用以上代码(甚至更好的代码)获得方向?也许我可以强制ContentResolver使用以前的ContentProvider来获取光标所需的列数据?
我真的必须在这里创建自己的ContentProvider吗?
转载地址:http://eqnuo.baihongyu.com/