Intent.getData()を介してアプリを超えて公開



Exposed Beyond App Through Intent



ほとんどの国内Androidアプリには、更新機能が組み込まれています。つまり、新しいバージョンのAPKをサーバーに配置し、インターフェースを介して更新情報を取得してダウンロードし、インストールします。この種の動作はGoogleによって厳しく禁止されていますが、この環境では妥協する必要があります。

ほとんどの経験豊富な人々は、過去にアプリ内に新しいバージョンのAPKをインストールしたとき、次のことを実現するために非常に単純なコードを使用するだけでよいことを知っています。



Intent intent = new Intent() intent.setAction(Intent.ACTION_VIEW) intent.setDataAndType(Uri.fromFile(file), 'application/vnd.android.package-archive') finish() startActivity(intent)

その中で、fileパラメータはAPKファイルのアドレスを介して取得されたFileオブジェクトです。たとえば、APKのダウンロードアドレスが/sdcard/myapp.apkの場合、新しいファイル( 'sdcard / myapp.apk')を渡します。シンプルで失礼な効果は抜群です。 Android 7.0以降、コードのこの部分を引き続き使用すると、問題が発生します。

android.os.FileUriExposedException: file:///storage/emulated/0/1.apk exposed beyond app through Intent.getData()

FileUriExposedExceptionは、文字通り、ファイルUriによって公開された例外を意味します



この例外は、アプリケーションがfile:// Uriを他のアプリケーションに公開するときに発生します。これは、受信者Apが共有リソースにアクセスする権限を持っていない可能性があるためです。したがって、content:// Urlを使用して一時的なアクセス許可を拡張し、受信者がリソースにアクセスできるようにする必要があります。明らかに、これはGoogleがAndroidの自由を強化し、セキュリティを向上させるために行っていることです。

アプリ間でファイルを共有する
Android 7.0を対象とするアプリの場合、Androidフレームワークによって適用されるStrictMode APIポリシーは、アプリの外部へのfile:// URIの開示を禁止します。ファイルURIを含むインテントがアプリを離れると、アプリはFileUriExposedExceptionで誤動作します。

アプリ間でファイルを共有するには、content:// URIを送信し、URIへの一時的なアクセスを許可する必要があります。この承認を行う最も簡単な方法は、FileProviderクラスを使用することです。FileProviderの使用状況を確認できます。
?FileProviderの使用



解決:

AndroidManifestに追加

<provider android:name='android.support.v4.content.FileProvider' android:authorities='Current package name.fileprovider' android:exported='false' android:grantUriPermissions='true'> <meta-data android:name='android.support.FILE_PROVIDER_PATHS' android:resource='@xml/filepaths' /> </provider>

AndroidXの最初の行は

androidx.core.content.FileProvider
1
resの下の新しいxml / filepaths.xml

<paths xmlns:android='http://schemas.android.com/apk/res/android'> <external-path name='external' path=“'/> </paths>

FileProviderを使用してapk互換をインストールします

Intent intent = new Intent(Intent.ACTION_VIEW) File apkFile = new File(apkSavePath) intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) Uri uri = FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + '.fileprovider', apkFile) intent.setDataAndType(uri, 'application/vnd.android.package-archive') } else { intent.setDataAndType(Uri.fromFile(apkFile), 'application/vnd.android.package-archive') } startActivity(intent)

その中で、apkSavePath、私のプログラムはSDカードの下に配置されています

// SDカードのルートパスを取得します
文字列sdcardRoot = Environment.getExternalStorageDirectory()。getAbsolutePath()
最終的な文字列apkSavePath = sdcardRoot + '/ 1.apk'

これらのコードを説明してください。システムがAndroid7.0よりも低い場合は、古いシステムを使用してください。それ以外の場合は、FileProviderルートを使用する必要があります。
インテントにFLAG_GRANT_READ_URI_PERMISSIONが設定された後、サードパーティのアクティビティ(実際にはファイルを共有するサードパーティのアプリ)が開始されると、相手側に一時的な読み取りURIが付与されます。マップされたディレクトリのアクセス許可
'Uri uri = FileProvider.getUriForFile(context、context.getPackageName()+' .fileprovider '、apk_file)'次に、FileProviderを使用してファイルを転送します(APKファイルの新しいバージョンは次のとおりです)。 //安全な一時ファイル共有機能を実装するURI。インテントの処理を担当するシステムがAPKを正常にインストールできるようにします
————————————————
著作権表示:この記事は、CSDNブロガー「Errol_King」の元の記事です。これは、CC 4.0BY-SA著作権契約に従います。転載のために、元のソースリンクとこのステートメントを添付してください。
元のリンク:https://blog.csdn.net/u010356768/article/details/89212742