私のアプリでは、ユーザーが他のアプリから写真やビデオをインポートできます。 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
が提供するファイルを再利用することでも同じ問題が発生します
提案/回避策はありますか?許可を失う前にファイルを読み取ることができることはわかっているので、理論的にはコピーできますが、これがとても好きだとは言えません。
はい、これは Android開発者サイト で説明されている仕様によるものです。
セキュリティ上の理由から、権限は一時的なものであるため、クライアントアプリのタスクスタックが終了すると、ファイルにアクセスできなくなります。インテント応答を受け取ったら、onActivityResultメソッドでファイルデータを取得する必要があります。 onActivityResultが返されるとファイルが使用できなくなるため、ファイルデータのコピーを保存します。
「Googleフォト」アプリを使用すると、このSecurityExceptionログを再現できます。
この問題の主な原因は、「Googleフォト」がContentUriを「content://com.google.Android.apps.photos.contentprovider/1/1」のような固定文字列と共有し、静的な一時的な値に接続することです。 「Googleフォト」は、Intent.ACTION_SENDを受信する実際のアクティビティまたはコンテキストの場合、ファイルパスを提供しません。多分、プライベート画像ファイルを他のアプリに公開しないことは「Google Photo」のポリシーです。
たとえば、マニフェストファイルに2つのアクティビティ、アクティビティAとアクティビティBを定義します。アクティビティAは、Intent.ACTION_SENDを受け取ります。画像ファイルを処理するためのアクティビティB。アクティビティAはインテントをアクティビティBに転送します。その後、アクティビティBは「Googleフォト」への正しいアクティビティではないため、SecurityExceptionが発生します。
そのため、アクティビティAでファイルを一時的に保存し、アクティビティBで一時ファイルのパスを使用することをお勧めします
このユーザー権限をマニフェストファイルに追加してみてください。
<uses-permission Android:name="com.google.Android.providers.gsf.permission.READ_GSERVICES" />
意図に一致するすべてのパッケージに明示的に権限を設定する必要があります。 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);
}
this の質問は似ています
アクティビティ(フラグメントではない)が停止すると、URIによって取得されたすべてが無効になります
私も同じ問題を抱えています-バックグラウンドで写真をアップロードしようとしています。しかし、UIスレッドのユーザーはアクティビティを変更する可能性があり、URIは無効になります
私はこれで同じ問題を抱えています、そしてあなたは次の方法の回避策を試してください: