Android 无须获取Root权限静默安装App

参考链接

android 静默安装

[Android]实现静默安装APK的两种方法


一.非Root即可静默安装APK需要满足以下条件
  1. app进程和系统app进程是同一个进程,这个设置 android:sharedUserId="android.uid.system"即可

  2. 获得PackageManager的installPackage方法,由于API隐藏和重写,已经很难找到对应的installPackage,目前找到的是installPackage(String,String,String,String),具体参数未知,因此我们需要使用frameworks层的相关代码,获得IPackageManager,并且通过反射获得ServiceManager,实现IPackageInstallObserver相关方法

  3. 使用signApk+platform.x509.pem+platform.pk8对app进行签名,使其具有系统签名

  4. 认真处理以上条件


二.具体代码截图与说明

Android 无须获取Root权限静默安装App

有条件的的话,可以从frameworks/base/core/java/android/content/pm下获取这些文件,注意ManifestDigest使用了Google修改过的JDK,有些地方如IntegralString.appendByteAsHex无法使用,因此ManifestDigest.java需要改良。

三.核心代码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签名,否则安装不了)

2.将打包的apk使用signApk进行签名,命令如下

java -jar signApk.jar platform.x509.pem platform.pk8 slientInstall.Apk newApk.apk

或者新建Java工程如下打包

Android 无须获取Root权限静默安装App

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



你可能感兴趣的:(无root静默安装apk,静默安装app,android静默安装)