13

我有兩個應用程序。我試圖使用FileProvider將文件從應用程序A共享到應用程序B.應用程序A在應用程序B中的ContentProvider上調用insert方法插入記錄。插入的數據包括Uri到我想要從App A共享的文件.App B中的ContentProvider然後嘗試從App A讀取共享文件。 因爲我沒有使用Intent來共享文件, M在應用主叫Context.grantUriPermission允許讀取(有時寫):與FileProvider共享文件時發生的帶有grantUriPermission的SecurityException

mContext.grantUriPermission(MyPackageName, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 

但是,在執行此行給我(名稱變更爲保護無辜者):

java.lang.SecurityException: Uid 10066 does not have permission to uri content://au.com.example.AppA.fileprovider/MyFolder/MyFileName 
at android.os.Parcel.readException(Parcel.java:1322) 
at android.os.Parcel.readException(Parcel.java:1276) 
at android.app.ActivityManagerProxy.grantUriPermission(ActivityManagerNative.java:2374) 
at android.app.ContextImpl.grantUriPermission(ContextImpl.java:1371) 
at android.content.ContextWrapper.grantUriPermission(ContextWrapper.java:400) 
at etc... 

應用程序A有Manifest文件中的以下內容:

<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="au.com.example.AppA.fileprovider" 
    android:exported="false" 
    android:grantUriPermissions="true" 
    android:readPermission="au.com.example.READ_CONTENT" 
    android:writePermission="au.com.example.WRITE_CONTENT" > 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/filepaths" /> 
</provider> 

filepaths.xml有:

<paths> 
    <files-path 
     name="MyFolder" 
     path="MyFolder/" /> 
</paths> 

兩個應用程序A和應用B有以下幾點:

<uses-permission android:name="au.com.example.READ_CONTENT" /> 
<uses-permission android:name="au.com.example.WRITE_CONTENT" /> 

我試圖定義在這兩個應用程序的權限。它們都具有相同的調試簽名簽名:

<permission 
    android:name="au.com.example.READ_CONTENT" 
    android:permissionGroup="MyGroup" 
    android:protectionLevel="signature" > 
</permission> 
<permission 
    android:name="au.com.example.WRITE_CONTENT" 
    android:permissionGroup="MyGroup" 
    android:protectionLevel="signature" > 
</permission> 

在文件中最終的實際路徑是:

/data/data/au.com.example.AppA/files/MyFolder 

在這一點上我很爲難。我不知道爲什麼我無法授予我在同一個應用程序中創建的文件的權限。所以我的問題是:爲什麼我得到這個異常,我怎樣才能成功授予應用程序B的權限?

回答

15

那麼,經過一個星期和大量的試驗和錯誤,似乎答案是不指定權限。因此,應用程序清單應該包含:

<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="au.com.example.AppA.fileprovider" 
    android:exported="false" 
    android:grantUriPermissions="true" > 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/filepaths" /> 
</provider> 

即,我刪除了讀寫權限。我最初的理解,並沒有找到其他文件,這是必要的限制訪問。但是,我發現它們實際上會干擾並導致Context.grantUriPermission失敗。訪問權限已被限制。

要完成的圖片,並回答我的問題的第二部分,我發現:

Android Permission denial in Widget RemoteViewsFactory for Content

我不得不添加:

final long token = Binder.clearCallingIdentity(); 
try { 
    [retrieve file here] 
} finally { 
    Binder.restoreCallingIdentity(token); 
} 

在應用中的內容提供商B.否則它也會得到安全錯誤。

+0

我也有這個問題,並從清單中刪除讀取權限,但仍然得到'由java.lang.SecurityException:權限拒絕:打開提供程序android.support.v4.content.FileProvider ProcessRecord {40b7b968 7764: com.google.android.gm/10018}(pid = 7764,uid = 10018)需要null或null – StuStirling

+0

@ DiscoS2我見過同樣的事情。我發現卸載並重新安裝該應用程序修復了它。我沒有檢查過,但我懷疑是否有某種緩存清單正在進行。 – DavidsAlias

+2

如果您沒有使用Signature級別的權限,您的應用程序是否暴露在外部威脅之下才能讀取任何具有正確Uri的文件? – Toochka

-2

代碼中的第一個問題是導出的屬性設置爲false。請將其更改爲true,

<provider 
android:name="android.support.v4.content.FileProvider" 
android:authorities="au.com.example.AppA.fileprovider" 
android:exported="true" 
android:readPermission="au.com.example.READ_CONTENT" 
android:writePermission="au.com.example.WRITE_CONTENT" > 
</provider> 

你必須做的第二件事是,如果外部應用程序應用程序B是在應用程序使用A.內容提供商然後,在應用程序清單文件提及的權限爲,

<permission 
android:name="au.com.example.READ_CONTENT" 
> 
</permission> 
<permission 
android:name="au.com.example.WRITE_CONTENT" 
> 
</permission> 

和應用B提及使用許可權的,

<uses-permission android:name="au.com.example.READ_CONTENT" /> 
<uses-permission android:name="au.com.example.WRITE_CONTENT" /> 

請讓我知道你的問題是否已經解決或沒有。如果不是,請發送您的整個代碼。我會盡力找到問題。 謝謝。

+1

我最終解決了這個問題。請參閱接受的答案。 Exported = true將允許訪問具有列出權限的任何應用程序。我試圖將應用程序分享給另一個應用程序,而不是任何應用程序。 – DavidsAlias

+0

你的意思是臨時權限 –

+3

'FileProvider'檢查'android:exported =「true」'並且會拋出異常。 – WindRider