Android project combat (forty): Andoird 7.0+ installation APK adaptation

Original: Android project combat (forty): Andoird 7.0+ installation APK adaptation

  

   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);
            }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325112861&siteId=291194637