Fork me on GitHub

Android应用安装和卸载时的广播

在android系统中,安装和卸载都会发送广播,当应用安装完成后系统会发android.intent.action.PACKAGE_ADDED广播。

可以通过intent.getDataString()获得所安装的包名。当卸载程序时系统发android.intent.action.PACKAGE_REMOVED广播。
同样intent.getDataString()获得所卸载的包名。

在安卓APP项目开发中,我们有这样的需求:

APP安装更新完成后,需要把 APK 文件删除

这里,我们可以通过安卓四大组件之一 —— 广播-接收器,来助阵。

广播有动态注册和静态注册两种方式,此处用静态注册方式。

在 AndroidManifest.xml 文件中静态注册广播接收器:

1
2
3
4
5
6
7
8
9
10
11
12
<receiver android:name="具体包名.广播接收器名"
android:enabled="true">

<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<!--涉及到存储卡状态改变的时候必须添加-->
<data android:scheme="package" />
</intent-filter>

</receiver>

几个 intent-filter name 相信从名字就能知道什么意思了。

PACKAGE_ADDED 接受包被添加时发送的广播
PACKAGE_REPLACED 接受包被替换时发送的广播
PACKAGE_REMOVED 接受包被移除时发送的广播

安卓系统在我们安装或卸载APP等操作时,会发送以上的一些广播包,我们这里设个接收器来”监听“这些操作的发生。

新建一个类,继承自 BroadcastReceiver,重写 onReceive 方法,具体逻辑处理可在此书写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;

import java.io.File;

/**
* Created by Moses on 2017/12/5.
*
* PackageInstallSuccessfulReceiver
*
* 接受 广播 软件包被添加、删除和替换时发出
*
*/

public class PackInstSucRecei extends BroadcastReceiver {
private String apkfileName = "app-debug.apk";

@Override
public void onReceive(Context context, Intent intent) {

if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Log.d(TAG, "监听到系统广播,包被添加: ");
//删除apk文件
deleteApkfile(apkfileName);
}

if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Log.d(TAG, "监听到系统广播,包被移除: ");
Log.d(TAG, "onReceive: " + intent.getDataString());
}

if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
Log.d(TAG, "监听到系统广播,包被替换: ");
Log.d(TAG, "onReceive: "+ intent.getPackage());
deleteApkfile(apkfileName);
}
}

public Boolean deleteApkfile(String apkFileName){
//Apk文件路径可自定义,此处用 download 文件夹
File apkfile = new File(Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getPath(), apkFileName);
if (!apkfile.exists()) {
Log.d(TAG, "apkfile delete already! ");
} else {
//调用现成的文件操作方法删除文件
if (apkfile.delete())
Log.d(TAG, "apkfile delete successfully! ");
}
return false;
}
}