1. The configuration:

Add permission and FileProvider to Androidmanifest.xml
--------------------------------------------------------------------------------------------------------------------
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
--------------------------------------------------------------------------------------------------------------------

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.fengzhi.wuyemanagement.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
Copy the code
1.2 Creating a File (path: res\ XML \file_paths.xml) :
<paths>
    <external-path path="." name="external_storage_root" />
</paths>
Copy the code
1.3 (app) build. Gradle:
    implementation "Com.lzy.net: okgo: 3.0.4"// Okgo network request implementation'com. Google. Code. Gson: gson: 2.8.2'//gson
    implementation "Org. Permissionsdispatcher: permissionsdispatcher: 4.3.1." "/ / permission annotationProcessor"Org. Permissionsdispatcher: permissionsdispatcher - processor: 4.3.1." "/ / permissionCopy the code

2. Here is an example of clicking the button to update:

2.1 Core code:
private int version; /* Private ProgressBar mProgress; private AlertDialog mDownloadDialog; -------------------------------------------------------------------------------------------------------------------- // Click the button to check permissions,,, Check out the update @ NeedsPermission ({Manifest. Permission. READ_EXTERNAL_STORAGE, Manifest. Permission. WRITE_EXTERNAL_STORAGE, Manifest.permission.REQUEST_INSTALL_PACKAGES}) protected voidcheckUpdate() {
        showLoadingDialog("Testing update..."); version = AppUpdateUtil.getAppVersionCode(this); // Check the current version number // call the method,, the concrete implementation of the interface, receive the parameters passed, then adjust their own method,  requestAppUpdate(version, New DataRequestListener<UpdateAppBean>() {@override public void success(UpdateAppBean data) { UpdateApp (data.getData().getapk_url ()); } @override public void fail(String MSG) {// return json, getStatus = 1"This is the latest version!"SToast(msg); dismissLoadingDialog(); }}); } // Check version number, first request (POST),, Private void requestAppUpdate(int version, final DataRequestListener<UpdateAppBean> listener) { OkGo.<String>post(Const.HOST_URL + Const.UPDATEAPP).params("version", version).execute(new StringCallback() {
            @Override
            public void onSuccess(Response<String> response) {
                Gson gson = new Gson();
                UpdateAppBean updateAppBean = gson.fromJson(response.body(), UpdateAppBean.class);
                if (updateAppBean.getStatus() == 0) {
                    listener.success(updateAppBean);
                } else {
                    listener.fail(updateAppBean.getMsg());
                }
            }

            @Override
            public void onError(Response<String> response) {
                listener.fail("Server connection failed"); dismissLoadingDialog(); }}); Private void updateApp(String APk_URL) {dismissLoadingDialog(); private void updateApp(String apk_URL) {dismissLoadingDialog(); DialogUtils.getInstance().showDialog(this,"New version found. Do you want to download the update?",
                new DialogUtils.DialogListener() {
            @Override
            public void positiveButton() { downloadApp(apk_url); }}); Private void downloadApp(String apk_URL) {OkGo.<File>get(apk_url).tag(this).execute(new)FileCallback() { @Override public void onSuccess(Response<File> response) { String filePath = response.body().getAbsolutePath(); Intent intent = IntentUtil.getInstallAppIntent(mContext, filePath); Stratactivityforresult McOntext.startactivity (intent); dismissLoadingDialog(); mDownloadDialog.dismiss(); mDownloadDialog=null; } @Override public void downloadProgress(Progress progress) { // showDownloadDialog(); // mProgress.setProgress((int) (progress.fraction * 100));ifBuilder Builder = new Alertdialog.builder (mContext); builder.setTitle("Updating"); // Add a progress bar to the download dialog box final LayoutInflater inflater = LayoutInflater. From (mContext); View v = inflater.inflate(R.layout.item_progress, null); mProgress = (ProgressBar) v.findViewById(R.id.update_progress); builder.setView(v); mDownloadDialog = builder.create(); mDownloadDialog.setCancelable(false); mDownloadDialog.show(); } mProgress.setProgress((int) (progress.fraction * 100)); }}); }Copy the code
2.2 DataRequestListener:
Public interface DataRequestListener<T> {// Request success void success(T data); Void fail(String MSG); }Copy the code

Next up are the utility classes, from Github, reference, github.com/vondear/RxT…

2.3 AppUpdateUtil:
/** * get App version code ** @param context * @returnPublic static int getVersionCode (Context Context) {return getAppVersionCode(context, context.getPackageName());
    }
Copy the code
2.4 IntentUtil:
Public class IntentUtil {/** ** Get the intent of installing App(support 7.0) ** @param context * @param filePath * @return*/ public static Intent getInstallAppIntent(Context context, String filePath) {// Local path of apk File File apkFile = new File(filePath);if(! apkfile.exists()) {return null;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri contentUri = FileUtil.getUriForFile(context, apkfile);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
        intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        return intent;
    }
Copy the code
2.5 FileUtil:
/** * Convert files to URIs (7.0 supported) ** @param mContext * @param file * @return
     */
    public static Uri getUriForFile(Context mContext, File file) {
        Uri fileUri = null;
        if (Build.VERSION.SDK_INT >= 24) {
            fileUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".fileprovider", file);
        } else {
            fileUri = Uri.fromFile(file);
        }
        return fileUri;
    }
Copy the code

3. Problems encountered

9.0 phone authorities configuration error causing installation failure

2. The authorities here are the same as in Fileutil. Java