【转载】Android App的卸载与安装

前段时间由于项目的需要,在8.0系统上防止Android App被卸载,这段时间搜了很多资料,转载了感兴趣的文章方便以后查看。

 

一个手机App,经下载、安装、更新、卸载。

下载就不说了,本篇博客主要研究 安装、更新和卸载。

一个apk经过下载下来,有几种安装方式?

1.内置APP随着系统启动PMS而安装。(刷机后一般第一步操作就是这个)

2.使用adb install命令安装。(开发人员常用方式)

3.通过系统内置的PackageInstaller应用安装。(一般应用通过浏览器下载后就会调用系统安装器弹出界面进行安装)

4.在一些手机厂商内置的应用商店下载,然后静默安装。(手机厂商使用系统级权限进行应用安装)

5.Root的手机使用root权限进行静默安装。(第三方应用市场一般会对root手机采取此类安装方式)

从源码上看:一般分两类 1. 扫描应用程序的存放文件夹进行安装 2. 通过packagemanager进行安装。

这里只研究常用的安装方式 第2、3点

adb命令安装如下

安装前查看设备是否存在

adb devices

有设备是这个样子的

 

adb install 路径

成功后是这个样子的

 

adb 命令 一般是开发人员常用

我们来看看系统内置的安装方法

public static void installApp(Context context, String filePath) {
    File apkFile = new File(filePath);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        Uri contentUri = FileProvider.getUriForFile(
                context
                , BuildConfig.APPLICATION_ID + ".fileProvider"
                , apkFile);
        intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
    } else {
        intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
    }
    context.startActivity(intent);


这种安装在Android 8.0 手机以下没什么问题,但是前几天有个同事手机是8.0的,由于8.0的手机对未知来源的apk安装做了限制,所以只写以上的代码就不行了,处理代码如下。

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
    boolean b =getPackageManager().canRequestPackageInstalls();
    if (b) {
        //调用安装方法
    } else {
        //请求安装未知应用来源的权限
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, REQUEST_INSTALL_PACKAGES);
    }
}else {
    //8.0以下调用安装方法
}

请求一下同意未知来源安装的权限

权限结果如下

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

if(requestCode == REQUEST_INSTALL_PACKAGES){
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
       //调用安装方法
    } else {
    //做未获取到安装权限的提示
}

}

app 的更新

APP的更新一般是后台控制的,根据后台返回的数据,判断当前的APP是否需要更新,更新执行下载操作,下载完了就回到了安装上面,所以更新没什么需要讨论的。

Android 系统中,有apk的安装、更新、卸载。系统都会发出广播,我们就能收到这个广播。来看看这些广播

首先先把这些广播都给注册上,咦,注册广播用静态注册好呢还是动态注册好呢? 这个就要看你应用的业务需求了,选择适合你应用的注册方法,这里我选择静态注册,AndroidManifest中注册如下。

<receiver android:name=".AppInstallReceiver">
    <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" />
        <action android:name="android.intent.action.USER_PRESENT" />
        <data android:scheme="package" />
    </intent-filter>
</receiver>

然后看看广播接收器

public class AppInstallReceiver extends BroadcastReceiver {
    
    private final static String TAG="AppInstallReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        String packageName = intent.getData().getSchemeSpecificPart();
        switch (intent.getAction()){
            case Intent.ACTION_PACKAGE_REMOVED:
                Log.i(TAG,"收到卸载广播,包名为 "+packageName);
                break;
            case Intent.ACTION_MY_PACKAGE_REPLACED:
                Log.i(TAG,"收到App更新广播,包名为 "+packageName);
                break;
            case Intent.ACTION_PACKAGE_ADDED:
                Log.i(TAG,"收到App安装广播,包名为 "+packageName);
                break;
        }
        
    }
}

这些广播有什么用呢?通过监听这些广播客监听到我们目标程序的安装、更新、卸载状态,之后拿到这些状态后做相应的工作,插件化的程序使用居多。

app的卸载

对于用户来说,卸载一个APP,直接长按拖去垃圾筐即可卸载。但是对于我们Android 开发人员来说,其他卸载方法也是要会的。

卸载的方式

1.手机桌面长按应用图标至抖动,然后拖去垃圾筐。

2.调用系统卸载服务进行卸载

3.通过adb 命令卸载

调用系统服务卸载,如下

public static void unstallApp(Context context,String packageName){
    Intent uninstall_intent = new Intent();
    uninstall_intent.setAction(Intent.ACTION_DELETE);
    uninstall_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    uninstall_intent.setData(Uri.parse("package:"+packageName));
    context.startActivity(uninstall_intent);
}

传入 context和包名即可

通过adb命令卸载

同样,卸载前通过命令 adb devices 来查看设备是否连接上

命令  adb shell pm list packages 来查看当前设备安装的应用

是这个样子的

 

卸载命令

adb uninstall 包名

比如

 

APP的安装、更新、卸载差不多就讲完了,下面说一说获取已安装APP的相关信息。

不多说,直接上代码,如下。

public static List<AppInfo> getAllAppInfos(PackageManager packageManager) {

    List<AppInfo> list = new ArrayList<AppInfo>();
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    List<ResolveInfo> ResolveInfos = packageManager.queryIntentActivities(intent, 0);
    // 遍历
    for (ResolveInfo ri : ResolveInfos) {
        String packageName = ri.activityInfo.packageName;
        Drawable icon = ri.loadIcon(packageManager);
        String appName = ri.loadLabel(packageManager).toString();
        AppInfo appInfo = new AppInfo(icon, appName, packageName);
        list.add(appInfo);
    }
    return list;
}

AppInfo 是我自己创建的实体类。

好了,到这里了,喜欢或对您有用麻烦点赞哦,谢谢大家。
--------------------- 
作者:我家有酸柠檬 
来源:CSDN 
原文:https://blog.csdn.net/qq_38302914/article/details/81083141 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值