静默安装APP
private String apkPath = Environment.getExternalStorageDirectory()
.getPath() + "/HelloInstallMe.apk";
String result = install(apkPath);
private String install(String apkAbsolutePath) {
String[] args = { "pm", "install", "-r", apkAbsolutePath };
String result = "";
ProcessBuilder processBuilder = new ProcessBuilder(args);
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read = -1;
process = processBuilder.start();
errIs = process.getErrorStream();
while ((read = errIs.read()) != -1) {
baos.write(read);
}
baos.write('\n');
inIs = process.getInputStream();
while ((read = inIs.read()) != -1) {
baos.write(read);
}
byte[] data = baos.toByteArray();
result = new String(data);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (errIs != null) {
errIs.close();
}
if (inIs != null) {
inIs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
return result;
}
执行完成之后,就安装完毕,这个方法可以正常执行覆盖apk操作;
所以可以等价更新功能;
在安装APP的时候,有些场景可能需要你判断APP是否存在,再进行安装与否:
下面的PackageCheck.java可以实现判断:
public class PackageCheck {
public static String getPackageName(Context context,String packageName){
final PackageManager packageManager = context.getPackageManager();
List< PackageInfo> pinfo = packageManager.getInstalledPackages(0);//获取所有已安装程序
List<String> pName = new ArrayList<String>();//用于存储所有已安装程序的包名
if(pinfo != null){
for(int i = 0; i < pinfo.size(); i++){
String pn = pinfo.get(i).packageName;
pName.add(pn);
}
}
boolean result = pName.contains(packageName);
if(result){
return packageName;
}else{
return null;
}
}
}
如果需要从assets目录下安装另外一个应用程序,可以先进行拷贝到SD卡中再重复上面的步骤;
public class Copy {
private static String tag = "Copy";
public static int copyTest(Context context) {
Log.i(tag, "copy from assets/HelloInstallMe01.apk ------> "
+ MainActivity.apkPath1);
return copyApkFromAssets(context, "HelloInstallMe01.apk",
MainActivity.apkPath1);
}
public static int copyApkFromAssets(Context context, String fileName,
String path) {
if (isSdCardExist(path)) {
Log.i(tag, "copy file is exist .... ");
return 2;
}
try {
InputStream is = context.getAssets().open(fileName);
File file = new File(path);
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] temp = new byte[1024];
int i = 0;
while ((i = is.read(temp)) > 0) {
fos.write(temp, 0, i);
}
fos.close();
is.close();
Log.i(tag, "copy success ");
return 1;
} catch (IOException e) {
Log.e(tag, "copy file fail .... ");
e.printStackTrace();
return 0;
}
}
// 判断sd卡中是否存在安装包
public static boolean isSdCardExist(String path) {
File file = new File(path);
return file.exists();
}
}
这里的判断存在,其中sd卡目录为:
public static String apkPath1 = Environment.getExternalStorageDirectory()
.getPath() + "/HelloInstallMe01.apk";
权限:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<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" />
静默安装一般不适用于通用安卓手机,因为没有取得root权限无法正确执行的,即使是豌豆荚360手机助手等,也是通过获取root权限才能使用静默安装;