静默安装

最近在做有关静默安装和静默卸载的功能,6.0之前可以使用:

String[] args = null;
		if (loc == InsLoc.EXT) {
			args = new String[]{ _pm, _install, __r, __s, apkAbsolutePath };
		} else if (loc == InsLoc.INT){
			args = new String[]{ _pm, _install, __r, __f, apkAbsolutePath };
		} else {
			args = new String[]{ _pm, _install, __r, apkAbsolutePath };
		}

		String result = "";
		ProcessBuilder processBuilder = new ProcessBuilder(args);
		Process process = null;
		DataInputStream errIs = null;
		DataInputStream inIs = null;
		try {
			process = processBuilder.start();
			MyLog.d(TAG, "----install before waitfor----");
			int r = process.waitFor();
			MyLog.d(TAG, "----install after waitfor----r:" + r);

			errIs = new DataInputStream(process.getErrorStream());
			String line = null;
			while ((line = errIs.readLine()) != null) {
				MyLog.d(TAG, "----err line:[" + line + "]----");
				if (line.contains(_Failure)) {
					result = line;
				}
			}
			inIs = new DataInputStream(process.getInputStream());
			line = null;
			while ((line = inIs.readLine()) != null) {
				MyLog.d(TAG, "----std line:[" + line + "]----");
				if (line.contains(_Success)) {
					result = line;
				}
			}
		} catch (IOException e) {
			MyLog.w(TAG, "----install ERROR:" + e.getMessage());
		} catch (Exception e) {
			MyLog.w(TAG, "----install ERROR:" + e.getMessage());
		} finally {
			try {
				if (errIs != null) {
					errIs.close();
				}
				if (inIs != null) {
					inIs.close();
				}
			} catch (IOException e) {
			}
			if (process != null) {
				process.destroy();
			}
		}

能够正常静默,必须使用root样机。

当放到7.0样机上时,发现静默不了:出现java.lang.SecurityException: Package xxxx does not belong to 10054异常。通过不断的google和度娘,最终使用下面的方法解决:

 String result = "";
//        ProcessBuilder processBuilder = new ProcessBuilder(args);
        Process process = null;
        DataInputStream errIs = null;
        DataInputStream inIs = null;
        try {
            process = Runtime.getRuntime().exec("pm install -i "+packageName+" --user 0 "+apkAbsolutePath);
            MyLog.d(TAG, "----install before waitfor----");
            int r = process.waitFor();
            MyLog.d(TAG, "----install after waitfor----r:" + r);

            errIs = new DataInputStream(process.getErrorStream());
            String line = null;
            while ((line = errIs.readLine()) != null) {
                MyLog.d(TAG, "----err line:[" + line + "]----");
                if (line.contains(_Failure)) {
                    result = line;
                }
            }
            inIs = new DataInputStream(process.getInputStream());
            line = null;
            while ((line = inIs.readLine()) != null) {
                MyLog.d(TAG, "----std line:[" + line + "]----");
                if (line.contains(_Success)) {
                    result = line;
                }
            }
        } catch (IOException e) {
            MyLog.w(TAG, "----install ERROR:" + e.getMessage());
        } catch (Exception e) {
            MyLog.w(TAG, "----install ERROR:" + e.getMessage());
        } finally {
            try {
                if (errIs != null) {
                    errIs.close();
                }
                if (inIs != null) {
                    inIs.close();
                }
            } catch (IOException e) {
            }
            if (process != null) {
                process.destroy();
            }
        }
        return result;

值得注意的是,上面的package指的是自身应用的package。当时就因为这个package踩了不少坑。

有关静默卸载:6.0以下使用:

String[] args = null;
    	if (keepData){
    		args = new String[]{ _pm, _uninstall, __k, packageName };
    	}else {
    		args = new String[]{ _pm, _uninstall, packageName };
    	}
    	
		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);
			MyLog.i(TAG, "----unInstallPackage exec cmd finish:[" + result.trim() + "]");
		} catch (IOException e) {
			MyLog.w(TAG, "----unInstallPackage ERR:" + e.getMessage(), e);
		} catch (Exception e) {
			MyLog.w(TAG, "----unInstallPackage ERR:" + e.getMessage(), e);
		} finally {
			try {
				if (errIs != null) {
					errIs.close();
				}
				if (inIs != null) {
					inIs.close();
				}
			} catch (IOException e) {
				MyLog.w(TAG, "----unInstallPackage WARN:" + e.getClass().getName() + "--" + e.getMessage(), e);
			}
			if (process != null) {
				process.destroy();
			}
		}
		return result;

能够正常在root样机下卸载,但是到了6.0以上的时候。又坑爹了。经过研究可以使用反射:

 try {
            PackageManager pm = context.getPackageManager();
            Method[] methods = pm != null ? pm.getClass().getDeclaredMethods() : null;
            Method mDel = null;
            if (methods != null && methods.length > 0) {
                for (Method method : methods) {
                    if (method.getName().toString().equals("deletePackage")) {
                        mDel = method;
                        break;
                    }
                }
            }

            if (mDel != null) {
                mDel.setAccessible(true);
                mDel.invoke(pm, pkgName,null, 0);
            }

        } catch (Exception e) {

        }

基本就是这样了。~~

猜你喜欢

转载自blog.csdn.net/github_37271067/article/details/81085515