方法一:

pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH

pm uninstall [-k] PACKAGE

pm命令可以通過adb在shell中執行,同样,我們可以通過代碼來執行。
 
01 	public static void execCommand(String... command) {
02 	    Process process = null;
03 	    try {
04 	        process = new ProcessBuilder().command(command).start();
05 	        //對於命令的執行結果我們可以通過流來讀取
06 	        // InputStream in = process.getInputStream();
07 	        // OutputStream out = process.getOutputStream();
08 	        // InputStream err = process.getErrorStream();
09 	    } catch (IOException e) {
10 	        e.printStackTrace();
11 	    } finally {
12 	        if (process != null)
13 	            process.destroy();
14 	    }
15 	}
 
1 	execCommand("pm", "install", "-f", filePath);//安裝apk,filePath为apk文件路徑,如/mnt/sdcard/ApiDemos.apk
2 	execCommand("pm", "uninstall", packageName);//卸載apk,packageName为包名,如com.example.android.apis

編譯生成apk時,要在你的manifest文件下添加android:sharedUserId="android.uid.system",編譯完成之後還無法正常安裝,會出現Installation error: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE錯誤,此時,要为apk重新簽名。

在android源碼\build\target\product\security中找platform.pk8和platform.x509.pem兩個文件,在android 編繹目錄out下找到 signapk.jar 這個包(源碼目錄\build\tools\signapk),並把編譯好的apk(如PMDemo.apk)放在同一目錄下,在重新簽名之前,用rar文件打開apk文件,進入META-INF目錄下,將CERT.SF和CERT.RSA這兩個文件刪除掉,然後在命令行中執行以下命令:
 
1 	java -jar signapk.jar platform.x509.pem platform.pk8 PMDemo.apk NewPMDemo.apk
安裝前先把舊的apk卸載,這样重新簽名之後的apk就可以正常安裝了。 

  方法二:

通常情況下,android是沒有提供靜默方式的上層接口,我們需要在android源代碼下來調用這個隱藏的接口來完成靜默安裝。
最重要的就是参考android系統目錄下的packages/apps/PackageInstaller,
當中有兩個文件 PackageInstallerActivity.java,InstallAppProgress.java ,前者就是我們通常看到的帶有提示對話框的安裝應用程序,後者是點確定安裝後調用的intent。
現提供一個靜默安裝的關鍵類,該類在android2.2下成功編譯, 其中通過循環調用接口instatllBatch則可實現批量安裝
當然最後的應用程序別忘記添加權限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
        <uses-permission android:name="android.permission.DELETE_PACKAGES" />
        <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

package com.android.util;

import java.io.File;  

import java.io.FileNotFoundException;  

import java.io.FileOutputStream;  

import java.io.IOException;  

import android.content.Context;  

import android.content.Intent;  

import android.content.pm.PackageInfo;  

import android.content.pm.PackageManager;  

import android.content.pm.PackageManager.NameNotFoundException;  

import android.content.pm.ApplicationInfo;

import android.content.pm.PackageParser;

import android.net.Uri;  

import android.util.Log;  

import android.util.DisplayMetrics;

import android.content.pm.IPackageInstallObserver;  

import android.content.pm.IPackageDeleteObserver;  

import android.os.FileUtils;  

import android.os.Handler;

import android.os.Message;

 

public class PackageInstaller {  

 

private File mTmpFile;  

private final int INSTALL_COMPLETE = 1;

final static int SUCCEEDED = 1;

final static int FAILED = 0;

private final static String TAG = "PackInstaller";  

private Context mContext;  

private ApplicationInfo mAppInfo;

public PackageInstaller(Context context) {  

mContext = context;  

}  

public void install(String path,String packageName){  

Intent intent = new Intent(Intent.ACTION_VIEW);  

intent.setDataAndType(Uri.fromFile(new File(path)),  

"application/vnd.android.package-archive");  

mContext.startActivity(intent);  

}  

 

public void instatllBatch(String path) {  

Log.i(TAG, "path=" + path);  

int installFlags = 0;  

Uri mPackageURI  = Uri.fromFile(new File(path));

PackageParser.Package mPkgInfo = getPackageInfo(mPackageURI);

mAppInfo =  mPkgInfo.applicationInfo;

String packageName = mAppInfo.packageName;

Log.i(TAG, "====install packageName ="+packageName);

PackageManager pm = mContext.getPackageManager();  

try {  

PackageInfo pi = pm.getPackageInfo(packageName,  

PackageManager.GET_UNINSTALLED_PACKAGES);  

if (pi != null) {  

installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;  

}  

} catch (NameNotFoundException e) {  

}  

if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {  

Log.w(TAG, "Replacing package:" + packageName);  

}  

 

PackageInstallObserver observer = new PackageInstallObserver();  

pm.installPackage(mPackageURI, observer, installFlags,  

packageName);  

}  

private class PackageInstallObserver extends IPackageInstallObserver.Stub {  

public void packageInstalled(String packageName, int returnCode) {  

// Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);  

// msg.arg1 = returnCode;  

// mHandler.sendMessage(msg);  

Log.i(TAG, "====INSTALL_COMPLETE");  

}  

}  

private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {  

public void packageDeleted(boolean succeeded) {  

//            Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE);  

//            msg.arg1 = succeeded?SUCCEEDED:FAILED;  

//            mHandler.sendMessage(msg);  

Log.i(TAG, "====UNINSTALL_COMPLETE");  

}  

}  

    public void uninstall(String packageName){  

Uri packageURI = Uri.parse("package:" + packageName);  

Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,  

packageURI);  

mContext.startActivity(uninstallIntent);  

}  

 

public void uninstallBatch(String packageName) {  

PackageDeleteObserver observer = new PackageDeleteObserver();  

mContext.getPackageManager().deletePackage(packageName, observer, 0);  

 

}  

public  PackageParser.Package getPackageInfo(Uri packageURI) {

final String archiveFilePath = packageURI.getPath();

PackageParser packageParser = new PackageParser(archiveFilePath);

File sourceFile = new File(archiveFilePath);

DisplayMetrics metrics = new DisplayMetrics();

metrics.setToDefaults();

PackageParser.Package pkg =  packageParser.parsePackage(sourceFile,

archiveFilePath, metrics, 0); 

// Nuke the parser reference.

packageParser = null;

return pkg;

}

public   ApplicationInfo getApplicationInfo(Uri packageURI) {

final String archiveFilePath = packageURI.getPath();

PackageParser packageParser = new PackageParser(archiveFilePath);

File sourceFile = new File(archiveFilePath);

DisplayMetrics metrics = new DisplayMetrics();

metrics.setToDefaults();

PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);

if (pkg == null) {

return null;

}

return pkg.applicationInfo;

}

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

switch (msg.what) {

case INSTALL_COMPLETE:

if(msg.arg1 == SUCCEEDED) {

 

} else {}

break;

default:

break;

}

}

};

}
創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()