17

2つのアプリケーションがあります。FileProvider を使用して、アプリケーション A からアプリケーション B にファイルを共有しようとしています。アプリケーション A は、アプリケーション B の ContentProvider で insert メソッドを呼び出して、レコードを挿入します。挿入されたデータには、アプリ A から共有したいファイルへの Uri が含まれています。アプリ B の ContentProvider は、アプリ A から共有ファイルを読み取ろうとします。ファイルを共有するためにインテントを使用していないため、Context.grantUriPermissionアプリ 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 のマニフェスト ファイルには次のものが含まれます。

<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 に許可を与えることができますか?

4

2 に答える 2

19

さて、1 週間にわたって多くの試行錯誤を重ねた結果、パーミッションを指定しないことが答えのようです。そのため、App A マニフェストには代わりに以下を含める必要があります。

<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て失敗することがわかりました。アクセスはすでに制限されています。

全体像を完成させ、私の質問の 2 番目の部分に答えるために、次のことがわかりました。

コンテンツのウィジェット RemoteViewsFactory での Android 権限の拒否

追加する必要がありました:

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

アプリ B のコンテンツ プロバイダーに送信します。そうしないと、セキュリティ エラーも発生します。

于 2014-01-30T03:05:07.980 に答える
-4

コードの最初の問題は、 export 属性が 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>

あなたがしなければならない2番目のことは、外部アプリケーションアプリ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 を次のように言及しています。

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

問題が解決したかどうかをお知らせください。そうでない場合は、コード全体を送信してください。私は問題を見つけようとします。ありがとうございました。

于 2015-04-08T04:50:32.340 に答える