Android 无须获取Root权限静默安装App
16lz
2021-01-23
参考链接
android 静默安装
[Android]实现静默安装APK的两种方法
一.非Root即可静默安装APK需要满足以下条件
app进程和系统app进程是同一个进程,这个设置android:sharedUserId="android.uid.system"即可
获得PackageManager的installPackage方法,由于API隐藏和重写,已经很难找到对应的installPackage,目前找到的是installPackage(String,String,String,String),具体参数未知,因此我们需要使用frameworks层的相关代码,获得IPackageManager,并且通过反射获得ServiceManager,实现IPackageInstallObserver相关方法
使用signApk+platform.x509.pem+platform.pk8对app进行签名,使其具有系统签名
认真处理以上条件
二.具体代码截图与说明
有条件的的话,可以从frameworks/base/core/java/android/content/pm下获取这些文件,注意ManifestDigest使用了Google修改过的JDK,有些地方如IntegralString.appendByteAsHex无法使用,因此ManifestDigest.java需要改良。
三.核心代码MainActivity实现
packagecom.app.mobile.slient;importjava.io.File;importjava.lang.reflect.Method;importandroid.app.Activity;importandroid.content.pm.IPackageInstallObserver;importandroid.content.pm.IPackageManager;importandroid.net.Uri;importandroid.os.Bundle;importandroid.os.Environment;importandroid.os.IBinder;importandroid.os.RemoteException;importandroid.util.Log;importandroid.view.View;importandroid.widget.EditText;importandroid.widget.TextView;importandroid.widget.Toast;publicclassMainActivityextendsActivity{/****表示安装时以更新方式安装,即app不存在时安装,否则进行卸载再安装****/privatefinalintINSTALL_REPLACE_EXISTING=0x00000002;/****Apk存储目录,这里我放置在了SDcard的Download目录下****/privatefinalStringsdPath=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();privateTextViewmInstallTv;privateEditTextapkNameEt;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mInstallTv=(TextView)findViewById(R.id.id_install_tv);apkNameEt=(EditText)findViewById(R.id.id_apkname_Et);Log.i("Slient","sdPath="+sdPath);mInstallTv.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){installPackage();}});}publicvoidinstallPackage(){StringapkName=apkNameEt.getText().toString();PackageInstallObserverinstallObserver=newPackageInstallObserver();try{StringapkPath=sdPath.concat("/").concat(apkName).concat(".apk");Class<?>ServiceManager=Class.forName("android.os.ServiceManager");MethodgetService=ServiceManager.getDeclaredMethod("getService",String.class);getService.setAccessible(true);IBinderpackAgeBinder=(IBinder)getService.invoke(null,"package");IPackageManageriPm=IPackageManager.Stub.asInterface(packAgeBinder);iPm.installPackage(Uri.fromFile(newFile(apkPath)),installObserver,INSTALL_REPLACE_EXISTING,newFile(apkPath).getPath());}catch(Exceptione){e.printStackTrace();try{installObserver.packageInstalled(null,-1);}catch(RemoteExceptionignore){}}}/***安装监听*/publicclassPackageInstallObserverextendsIPackageInstallObserver.Stub{@OverridepublicvoidpackageInstalled(StringpackageName,intreturnCode)throwsRemoteException{if(returnCode==1)//返回1表示安装成功,否则安装失败{Toast.makeText(MainActivity.this,"安装成功!",Toast.LENGTH_SHORT).show();Log.e("Installed","packageName="+packageName+",returnCode="+returnCode);}else{Toast.makeText(MainActivity.this,"安装失败!",Toast.LENGTH_SHORT).show();}}}}
四.实施编译,打包,签名
1.使用Eclipse自带的打包工具,安装普通方式打包(注意,不可使用debug.keystore签名,否则安装不了)
2.将打包的apk使用signApk进行签名,命令如下
java-jarsignApk.jarplatform.x509.pemplatform.pk8slientInstall.ApknewApk.apk
或者新建Java工程如下打包
publicclassTestCase{publicstaticvoidmain(String[]args){try{Class<?>SignApk=Class.forName("com.android.signapk.SignApk");MethodmainMethod=SignApk.getDeclaredMethod("main",String[].class);if(!Modifier.isPublic(mainMethod.getModifiers())||!mainMethod.isAccessible()){mainMethod.setAccessible(true);}mainMethod.invoke(null,newObject[]{newString[]{"platform.x509.pem","platform.pk8","slientInstall.apk","newApk.apk"}});System.out.println("-----O(∩_∩)O哈哈~----签名成功-----O(∩_∩)O哈哈~----");}catch(Exceptione){e.printStackTrace();System.out.println("-----%>_<%----签名失败-----%>_<%----");}}}
3.然后就可以安装了,开始试试吧
由于开源中国不能上传相应的附近,我把项目上传到CSDN,请自行下载吧
下载地址:
http://download.csdn.net/detail/m_andrain/9018329
更多相关文章
- 【Android 开发】: Android 消息处理机制之三: Handler 中 sendM
- Android Studio的Gradle文件方法说明
- 获取Android SDK 源代码并在Eclipse中关联查看的方法
- Android SDK安装方法