【问题标题】:Unable to read files Uri shared by other app i.e. Whatsapp无法读取其他应用程序(即 Whatsapp)共享的文件 Uri
【发布时间】:2019-07-10 13:29:11
【问题描述】:

当其他应用程序通过 FileProvider 共享文件时,我的应用程序中收到的 Uri 不可读。如果我尝试获取文件路径或从中创建文件,那么它会说文件不存在。示例 Uri 来自 whatsapp 是 content://com.whatsapp.provider.media/item/91836 。当我尝试从 Uri 读取位图时,它会出现安全异常。

代码行是onCreate方法:

Uri mediaUri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), mediaUri);

清单:

<activity
        android:name=".ui.main.MainActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustNothing">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />

            <data android:mimeType="image/*" />
            <data android:mimeType="video/mp4" />
            <!--<data android:mimeType="video/*" />-->
        </intent-filter>
    </activity>

例外:

Caused by: java.lang.SecurityException: Permission Denial: opening provider com.whatsapp.MediaProvider from ProcessRecord{fbda37f 23891:com.fayvo/u0a273} (pid=23891, uid=10273) that is not exported from UID 10133
        at android.os.Parcel.createException(Parcel.java:1953)
        at android.os.Parcel.readException(Parcel.java:1921)
        at android.os.Parcel.readException(Parcel.java:1871)
        at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:4159)
        at android.app.ActivityThread.acquireProvider(ActivityThread.java:6759)
        at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2912)
        at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1879)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1460)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1313)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1033)
        at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:919)

【问题讨论】:

  • 请提供minimal reproducible example。这将包括您如何获得Uri 以及您尝试在何处使用Uri。请记住by default only the activity that receives the Uri can use it.
  • 更新了代码行,只是我分享了whatsapp聊天中的图片,它没有加载到我的应用程序中
  • 如果这两行是连续的(例如,在您的ACTION_VIEW 活动的onCreate() 中),并且您正在获得Uri,如EXTRA_STREAM 所示,那么这似乎是WhatsApp 中的一个错误。
  • 但是其他应用程序如何使用它。当我从 whatsapp 的外部存储共享图像时,我的相同代码工作正常。在这种情况下,问题似乎与似乎私有的 uri 有关。
  • “但其他应用程序如何使用它” - 我无法回答。您的实现中可能存在错误,但我们只有两行代码可供查看,因此任何人都很难为您提供更具体的建议。

标签: android uri deep-linking android-fileprovider share-intent


【解决方案1】:

在这些情况下使用这种方法对我有用:

private File readSharedContentUri(Uri contentUri) {
    // Get content resolver.
    ContentResolver contentResolver = getContentResolver();
    File targetFile = null;
    try {
        InputStream inputStream = contentResolver.openInputStream(contentUri);
        byte[] buffer = new byte[inputStream.available()];
        inputStream.read(buffer);
        targetFile = PathUtil.getFilePath(context, true, "received_media_" + System.currentTimeMillis(), CommonUtils.isMimeTypeOfImage(contentResolver.getType(contentUri)) ? ".jpg" : ".mp4");
        inputStream.close();
        OutputStream outStream = new FileOutputStream(targetFile);
        outStream.write(buffer);
        outStream.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    return targetFile;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-15
    • 2018-04-15
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2016-09-09
    • 1970-01-01
    相关资源
    最近更新 更多