Android应用安装卸载监控

安装应用

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
57
58
59
60
public class InstallUtil {
private Activity mAct;
private String mPath;//下载下来后文件的路径
public static int UNKNOWN_CODE = 2018;

public InstallUtil(Activity mAct, String mPath) {
this.mAct = mAct;
this.mPath = mPath;
}

public void install(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startInstallO();
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) startInstallN();
else startInstall();
}

/**
* android1.x-6.x
*/
private void startInstall() {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.parse("file://" + mPath), "application/vnd.android.package-archive");
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mAct.startActivity(install);
}

/**
* android7.x
*/
private void startInstallN() {
//参数1 上下文, 参数2 在AndroidManifest中的android:authorities值, 参数3 共享的文件
Uri apkUri = FileProvider.getUriForFile(mAct, Constants.AUTHORITY, new File(mPath));
Intent install = new Intent(Intent.ACTION_VIEW);
//由于没有在Activity环境下启动Activity,设置下面的标签
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
mAct.startActivity(install);
}

/**
* android8.x
*/
@RequiresApi(api = Build.VERSION_CODES.O)
private void startInstallO() {
boolean isGranted = mAct.getPackageManager().canRequestPackageInstalls();
if (isGranted) startInstallN();//安装应用的逻辑(写自己的就可以)
else new AlertDialog.Builder(mAct)
.setCancelable(false)
.setTitle("安装应用需要打开未知来源权限,请去设置中开启权限")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int w) {
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
mAct.startActivityForResult(intent, UNKNOWN_CODE);
}
})
.show();
}
}

调用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DownAct extends AppCompatActivity {

private InstallUtil mInstallUtil;

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

mInstallUtil = new InstallUtil(this, "");
mInstallUtil.install();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == InstallUtil.UNKNOWN_CODE) {
mInstallUtil.install();//再次执行安装流程,包含权限判等
}
}
}

卸载应用

1
2
3
Uri uri = Uri.fromParts("package", "com.example.demo", null);
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
startActivity(intent);

监听应用安装卸载

XML形式

1、新建监听类:BootReceiver继承BroadcastReceiver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class BootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
//接收安装广播
if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
String packageName = intent.getDataString();
System.out.println("安装了:" +packageName + "包名的程序");
}
//接收卸载广播
if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
String packageName = intent.getDataString();
System.out.println("卸载了:" + packageName + "包名的程序");

}
}
}

2、 修改AndroidManifest.xml配置文件,添加广播介绍,添加监听的权限

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
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rongfzh.yc"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="7" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".PakDetectActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BootReceiver"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

</manifest>

3、运行程序,卸载一个程序ApiDemos程序打印日志如下

卸载了​package:com.example.android.apis包名的程序

4、安装腾讯微博,打印日志如下

安装了​package:com.tencent.WBlog包名的程序

代码方式

一般在Activity的onStart()方法中注册监听,在onDestroy()方法中注销监听(也可以在onStop()方法中注销,其生命周期注销时结束)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public void onStart(){
super.onStart();

installedReceiver = new MyInstalledReceiver();
IntentFilter filter = new IntentFilter();

filter.addAction("android.intent.action.PACKAGE_ADDED");
filter.addAction("android.intent.action.PACKAGE_REMOVED");
filter.addDataScheme("package");

this.registerReceiver(installedReceiver, filter);
}

@Override
public void onDestroy(){
if(installedReceiver != null) {
this.unregisterReceiver(installedReceiver);
}

super.onDestroy();
}

判断应用是否安装

Java

1
2
3
4
5
6
7
8
9
/**
* 判断是否安装目标应用
*
* @param packageName 目标应用安装后的包名
* @return 是否已安装目标应用
*/
private boolean isInstallByread(String packageName) {
return new File("/data/data/" + packageName).exists();
}

或者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 检查APP是否安装
*
* @param context
* @param pkgName
* @return
*/
public static boolean checkAppInstalled(Context context, String pkgName) {
if (pkgName == null || pkgName.isEmpty()) {
return false;
}
final PackageManager packageManager = context.getPackageManager();
List<PackageInfo> info = packageManager.getInstalledPackages(0);
if (info.isEmpty())
return false;
for (int i = 0; i < info.size(); i++) {
if (pkgName.equals(info.get(i).packageName)) {
return true;
}
}
return false;
}

Kotlin

1
2
3
4
5
6
7
8
9
/**
* 判断是否安装目标应用
*
* @param packageName 目标应用安装后的包名
* @return 是否已安装目标应用
*/
private fun isInstallByread(packageName: String): Boolean {
return File("/data/data/$packageName").exists()
}

跟应用有关的方法

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* 获取版本号
*
* @return 当前应用的versionCode
*/
public static int getVersionCode(Context context) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
int versionCode = info.versionCode;
return versionCode;
} catch (Exception e) {
return 0;
}
}

/**
* 获取版本号
*
* @return 当前应用的versionName
*/
public static String getVersionName(Context context) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
String versionName = info.versionName;
return versionName;
} catch (Exception e) {
return "未知";
}
}

public static void installApk(Context mContext, File apkFile) {
if (Build.VERSION.SDK_INT >= 24) {//判读版本是否在7.0以上
Uri apkUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".fileprovider", apkFile);//在AndroidManifest中的android:authorities值
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//对目标应用临时授权该Uri所代表的文件
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
mContext.startActivity(install);
} else {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(install);
}
}

/**
* 检查APP是否安装
*
* @param context
* @param pkgName
* @return
*/
public static boolean checkAppInstalled(Context context, String pkgName) {
if (pkgName == null || pkgName.isEmpty()) {
return false;
}
final PackageManager packageManager = context.getPackageManager();
List<PackageInfo> info = packageManager.getInstalledPackages(0);
if (info.isEmpty())
return false;
for (int i = 0; i < info.size(); i++) {
if (pkgName.equals(info.get(i).packageName)) {
return true;
}
}
return false;
}

public static void openApk(Context mContext,String packagename) {
Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packagename);
if (intent != null) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
}