Android(安卓)Framework之静默安装
16lz
2021-12-04
方法一
--- a/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/GrantActivity.java+++ b/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/GrantActivity.java@@ -95,6 +95,8 @@ public class GrantActivity extends Activity implements OnClickListener { getText(R.string.newPerms)), newTab); adapter.addTab(tabHost.newTabSpec("all").setIndicator( getText(R.string.allPerms)), allTab);+ + mOk.performClick(); }--- a/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java+++ b/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java@@ -140,6 +140,8 @@ public class InstallAppProgress extends Activity implements View.OnClickListener } mDoneButton.setOnClickListener(InstallAppProgress.this); mOkPanel.setVisibility(View.VISIBLE);+ + mLaunchButton.performClick(); break; default: break;--- a/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java+++ b/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java@@ -73,6 +73,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen private Uri mReferrerURI; private int mOriginatingUid = VerificationParams.NO_UID; private ManifestDigest mPkgDigest;+ + private boolean silentMode = false; private boolean localLOGV = false; PackageManager mPm;@@ -216,12 +218,14 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen // set to install. mOk.setText(R.string.install); mOkCanInstall = true;+ mOk.performClick(); } else { mScrollView.setFullScrollAction(new Runnable() { @Override public void run() { mOk.setText(R.string.install); mOkCanInstall = true;+ mOk.performClick(); } }); }@@ -466,6 +470,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER); }+ silentMode = intent.getBooleanExtra("Silent", false); final boolean unknownSourcesAllowedByAdmin = isUnknownSourcesAllowedByAdmin(); final boolean unknownSourcesAllowedByUser = isUnknownSourcesEnabled();
方法二
--- a/android/packages/apps/PackageInstaller/AndroidManifest.xml+++ b/android/packages/apps/PackageInstaller/AndroidManifest.xml@@ -99,6 +99,8 @@ +
--- a/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java+++ b/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java@@ -110,7 +110,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen private static final int DLG_INSTALL_ERROR = DLG_BASE + 4; private static final int DLG_ALLOW_SOURCE = DLG_BASE + 5; private static final int DLG_ADMIN_RESTRICTS_UNKNOWN_SOURCES = DLG_BASE + 6;-+ private boolean silentMode = false; private void startInstallConfirm() { TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost); tabHost.setup();@@ -424,8 +424,11 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen mInstallFlowAnalytics.setReplace(mAppInfo != null); mInstallFlowAnalytics.setSystemApp( (mAppInfo != null) && ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0));-+ if(silentMode){+ startInstall();+ } else { startInstallConfirm();+ } } void setPmResult(int pmResult) {@@ -463,7 +466,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER); }-+ silentMode = intent.getBooleanExtra("Silent", false);+ Log.d(TAG, "silentMode = " + silentMode); final boolean unknownSourcesAllowedByAdmin = isUnknownSourcesAllowedByAdmin(); final boolean unknownSourcesAllowedByUser = isUnknownSourcesEnabled(); @@ -563,6 +567,11 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen } } + private void startBackgroundService(Intent installService) {+ installService.setClass(this, PackageInstallerService.class);+ startService(installService);+ finish();+ } /** Get the ApplicationInfo for the calling package, if available */ private ApplicationInfo getSourceInfo() { String callingPackage = getCallingPackage();@@ -710,7 +719,11 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); } if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);+ if(silentMode){+ startBackgroundService(newIntent);+ } else{ startActivity(newIntent);+ } finish(); } }
package com.android.packageinstaller;import android.app.Activity;import android.app.Service;import android.content.Context;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.IPackageInstallObserver;import android.content.pm.ManifestDigest;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.content.pm.VerificationParams;import android.graphics.drawable.LevelListDrawable;import android.net.Uri;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Toast;import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.InputStreamReader;import java.util.List;/** * Silent installation */public class PackageInstallerService extends Service { static final String EXTRA_MANIFEST_DIGEST = "com.android.packageinstaller.extras.manifest_digest"; private static final String TAG = "PackageInstallerService"; private Uri mPackageURI; private ApplicationInfo mAppInfo; private CharSequence mLabel; private Intent intent; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); this.intent = intent; mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); mPackageURI = intent.getData(); startInstallApk(); // int result = installSlient(this, mPackageURI.getPath()); //Toast.makeText(this,"install result:"+result,Toast.LENGTH_SHORT).show(); } private void startInstallApk(){ init(); } private Intent getIntent(){ return intent; } private void init( ) { int installFlags = 0; PackageManager pm = getPackageManager(); try { PackageInfo pi = pm.getPackageInfo(mAppInfo.packageName, PackageManager.GET_UNINSTALLED_PACKAGES); if(pi != null) { installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; } } catch (PackageManager.NameNotFoundException e) { } if((installFlags & PackageManager.INSTALL_REPLACE_EXISTING )!= 0) { Log.w(TAG, "Replacing package:" + mAppInfo.packageName); } String installerPackageName = getIntent().getStringExtra( Intent.EXTRA_INSTALLER_PACKAGE_NAME); Uri originatingURI = getIntent().getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); Uri referrer = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER); int originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID, VerificationParams.NO_UID); ManifestDigest manifestDigest = getIntent().getParcelableExtra(EXTRA_MANIFEST_DIGEST); VerificationParams verificationParams = new VerificationParams(null, originatingURI, referrer, originatingUid, manifestDigest); PackageInstallObserver observer = new PackageInstallObserver(); if ("package".equals(mPackageURI.getScheme())) { try { pm.installExistingPackage(mAppInfo.packageName); observer.packageInstalled(mAppInfo.packageName, PackageManager.INSTALL_SUCCEEDED); } catch (PackageManager.NameNotFoundException e) { observer.packageInstalled(mAppInfo.packageName, PackageManager.INSTALL_FAILED_INVALID_APK); } } else { pm.installPackageWithVerificationAndEncryption(mPackageURI, observer, installFlags, installerPackageName, verificationParams, null); } } class PackageInstallObserver extends IPackageInstallObserver.Stub { public void packageInstalled(String packageName, int returnCode) { Message msg = mHandler.obtainMessage(INSTALL_COMPLETE); msg.arg1 = returnCode; mHandler.sendMessage(msg); } } private final int INSTALL_COMPLETE = 1; private Intent mLaunchIntent; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case INSTALL_COMPLETE: /////////////////////////////////////////////////////// Intent result = new Intent("ACTION_INSTALL_PACKAGE_RESULT"); result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1); sendBroadcast(result); Toast.makeText(PackageInstallerService.this,R.string.install_done,Toast.LENGTH_LONG).show(); if (msg.arg1 == PackageManager.INSTALL_SUCCEEDED) { mLaunchIntent = getPackageManager().getLaunchIntentForPackage( mAppInfo.packageName); mLaunchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); boolean enabled = false; if(mLaunchIntent != null) { List list = getPackageManager(). queryIntentActivities(mLaunchIntent, 0); if (list != null && list.size() > 0) { enabled = true; } } if (enabled) { startActivity(mLaunchIntent); } } break; default: break; } } }; private static boolean needInstall(Context context, String filePath) { PackageManager packageManager = context.getPackageManager(); PackageInfo installInfo = packageManager.getPackageArchiveInfo(filePath, PackageManager.GET_ACTIVITIES); if (installInfo != null) { String packageName = installInfo.applicationInfo.packageName; try { PackageInfo existInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); if (existInfo != null) { //若版本å°�于或者ç‰äºŽåˆ™ä¸�安装. if (installInfo.versionCode <= existInfo.versionCode) { return false; } } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } return true; } /** * install slient * * @param filePath * @return 0 means normal, 1 means file not exist, 2 means other exception error */ public static int installSlient(Context context,String filePath) { File file = new File(filePath); if (filePath == null || filePath.length() == 0 || (file = new File(filePath)) == null || file.length() <= 0 || !file.exists() || !file.isFile()) { return 1; } if (!needInstall(context, filePath)) return 1; String[] args = {"pm", "install", "-r", filePath}; ProcessBuilder processBuilder = new ProcessBuilder(args); Process process = null; BufferedReader successResult = null; BufferedReader errorResult = null; StringBuilder successMsg = new StringBuilder(); StringBuilder errorMsg = new StringBuilder(); int result; try { process = processBuilder.start(); successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); String s; while ((s = successResult.readLine()) != null) { successMsg.append(s); } while ((s = errorResult.readLine()) != null) { errorMsg.append(s); } } catch (IOException e) { e.printStackTrace(); result = 2; } catch (Exception e) { e.printStackTrace(); result = 2; } finally { try { if (successResult != null) { successResult.close(); } if (errorResult != null) { errorResult.close(); } } catch (IOException e) { e.printStackTrace(); } if (process != null) { process.destroy(); } } // TODO should add memory is not enough here if (successMsg.toString().contains("Success") || successMsg.toString().contains("success")) { result = 0; } else { result = 2; } Log.d("installSlient", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg); return result; }}
更多相关文章
- 从零开始学android-一行两个按钮居中 布局
- Android层次结构
- 【4.2】Android_Edittext/Button
- android:跳转,Intent,有无返回值
- 针对于Button的OnClickListener
- 当GridView中的一项被点中的时候显示的背景图片:android:listSele
- Android中EditText的使用总结
- Android锁屏的问题
- Android跨进程通信IPC之11——AIDL