First look at the code to install the apk file
/** * Install APK by calling system installer with implicit intent */ public static void install(Context context) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.fromFile( new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "xxxx.apk")), "application/vnd.android.package-archive"); context.startActivity(intent); }
The test found that this code can successfully open the specified apk file under the specified path on models below 7.0, but calling this code on models 7.0+ will report an error:
android.os.FileUriExposedException: file:///storage/emulated/0/Download/xxxx.apk exposed beyond app through Intent.getData()
The reason is: Android 7.0 release prohibits exposing file:// URIs outside your app. If an Intent containing the file file:// URI type leaves your app, the app fails with a FileUriExposedException.
Solution:
1. Add <provider>, one of the four major components, to the AndroidManifest.xml file
<!-- Adapt to 7.0 apk installation--> <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.xxx.xxxx.fileprovider" android:grantUriPermissions="true" android:exported="false"> <!--metadata--> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
Note that com.xxx.xxxx in the value of the android :authorities attribute is your package name and cannot be filled in at will
2. Create an xml file in the res directory and create a new xml file file_paths.xml
Note that the file name must be the same as the value of the resource attribute in the first step
The content is:
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path path="." name="download"/> </paths>
3. Execute different code to install apk according to the Android system level of the model
Note that different codes are executed according to the system version, the code below 7.0 that calls 7.0+ will report an error, and the code below 7.0+ that calls 7.0 will report an error.
if (file!= null ){ // file is the apk file Intent intent = new Intent(Intent.ACTION_VIEW); // Since the Activity is not started in the Activity environment, set the following label intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT>= 24 ) { // Interpretation Whether the version is above 7.0 // parameter 1 context, parameter 2 Provider host address and configuration file are consistent parameter 3 shared file Uri apkUri = FileProvider.getUriForFile(context, " com.xxx.xxxxx.fileprovider " , file); / / Add this sentence to temporarily authorize the file represented by the Uri to the target application intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); }else{ intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); } context.startActivity(intent); }