静默安装 apk html,android apk静默安装和卸载

静默安装:

在某个触发点自动后台安装指定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来进行安装操作

本文档只贴出具体安装的过程,舍弃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下,才能保证其有效.方法就是反射

静默安装的第一种方法:

packagecom.tnt.autoinstall;

importjava.io.ByteArrayOutputStream;

importjava.io.File;

importjava.io.InputStream;

importjava.lang.reflect.InvocationTargetException;

importjava.lang.reflect.Method;

importandroid.net.Uri;

importandroid.os.Bundle;

importandroid.app.Activity;

publicclassMainActivityextendsActivity {

privateUri packageUri;

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

packageUri = getPackageUri();

install();

}

privatevoidinstall()

{

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();

}

}

privateClass>[] getParamTypes(Class> cls, String mName) {

Class> cs[] = null;

Method[] mtd = cls.getMethods();

for(inti =0; i 

if(!mtd[i].getName().equals(mName)) {

continue;

}

cs = mtd[i].getParameterTypes();

}

returncs;

}

privateUri getPackageUri()

{

File file = newFile("/storage/sdcard0/download/1.apk");

returnUri.fromFile(file);

}

}

静默安装的第二种方法:

通过adb命令的方式来处理,代码如下,把上面的install函数替换下面代码

privatebooleaninstall()

{

String[] args = {"pm","install","-r", packageUri.getPath()};

String result = null;

ProcessBuilder processBuilder = newProcessBuilder(args);;

Process process = null;

InputStream errIs = null;

InputStream inIs = null;

try{

ByteArrayOutputStream baos = newByteArrayOutputStream();

intread = -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 = newString(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")))

{

returntrue;

}

returnfalse;

}

下面看下卸载过程

同样的.需要增加一个权限android:name="android.permission.DELETE_PACKAGES".放入system/app中.

卸载方式一:adb shell pm方式

privatevoiduninstall2() {

String[] args = { "pm","uninstall","com.popcap.pvzthird"};

String result = null;

ProcessBuilder processBuilder = newProcessBuilder(args);

;

Process process = null;

InputStream errIs = null;

InputStream inIs = null;

try{

ByteArrayOutputStream baos = newByteArrayOutputStream();

intread = -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 = newString(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);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值