使用 BroadcastReceiver 实现 APK 下载后自动跳出安装

  一般需要实现自动更新的情况下可以用到它。当然,如果你使用 OkHttp 或者 Rx 之类的就可以直接忽略了。本文只针对不使用第三方库的情况下快速实现。
  新建一个叫做 InstallReceiver 的类 (当然名字可以随便取),继承 BroadcastReceiver。完整的代码示例如下:

public class InstallReceiver extends BroadcastReceiver {
    private static final String TAG = "InstallReceiver";

    // 接收下载完成后发送的广播
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
            installApk(context);
        }
    }

    // 安装 APK
    private void installApk(Context context) {

        try {
            String filePath = "/download/test.apk";     // APK 绝对路径

            Intent i = new Intent(Intent.ACTION_VIEW);
            Uri address = Uri.parse("file://" + Environment.getExternalStorageDirectory() + filePath);
            i.setDataAndType(address, "application/vnd.android.package-archive");
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        } catch (Exception e) {
            Log.e("installApk", "安装失败, 原因: " + e);
            e.printStackTrace();
        }
    }
}

  然后在你需要用到的 Activity 中注册广播示例,比如:

IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);    // 添加要收到的广播
        InstallReceiver installReceiver = new InstallReceiver();                // 实例化广播实例
        registerReceiver(installReceiver, intentFilter);                        // 注册广播

  注册完后就调用 DownloadManager 下载就行:
“`java
// 使用 Android 自带的下载管理器下载 APK
public void downloadApk(String url, String fileName) {

    DownloadManager.Request request;
    try {
        request = new DownloadManager.Request(Uri.parse(url));
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }

    request.setTitle("更新");
    request.setDescription("正在下载更新...");

    // 在通知栏显示下载进度
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        request.allowScanningByMediaScanner();
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    }

    // 设置保存下载保存路径
    request.setDestinationInExternalPublicDir("/download/", fileName);      // 记得和 InstallReceiver.java 里一样,但不要加上 'Environment.getExternalStorageDirectory()' ,会导致重复目录

    Context appContext = MainActivity.this.getApplicationContext();
    DownloadManager manager = (DownloadManager) appContext.getSystemService(Context.DOWNLOAD_SERVICE);

    // 进入下载队列
    manager.enqueue(request);
}

“`