Android Project Practice (40): Andoird 7.0 + installation APK adaptation, andoirdapk
First, let's take a look at the code for installing the apk file.
/*** Use implicit Intent to call the system installer to install APK */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 shows that the code in this section can successfully open the specified apk file in the specified path on the 7.0 model. However, if you call this code on the 7.0 + model, an error is returned:
android.os.FileUriExposedException: file:///storage/emulated/0/Download/xxxx.apk exposed beyond app through Intent.getData()
The reason is: Android 7.0 prohibits the disclosure of file: // URI outside your application. If an Intent containing file: // URI leaves your application, the application fails, and a FileUriExposedException exception occurs.
Solution:
1. Add <provider>
<! -- 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 android: authorities is your package name and cannot be entered at will.
2. Create an xml file under the res directory and create the xml file file_paths.xml
Note that the file name must be consistent with the value of the resource attribute in step 1.
Content:
<?xml version="1.0" encoding="utf-8"?><paths> <external-path path="." name="download"/></paths>
3. Execute different apk installation code at the Android system level of the Model
Note: If you execute different codes according to the system version, an error will be reported when you call the code of 7.0 + or lower, and if you call the code of 7.0 + or lower, an error will be reported.
If (file! = Null) {// file is the apk file Intent intent = new Intent (Intent. ACTION_VIEW); // because the Activity is not started in the Activity environment, set the following tag intent. setFlags (Intent. FLAG_ACTIVITY_NEW_TASK); if (Build. VERSION. SDK_INT> = 24) {// check whether the version is above 7.0 // The context of parameter 1, 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 indicate that the object intent represented by the Uri is temporarily authorized to the target application. 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 );}