我们在工作中经常遇到一些客户提出静默安装与静默卸载的需求,应该说这个问题是比较简单的,但总有人在问,所以这里简单记录一下。
/**
* 静默安装
* @param apkFilePath 文件名
* @param installOnSdCard 是否安装到SD卡
* @return
*/
public boolean installApplication(String apkFilePath,boolean installOnSdCard){
PackageInstallObserver installObserver = new PackageInstallObserver();
File file=new File(apkFilePath);
Uri uri=Uri.fromFile(file);
//一般客户给的参数就是apk文件的路径,包名必须通过以下方式进行解析
PackageParser packageParser=new PackageParser();
String packageName=null;
try{
ApplicationInfo appInfo=packageParser.parsePackage(file, 0).applicationInfo;
packageName=appInfo.packageName;
}catch(PackageParserException ex){
return false;
}
PackageManager pm = mContext.getPackageManager();
int installFlags = 0;
try {
PackageInfo pi = pm.getPackageInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
if (pi != null) {
installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
}
} catch (NameNotFoundException e) {
Log.i(TAG,"NameNotFoundException");
}
if(installOnSdCard){
installFlags|=PackageManager.INSTALL_EXTERNAL;
}else{
installFlags|=PackageManager.INSTALL_INTERNAL;
}
installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
pm.installPackage(uri, installObserver, installFlags, packageName);
synchronized(installObserver){
long waitTime = 0;
while (!installObserver.doneFlag) {
Log.i(TAG,"installObserver.returnCode="+installObserver.returnCode);
try {
installObserver.wait();
//可以设置一个安装超时的时间
// waitTime += WAIT_TIME_INCR;
} catch (InterruptedException e) {
Log.i(TAG, "Interrupted during sleep", e);
return false;
}
}
return installObserver.returnCode==1?true:false;
}
}
核心api:installPackage,关键参数:installObserver
/**
* 监听应用安装
*/
class PackageInstallObserver extends IPackageInstallObserver.Stub{
public int returnCode;
private boolean doneFlag = false;
public void packageInstalled(String packageName, int returnCode) {
synchronized(this){
this.returnCode = returnCode;
Log.i(TAG,"returnCode="+returnCode);
doneFlag = true;
notifyAll();
}
}
}
同理,静默卸载类似如下:
/**
* 静默卸载
* @param packageName 应用名
* @param keepDataAndCache 是否保留数据
* @return
*/
public boolean uninstallApplication(String packageName, boolean keepDataAndCache){
PackageDeleteObserver deleteObserver=new PackageDeleteObserver();
PackageManager pm = mContext.getPackageManager();
int flags=0;
if(keepDataAndCache)
flags|=PackageManager.DELETE_KEEP_DATA;
pm.deletePackage(packageName, deleteObserver, flags);
synchronized(deleteObserver){
long waitTime = 0;
while (!deleteObserver.doneFlag) {
Log.i(TAG,"deleteObserver.returnCode="+deleteObserver.returnCode);
try {
deleteObserver.wait();
// waitTime += WAIT_TIME_INCR;
} catch (InterruptedException e) {
Log.i(TAG, "Interrupted during sleep", e);
}
}
return deleteObserver.returnCode==1?true:false;
}
}
/**
* 监听应用卸载
*/
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
public int returnCode;
private boolean doneFlag = false;
public void packageDeleted(String packageName,int returnCode){
synchronized(this){
this.returnCode = returnCode;
Log.i(TAG,"returnCode="+returnCode);
doneFlag = true;
notifyAll();
}
}
}
最后,别忘了在子线程中进行操作。