权限"/>
ApplicationPackageManager实现静默安装,需要系统权限
背景介绍
条件:
1.不使用Process process = Runtime.getRuntime().exec(pm install -r ....)执行shell命令。为什么不使用是因为su拿得到前提是系统支持。
2.需要拥有系统权限,即系统签名+android:sharedUserId="android.uid.system"。
实现方式
1.使用eclipse打系统jar只包含如下,打系统jar包的时候,只复制如下几个文件,然后忽略所有error直接export jar包
传送门 ApplicationPackageManager.java,PackageInstallObserver.java
2.jar放在Android Studio显示如下:
你会发现class文件会有各种error,不管。(因为接着我们会使用compileOnly)
App Gradle配置:
根Gradle配置
3.在src/main/aidl 下面也要创建IPackageInstallObserver.aidl和PackageManager.jar里面的文件一样,如果这里不放的话会提示找不到IPackageInstallObserver错误。请注意。
静默安装
public class InstallUtils {public static final String path = "sdcard/Android/data/com.xxx/cache/xxxx.apk";public static void installByPackageManager(Context context, String path) {PackageManager packageManager = context.getPackageManager();if (packageManager instanceof ApplicationPackageManager) {((ApplicationPackageManager)packageManager).installPackage(Uri.fromFile(new File(path)),new MyPackageInstallObserver(),0,"com.android.vending");}}private static class MyPackageInstallObserver extends PackageInstallObserver{public void onUserActionRequired(Intent intent) {}public void onPackageInstalled(String basePackageName, int returnCode, String msg,Bundle extras) {LogUtils.d(LogUtils.TAG,"MyPackageInstallObserver--onPackageInstalled basePackageName="+basePackageName);}}
}
分析
ApplicationPackageManager 构造器传IPackageManager
protected ApplicationPackageManager(ContextImpl context,IPackageManager pm) {mContext = context;mPM = pm;}
@Overridepublic void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,String installerPackageName) {installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,installerPackageName, mContext.getUserId());}@Overridepublic void installPackage(Uri packageURI, PackageInstallObserver observer,int flags, String installerPackageName) {installCommon(packageURI, observer, flags, installerPackageName, mContext.getUserId());}private void installCommon(Uri packageURI,PackageInstallObserver observer, int flags, String installerPackageName,int userId) {if (!"file".equals(packageURI.getScheme())) {throw new UnsupportedOperationException("Only file:// URIs are supported");}final String originPath = packageURI.getPath();try {mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,userId);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
IPackageManager的父类其实是 PackageManagerService.java 最终的PackageManager的方法调用都是Service进行执行,如下:
public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,int installFlags, String installerPackageName, int userId) {mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);final int callingUid = Binder.getCallingUid();enforceCrossUserPermission(callingUid, userId,true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {try {if (observer != null) {observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);}} catch (RemoteException re) {}return;}if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {installFlags |= PackageManager.INSTALL_FROM_ADB;} else {// Caller holds INSTALL_PACKAGES permission, so we're less strict// about installerPackageName.installFlags &= ~PackageManager.INSTALL_FROM_ADB;installFlags &= ~PackageManager.INSTALL_ALL_USERS;}UserHandle user;if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {user = UserHandle.ALL;} else {user = new UserHandle(userId);}// Only system components can circumvent runtime permissions when installing.if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0&& mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {throw new SecurityException("You need the "+ "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "+ "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");}if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0|| (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {throw new IllegalArgumentException("New installs into ASEC containers no longer supported");}final File originFile = new File(originPath);final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);final Message msg = mHandler.obtainMessage(INIT_COPY);final VerificationInfo verificationInfo = new VerificationInfo(null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,null /*packageAbiOverride*/, null /*grantedPermissions*/,null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));msg.obj = params;Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",System.identityHashCode(msg.obj));Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",System.identityHashCode(msg.obj));mHandler.sendMessage(msg);}
更多推荐
ApplicationPackageManager实现静默安装,需要系统权限
发布评论