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