Android 無須獲取Root權限靜默安裝App

參考連接java

android 靜默安裝
android

[Android]實現靜默安裝APK的兩種方法
app


一.非Root便可靜默安裝APK須要知足如下條件
  1. app進程和系統app進程是同一個進程,這個設置 android:sharedUserId="android.uid.system"便可ide

  2. 得到PackageManager的installPackage方法,因爲API隱藏和重寫,已經很難找到對應的installPackage,目前找到的是installPackage(String,String,String,String),具體參數未知,所以咱們須要使用frameworks層的相關代碼,得到IPackageManager,而且經過反射得到ServiceManager,實現IPackageInstallObserver相關方法工具

  3. 使用signApk+platform.x509.pem+platform.pk8對app進行簽名,使其具備系統簽名ui

  4. 認真處理以上條件this


二.具體代碼截圖與說明

有條件的的話,能夠從frameworks/base/core/java/android/content/pm下獲取這些文件,注意ManifestDigest使用了Google修改過的JDK,有些地方如IntegralString.appendByteAsHex沒法使用,所以ManifestDigest.java須要改良。spa

三.核心代碼MainActivity實現
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
相關文章
相關標籤/搜索