17

我有两个应用程序。我正在尝试使用 FileProvider 将文件从应用程序 A 共享到应用程序 B。应用程序 A 在应用程序 B 中调用 ContentProvider 上的 insert 方法来插入记录。插入的数据包括我要从 App A 共享的文件的 Uri。然后,App B 中的 ContentProvider 将尝试从 App A 读取共享文件。由于我没有使用 Intent 来共享文件,所以我调用Context.grantUriPermissionApp A 以允许读取(有时写入):

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>

App A 和 App 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

在这一点上,我很难过。我不知道为什么我不能授予我刚刚在同一个应用程序中创建的文件的权限。所以我的问题是:为什么我会得到这个例外,我怎样才能成功地向 App B 授予权限?

4

2 回答 2

19

好吧,经过一周的反复试验,似乎答案是不指定权限。所以 App A Manifest 应该包含:

<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失败。访问已经受到限制。

为了完成图片并回答我的问题的第二部分,我发现了以下内容:

用于内容的 Widget RemoteViewsFactory 中的 Android 权限拒绝

我不得不补充:

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

到 App B 中的内容提供者。否则它也会出现安全错误。

于 2014-01-30T03:05:07.980 回答
-4

代码中的第一个问题是将导出属性设置为 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 中的内容提供程序。那么在应用程序 A 清单文件中提及权限为,

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

并在 App B 中提到使用权限为,

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

请让我知道您的问题是否已解决。如果没有,请发送您的整个代码。我会努力找出问题所在。谢谢你。

于 2015-04-08T04:50:32.340 回答