Android Framework之静默安装

方法一

--- 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 Framework之静默安装)