如何获取从FileProvider类获取的图像文件的方向? [英] How to get orientation of image file, which was taken from FileProvider class?

查看:207
本文介绍了如何获取从FileProvider类获取的图像文件的方向?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Targeting API 24或更高版本,开发人员需要使用FileProvider(或他们自己的ContentProvider),而不是使用简单的"Uri.fromFile"命令,才能让其他应用访问该应用的文件.

Targeting API 24 or above, instead of using a simple "Uri.fromFile" command, developers need to use FileProvider (or their own ContentProvider), in order to let other apps to access the app's files.

我尝试使用以下代码打开相机应用程序,使其将文件保存到应用程序的私有存储中:

I try to open a camera app to let it save a file into my app's private storage, using this code:

    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

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

清单文件

    <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/provider_paths"/>
    </provider>

启动相机应用程序后,这开始就很好,但是在返回的结果中,我无法使用以前可以正常运行的代码来获取图像文件的方向:

This starts fine, as the camera app is launched, but in the returned result, I fail to get the orientation of the image file using code that previously worked fine:

@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;
}

这将崩溃,因为运行此代码时光标没有任何列.

This will crash, because the cursor doesn't have any columns while running this code.

不仅如此,即使回退功能(在更改代码以使用它时)也不起作用,因为它在文件路径中添加了另一部分(在这种情况下为外部").

Not only that, but even the fallback function (when changing the code to use it) doesn't work, as it adds an additional part to the path of the file ("external" in this case).

似乎contentResolver在这里使用的是FileProvider,而不是以前版本的Android中使用的文件.

It seems that the contentResolver uses the FileProvider here, instead of what was used on previous versions of Android.

问题是,我需要此URI的ContentProvider才能授予相机应用访问该文件的权限...

Thing is, I need the ContentProvider of this URI in order to grant the camera app permission to access this file...

如何使用新的FileProvider Uri使用以上代码(甚至更好的代码)来获得方向?也许我可以强制ContentResolver使用以前的ContentProvider来获取光标所需的列数据?

How do I get the orientation using the above code (or even a better code), using the new FileProvider Uri ? Maybe I can force the ContentResolver to use the previously ContentProvider to get the needed column's data of the cursor?

我真的必须在这里创建自己的ContentProvider吗?

Do I really have to create my own ContentProvider here?

推荐答案

Uri不是文件.您正在Uri上调用getPath()并将其视为文件路径.仅当Uri中的方案为file时,这才有效.就您而言,事实并非如此.

A Uri is not a file. You are calling getPath() on a Uri and are treating it as if it were a file path. That only works if the scheme in the Uri is file. In your case, it is not.

您已经有一个File对象指向该文件.它称为photoFile.保留活动区域中的内容,然后将其保存为已保存实例状态Bundle(因为在照相机应用程序处于前台时,您的过程可能会终止).然后,使用photoFile.不过请不要使用内置的ExifInterface,因为

You already have a File object pointing to the file. It is called photoFile. Hold onto that in a field of your activity, and save it in the saved instance state Bundle (as your process might get terminated while the camera app is in the foreground). Then, use photoFile. Don't use the built-in ExifInterface though, as it has security flaws.

如何使用新的FileProvider Uri使用上面的代码(甚至更好的代码)来获得方向?

How do I get the orientation using the above code (or even a better code), using the new FileProvider Uri ?

你不知道.使用photoFile.

也许我可以强制ContentResolver使用以前的ContentProvider来获取光标所需的列数据?

Maybe I can force the ContentResolver to use the previously ContentProvider to get the needed column's data of the cursor?

我不知道为什么您会期望使用UrigetOrientation()起作用.您正在查询MediaStore以获得与Uri无关的数据.

I have no idea why you would expect the getOrientation() that takes a Uri to work. You are querying the MediaStore for data about a Uri that does not come from the MediaStore.

我真的必须在这里创建自己的ContentProvider吗?

Do I really have to create my own ContentProvider here?

否,因为FileProvider不是您的问题.您将有与自己的ContentProvider相同的有缺陷的getOrientation()方法.

No, because FileProvider is not your problem. You would have the same flawed getOrientation() methods with your own ContentProvider.

这篇关于如何获取从FileProvider类获取的图像文件的方向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆