參考連接java
android 靜默安裝
android
app進程和系統app進程是同一個進程,這個設置 android:sharedUserId="android.uid.system"便可ide
得到PackageManager的installPackage方法,因爲API隱藏和重寫,已經很難找到對應的installPackage,目前找到的是installPackage(String,String,String,String),具體參數未知,所以咱們須要使用frameworks層的相關代碼,得到IPackageManager,而且經過反射得到ServiceManager,實現IPackageInstallObserver相關方法工具
使用signApk+platform.x509.pem+platform.pk8對app進行簽名,使其具備系統簽名ui
認真處理以上條件this
有條件的的話,能夠從frameworks/base/core/java/android/content/pm下獲取這些文件,注意ManifestDigest使用了Google修改過的JDK,有些地方如IntegralString.appendByteAsHex沒法使用,所以ManifestDigest.java須要改良。spa
package com.app.mobile.slient; import java.io.File; import java.lang.reflect.Method; import android.app.Activity; import android.content.pm.IPackageInstallObserver; import android.content.pm.IPackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { /****表示安裝時以更新方式安裝,即app不存在時安裝,不然進行卸載再安裝****/ private final int INSTALL_REPLACE_EXISTING = 0x00000002; /****Apk存儲目錄,這裏我放置在了SDcard的Download目錄下****/ private final String sdPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(); private TextView mInstallTv; private EditText apkNameEt; @Override protected void onCreate(Bundle savedInstanceState) { 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(new View.OnClickListener() { @Override public void onClick(View v) { installPackage(); } }); } public void installPackage() { String apkName = apkNameEt.getText().toString(); PackageInstallObserver installObserver = new PackageInstallObserver(); try { String apkPath = sdPath.concat("/").concat(apkName).concat(".apk"); Class<?> ServiceManager = Class.forName("android.os.ServiceManager"); Method getService = ServiceManager.getDeclaredMethod("getService", String.class); getService.setAccessible(true); IBinder packAgeBinder = (IBinder) getService.invoke(null, "package"); IPackageManager iPm = IPackageManager.Stub.asInterface(packAgeBinder); iPm.installPackage(Uri.fromFile(new File(apkPath)), installObserver,INSTALL_REPLACE_EXISTING, new File(apkPath).getPath()); }catch (Exception e) { e.printStackTrace(); try { installObserver.packageInstalled(null, -1); } catch (RemoteException ignore) { } } } /** * 安裝監聽 */ public class PackageInstallObserver extends IPackageInstallObserver.Stub{ @Override public void packageInstalled(String packageName, int returnCode)throws RemoteException { 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簽名,不然安裝不了).net
2.將打包的apk使用signApk進行簽名,命令以下debug
java -jar signApk.jar platform.x509.pem platform.pk8 slientInstall.Apk newApk.apk
或者新建Java工程以下打包
public class TestCase { public static void main(String[] args) { try { Class<?> SignApk = Class.forName("com.android.signapk.SignApk"); Method mainMethod = SignApk.getDeclaredMethod("main", String[].class); if(!Modifier.isPublic(mainMethod.getModifiers()) || !mainMethod.isAccessible()) { mainMethod.setAccessible(true); } mainMethod.invoke(null, new Object[]{new String[]{"platform.x509.pem","platform.pk8","slientInstall.apk","newApk.apk"}}); System.out.println("-----O(∩_∩)O哈哈~----簽名成功-----O(∩_∩)O哈哈~----"); } catch (Exception e) { e.printStackTrace(); System.out.println("-----%>_<%----簽名失敗-----%>_<%----"); } } }
3.而後就能夠安裝了,開始試試吧
因爲開源中國不能上傳相應的附近,我把項目上傳到CSDN,請自行下載吧
下載地址:
http://download.csdn.net/detail/m_andrain/9018329