Using okhttp in Android to realize automatic program update

There are two steps to realize automatic program update:

1. Download apk program to local;

2. Install the downloaded apk program


For the implementation of automatic program update server-side operations, please refer to Spring Boot realizes file upload and download

1. Check update service

public class UpdateService {

    private static OkHttpClient okHttpClient;

    public static void download(final String fileName, final UpdateCallback callback) {
        String url = "http://127.0.0.1:8090/springbootdemo/log/download/" + fileName;
        Request request = new Request.Builder()
                .addHeader("Accept-Encoding", "identity")
                .url(url).build();

        if (okHttpClient == null) {
            okHttpClient = new OkHttpClient();
        }

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callback.onFailure();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.body() == null) {
                    callback.onFailure();
                    return;
                }

                File filePath = new File(CommonConstants.DOWNLOAD_PATH);
                if (!filePath.exists()) {
                    filePath.mkdirs();
                }

                long contentLength = response.body().contentLength();
                byte[] buffer = new byte[1024];
                File file = new File(filePath.getCanonicalPath(), fileName);
                try (InputStream is = response.body().byteStream();
                     FileOutputStream fos = new FileOutputStream(file)) {
                    LoggerUtils.getLogger().info("Save path:" + file);

                    int length;
                    long sum = 0;
                    while ((length = is.read(buffer)) != -1) {
                        fos.write(buffer, 0, length);
                        sum += length;
                        int progress = (int) (sum * 1.0f / contentLength * 100);
                        callback.onProgress(progress);
                    }
                    fos.flush();

                    callback.onSuccess();
                } catch (Exception e) {
                    callback.onFailure();
                }
            }
        });
    }

    public interface UpdateCallback {

        void onSuccess();

        void onProgress(int progress);

        void onFailure();
    }
}

2. Check update interface

@ActivityLayoutInject(R.layout.activity_update)
public class UpdateActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @OnClick(R.id.menuBtnCheckUpdate)
    public void onClickCheckUpdate() {
        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setCancelable(true);
        dialog.setTitle("Downloading");
        dialog.setMessage("Please wait a moment....");
        dialog.setProgress(0);
        dialog.setMax(100);
        dialog.show();

        String fileName = "AndroidDemo-v1.0.0.0.apk";
        UpdateService.download(fileName, new UpdateService.UpdateCallback() {
            @Override
            public void onSuccess() {
                dialog.dismiss();

                if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    return;
                }

                File file = new File(CommonConstants.DOWNLOAD_PATH + fileName);
                try {
                    LoggerUtils.getLogger().info("Installation file directory:" + file);
                    LoggerUtils.getLogger().info("Ready to install");
                    installApk(file);
                } catch (Exception e) {
                    LoggerUtils.getLogger().info("Get open method error", e);
                }
            }

            @Override
            public void onProgress(int progress) {
                dialog.setProgress(progress);
            }

            @Override
            public void onFailure() {
                dialog.dismiss();
            }
        });
    }

    private void installApk(File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri fileUri;

        //Android 7.0 and above
        if (Build.VERSION.SDK_INT >= 24) {
            fileUri = FileProvider.getUriForFile(this,
                    BuildConfig.APPLICATION_ID + ".provider", file);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            fileUri = Uri.fromFile(file);
        }

        intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
        startActivity(intent);
    }
}

If your Android machine is below 7.0, it's OK here, but if it's above 7.0, you need to do the following.

3. Create a new file? Paths.xml file

In the res\xml folder, create file_paths.xml. path is the directory where the downloaded apk is stored

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="download"
        path="AndroidDemo/download/" />
</paths>

4. Register FileProvider

Register under the application of Android manifest.xml

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="cn.wbnull.androiddemo.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

5. Register read and write permissions

Register read / write and network permissions in Android manifest.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" />

Well, here we'll achieve the effect shown in the top video.




GitHub: https://github.com/dkbnull/AndroidDemo




92 original articles published, 126 praised, 360000 visitors+
Private letter follow

Tags: Android xml FileProvider encoding

Posted on Sun, 26 Jan 2020 09:15:51 -0500 by gva482