web-dev-qa-db-ja.com

コンテキストプロバイダーのデータを使用するか、Googleフォトの読み取り許可を要求しますか?

私のアプリでは、ユーザーが他のアプリから写真やビデオをインポートできます。 GoogleがGoogle+フォトをGoogleフォトに置き換えたため、いくつかの問題が発生しました。これらの1つは、アプリの再起動後にインポートしたファイルを再利用することです。 Googleフォトが画像URIを使用してインテントを返すときに与えられる権限を厳しくしたので、アプリが強制終了されると、アップロードされたファイルにアクセスする権限がなくなります。私はセキュリティの期待を得ています:

Java.lang.SecurityException: Permission Denial: opening provider com.google.Android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{2c17ab9e 2124:com.myapp.myapp/u0a436} (pid=2124, uid=10436) that is not exported from uid 10427

編集:

com.google.Android.apps.docs.sync.filemanager.FileProviderが提供するファイルを再利用することでも同じ問題が発生します

提案/回避策はありますか?許可を失う前にファイルを読み取ることができることはわかっているので、理論的にはコピーできますが、これがとても好きだとは言えません。

22
vkislicins

はい、これは Android開発者サイト で説明されている仕様によるものです。

セキュリティ上の理由から、権限は一時的なものであるため、クライアントアプリのタスクスタックが終了すると、ファイルにアクセスできなくなります。インテント応答を受け取ったら、onActivityResultメソッドでファイルデータを取得する必要があります。 onActivityResultが返されるとファイルが使用できなくなるため、ファイルデータのコピーを保存します。

21
Dazzibao
  1. 「Googleフォト」アプリを使用すると、このSecurityExceptionログを再現できます。

  2. この問題の主な原因は、「Googleフォト」がContentUriを「content://com.google.Android.apps.photos.contentprovider/1/1」のような固定文字列と共有し、静的な一時的な値に接続することです。 「Googleフォト」は、Intent.ACTION_SENDを受信する実際のアクティビティまたはコンテキストの場合、ファイルパスを提供しません。多分、プライベート画像ファイルを他のアプリに公開しないことは「Google Photo」のポリシーです。

  3. たとえば、マニフェストファイルに2つのアクティビティ、アクティビティAとアクティビティBを定義します。アクティビティAは、Intent.ACTION_SENDを受け取ります。画像ファイルを処理するためのアクティビティB。アクティビティAはインテントをアクティビティBに転送します。その後、アクティビティBは「Googleフォト」への正しいアクティビティではないため、SecurityExceptionが発生します。

そのため、アクティビティAでファイルを一時的に保存し、アクティビティBで一時ファイルのパスを使用することをお勧めします

9
BlueMist

このユーザー権限をマニフェストファイルに追加してみてください。

<uses-permission Android:name="com.google.Android.providers.gsf.permission.READ_GSERVICES" />
3
Zephyr

意図に一致するすべてのパッケージに明示的に権限を設定する必要があります。 Android 4.4で通常発生します。

このユーティリティを使用してそれを行うことができます:

List<ResolveInfo> resInfoList = getContext().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            getContext().grantUriPermission(packageName, imageFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
1
Maher Abuthraa

this の質問は似ています

アクティビティ(フラグメントではない)が停止すると、URIによって取得されたすべてが無効になります

私も同じ問題を抱えています-バックグラウンドで写真をアップロードしようとしています。しかし、UIスレッドのユーザーはアクティビティを変更する可能性があり、URIは無効になります

1
Art
0
jtxyz0804