FileUriExposedException異常處理

前幾天手一癢,把項目的targetSdkVersion改成最新的25, 今天打開App,發現拍照功能不正常, 網上查了很多資料,總結如下:

官方對FileUriExposedException的解釋

The exception that is thrown when an application exposes a file:// Uri to another app. This exposure is discouraged since the receiving app may not have access to the shared path. For example, the receiving app may not have requested the READ_EXTERNAL_STORAGE runtime permission, or the platform may be sharing the Uri across user profile boundaries.Instead, apps should use content:// Uris so the platform can extend temporary permission for the receiving app to access the resource.This is only thrown for applications targeting N or higher. Applications targeting earlier SDK versions are allowed to share file:// Uri, but it's strongly discouraged.

解決步驟

step 1:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <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>
    </application>
</manifest>

step 2:
添加 provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="cache" path="."/>
</paths>

step 3:

 Intent intentTmp = new Intent("android.media.action.IMAGE_CAPTURE");
                    intentTmp.putExtra(MediaStore.EXTRA_OUTPUT,
                            getCaptureImageOutputUri(mContext));
                    intentTmp.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    startActivityForResult(intentTmp, REQUESTCODE_FROM_CAMERA);
 public Uri getCaptureImageOutputUri(@NonNull Context context) {
        Uri outputFileUri = null;
        File getImage = context.getExternalCacheDir();
        if (getImage != null) {
            if (Build.VERSION.SDK_INT >= 24) {
                outputFileUri = FileProvider.getUriForFile(context,
                        context.getApplicationContext().getPackageName() + ".provider",
                        new File(getImage.getPath(), photoNameString));
            } else {
                outputFileUri = Uri.fromFile(new File(getImage.getPath(), photoNameString));
            }
        }

        return outputFileUri;
    }

ps:上面的代碼如果不做if (Build.VERSION.SDK_INT >= 24)這個判斷,會出現下面權限問題

 Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{4293c3b8 3545:com.android.camera/u0a9} (pid=3545, uid=10009) that is not exported from uid 10056
       at android.os.Parcel.readException(Parcel.java:1425)
       at android.os.Parcel.readException(Parcel.java:1379)
       at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2354)
       at android.app.ActivityThread.acquireProvider(ActivityThread.java:4292)
       at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:1749)

參考:

Google 官網
Stackoverflow

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • By clicking to agree to this Schedule 2, which is hereby ...
    qaz0622閱讀 1,494評論 0 2
  • 問題 以下是一段簡單的代碼,它調用系統的相機app來拍攝照片: 在一般情況下,運行沒有任何問題;可是當把targe...
    gelitenight閱讀 23,976評論 7 34
  • 英文文檔,一開始我也是抗拒的,邊翻譯邊看,也就花費了1個小時基本就閱讀過了,我的英文基礎其實很差。附上鏈接:鏈接:...
    lonecolonel閱讀 10,015評論 3 1
  • 有一句話是:關心則亂。確實,一旦你將心思放在了一個人或一件事上,心就會有了牽絆,然后亂了方寸。最后,越在意的事,反...
    吳潔_3015閱讀 478評論 2 7
  • 左伊出差14天后回來,依然很想她。 昨天我們談了哪一個人最重要的終極能力。什么更重要,什么最重要?隨著個人能力的發...
    凈明林閱讀 134評論 0 0