android apk静默安装和卸载
来源:互联网 发布:温州国际淘宝城 编辑:程序博客网 时间:2024/05/21 14:05
静默安装:
在某个触发点自动后台安装指定apk.没有安装界面.新软件自动安装,有旧版本的默默卸载,然后再安装,并且在不受系统设置中的第三方软件安装开关的限制.
自己跟踪记录的源码流程
Filemanager中点击apk包之后发送了一个intent出去
/*
* uri = file:///storage/sdcard0/download/%E7%99%BE%E9%98%85.apk
* mimeType = application/vnd.android.package-archive
*/
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, mimeType);
startActivity(intent);
Android会去系统中的packagemanager中查询哪个apk能响应这个操作.
找到PackageInstaller这个apk.文件路劲位于packages\apps\PackageInstaller
<activity android:name=".PackageInstallerActivity" …..>
<intent-filter>……
<data android:mimeType="application/vnd.android.package-archive" />
系统会启动这个Activity来进行安装操作
本文档只贴出具体安装的过程,舍弃ui操作,并加以简单说明
mPackageURI = intent.getData(); //获取安装包路劲
mPm = getPackageManager(); //获取packagemanager
checkFileInvaild //检测给定的文件是否为一个apk.如果自己确定的东西,省略吧
final File sourceFile = new File(mPackageURI.getPath()); //把路劲转成file类型
PackageParser.Package mPkgInfo = PackageUtil.getPackageInfo(sourceFile); //解析apk
getIconandTitle //根据mPkgInfo获取apk的icon和title.并存起来,对本题无用
if (!isInstallingUnknownAppsAllowed())//此处判断是否允许第三方软件安装.在设置里.
initiateInstall(); //开始初始化安装
String pkgName = mPkgInfo.packageName; //得到包名
String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
if (oldName != null && oldName.length > 0 && oldName[0] != null) {
pkgName = oldName[0];
mPkgInfo.setPackageName(pkgName);
}//以上是检测是否存在该包名.但是其已经被改变成别的神马了.*我不知道是神马意思
mPm.getApplicationInfo(pkgName,PackageManager.GET_UNINSTALLED_PACKAGES);
//检测是否有已经安装并未卸载的同名apk,有则弹出替代框(略过),无则安装
startInstallConfirm(); //弹出安装确认,点击ok
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,mPkgInfo.applicationInfo);
newIntent.setData(mPackageURI);
newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
newIntent.setClass(this, InstallAppProgress.class); //把apk的info传入新的Activity安装
…..
mAppInfo = intent.getParcelableExtra(XXX);
mPackageURI = intent.getData(); //从上面得到这些东西
String installerPackageName = getIntent().getStringExtra(xxxxPACKAGE_NAME);
PackageInstallObserver observer = new PackageInstallObserver();
pm.installPackage(mPackageURI, observer, installFlags(0), installerPackageName);
//安装过程就交个packagemanager去吧.我们不用管了.
//如果你要等待此apk安装完了之后还要处理一些东东的话.看下面
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
intentFilter.addDataScheme("package");
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_PACKAGE_REMOVED) {}
else if (Intent.ACTION_PACKAGE_ADDED || Intent.ACTION_PACKAGE_REPLACED) {}}
}, intentFilter);
//上面主要就是监听三个事件并在receive中去处理.
好了.回归主题.静默安装的关键代码已经出来了.只有一行
pm.installPackage(mPackageURI,observer, installFlags(0), installerPackageName);
看源码中该函数说明必须要加上android.Manifest.permission#INSTALL_PACKAGES才行,此权限只有system应用才能使用.所以此应用必须放入system/app下,才能保证其有效.方法就是反射
静默安装的第一种方法:
package com.tnt.autoinstall;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.InputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import android.net.Uri;import android.os.Bundle;import android.app.Activity;public class MainActivity extends Activity {private Uri packageUri; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); packageUri = getPackageUri(); install(); } private void install() { try { Class<?> pmService; Class<?> activityTherad; Method method; activityTherad = Class.forName("android.app.ActivityThread"); Class<?> paramTypes[] = getParamTypes(activityTherad , "getPackageManager"); method = activityTherad.getMethod("getPackageManager", paramTypes); Object PackageManagerService = method.invoke(activityTherad); pmService = PackageManagerService.getClass(); Class<?> paramTypes1[] = getParamTypes(pmService , "installPackage"); method = pmService.getMethod("installPackage", paramTypes1); method.invoke(PackageManagerService , packageUri , null , 0 , null);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}catch (ClassNotFoundException e1) {e1.printStackTrace();} } private Class<?>[] getParamTypes(Class<?> cls, String mName) {Class<?> cs[] = null;Method[] mtd = cls.getMethods();for (int i = 0; i < mtd.length; i++) {if (!mtd[i].getName().equals(mName)) {continue;}cs = mtd[i].getParameterTypes();}return cs;} private Uri getPackageUri() { File file = new File("/storage/sdcard0/download/1.apk"); return Uri.fromFile(file); }}
静默安装的第二种方法:
通过adb命令的方式来处理,代码如下,把上面的install函数替换下面代码
private boolean install() { String[] args = {"pm", "install", "-r", packageUri.getPath()};String result = null;ProcessBuilder processBuilder = new ProcessBuilder(args);;Process process = null;InputStream errIs = null;InputStream inIs = null;try{ByteArrayOutputStream baos = new ByteArrayOutputStream();int read = -1;process = processBuilder.start();errIs = process.getErrorStream();while((read = errIs.read()) != -1){baos.write(read);}baos.write('\n');inIs = process.getInputStream();while((read = inIs.read()) != -1){baos.write(read);}byte[] data = baos.toByteArray();result = new String(data);}catch(Exception e){e.printStackTrace();}finally{try{if(errIs != null){errIs.close();}if(inIs != null){inIs.close();}}catch(Exception e){e.printStackTrace();}if(process != null){process.destroy();}}if(result != null && (result.endsWith("Success")||result.endsWith("Success\n"))){return true;}return false; }
下面看下卸载过程
同样的.需要增加一个权限android:name="android.permission.DELETE_PACKAGES".放入system/app中.
卸载方式一:adb shell pm方式
private void uninstall2() {String[] args = { "pm", "uninstall", "com.popcap.pvzthird" };String result = null;ProcessBuilder processBuilder = new ProcessBuilder(args);;Process process = null;InputStream errIs = null;InputStream inIs = null;try {ByteArrayOutputStream baos = new ByteArrayOutputStream();int read = -1;process = processBuilder.start();errIs = process.getErrorStream();while ((read = errIs.read()) != -1) {baos.write(read);}baos.write('\n');inIs = process.getInputStream();while ((read = inIs.read()) != -1) {baos.write(read);}byte[] data = baos.toByteArray();result = new String(data);} catch (Exception e) {e.printStackTrace();} finally {try {if (errIs != null) {errIs.close();}if (inIs != null) {inIs.close();}} catch (Exception e) {e.printStackTrace();}if (process != null) {process.destroy();}}}
卸载方式二:反射调用系统函数
Class<?> pmService;Class<?> activityTherad;Method method;activityTherad = Class.forName("android.app.ActivityThread");Class<?> paramTypes[] = getParamTypes(activityTherad,"getPackageManager");method = activityTherad.getMethod("getPackageManager", paramTypes);Object PackageManagerService = method.invoke(activityTherad);pmService = PackageManagerService.getClass();Class<?> paramTypes1[] = getParamTypes(pmService, "deletePackage");method = pmService.getMethod("deletePackage", paramTypes1);method.invoke(PackageManagerService, "com.popcap.pvzthird", null, 0);
- android apk静默安装和卸载
- android apk静默安装和卸载
- Android静默安装和卸载APK
- android apk静默安装和卸载(2)
- android apk静默安装和卸载
- android静默安装、静默卸载apk方法
- Android静默安装和静默卸载
- Android--静默安装和静默卸载
- Android静默安装和静默卸载
- Android静默安装和静默卸载
- android实现静默卸载和静默安装
- Android静默安装和静默卸载
- Android静默安装和静默卸载
- 静默安装和卸载第三方apk
- android 静默安装和卸载
- android静默安装和卸载
- Android 静默安装和卸载
- 静默安装apk,静默卸载apk
- HDU 3400 Line belt
- Scott Mitchell 的ASP.NET 2.0数据教程之一: 创建一个数据访问层
- Linux下svn搭建配置流程
- Ubuntu: Ubuntu 12.04 LTS 中文输入法的安装
- win2003中Apache开启gzip功能
- android apk静默安装和卸载
- bitmap如何使用
- Scott Mitchell 的ASP.NET 2.0数据教程之二:创建一个业务逻辑层
- 【STL学习】堆相关算法详解与C++编程实现(Heap)
- Java数据类型精解
- Win32控制台工程中创建窗口
- Codeforces Round #164 (Div. 2) (完全)
- NFC Forum发布NFC数据交换格式(NDEF)规范
- MYSQLDUMP备份数据库和MYSQL还原数据库