前段时间由于项目的需要,研究了下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中注册如下。
然后看看广播接收器
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 ListgetAllAppInfos(PackageManager packageManager) { List list = new ArrayList (); Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); List 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 是我自己创建的实体类。
好了,到这里了,喜欢或对您有用麻烦点赞哦,谢谢大家。