android手機在獲得root許可權之後,可以調用命令的方式靜默安裝軟體,這一點體驗是很不錯,但是目前網路上關於android靜默安裝app的代碼均出自一人之手,其中有一個非常sb的bug,借用代碼的人居然都沒有發現,導致網路上幾乎所有關於android app靜默安裝的代碼都是錯誤的。
| 代碼如下 |
複製代碼 |
|
new Thread() {
public void run() {
Process process = null;
OutputStream out = null;
InputStream in = null;
try {
// 請求root
process = Runtime.getRuntime().exec("su");
out = process.getOutputStream();
// 調用安裝
out.write(("pm install -r " + currentTempFilePath + "
").getBytes());
in = process.getInputStream();
int len = 0;
byte[] bs = new byte[256];
while (-1 != (len = in.read(bs))) {
String state = new String(bs, 0, len);
if (state.equals("Success
")) {
//安裝成功後的操作
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.flush();
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start(); |
這個代碼實際上也可以運行起來,在root的手機中,也可以靜默安裝成功,但是代碼有問題就是bug,不知道哪一天這個有問題的代碼就會出現錯誤
下面是修改之後的代碼,修改了上面的bug
| 代碼如下 |
複製代碼 |
|
new Thread() {
public void run() {
Process process = null;
OutputStream out = null;
InputStream in = null;
try {
// 請求root
process = Runtime.getRuntime().exec("su");
out = process.getOutputStream();
// 調用安裝
System.out.println(apkFile.getAbsolutePath());
out.write(("pm install -r " + apkFile.getAbsolutePath() + "
").getBytes());
in = process.getInputStream();
int len = 0;
int readLen = 0;
byte[] bs = new byte[256];
//讀出所有的輸出資料
while (-1 != (readLen = in.read(bs))) {
len = len + readLen;
//如果讀的資料大於緩衝區。則停止
if (len > bs.length) {
len -= readLen;
break;
}
}
String state = new String(bs, 0, len);
if (state.startsWith("Success")) {
// 安裝成功後的操作
}
else {
//靜默安裝失敗,使用手動安裝
installByUser();
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.flush();
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start(); |
修改的地方就在於從輸出資料流中讀取輸出資料,可以看出如果輸出的資料大於緩衝區大小(256),就會導致安裝後的操作多次執行,上面這段錯誤的代碼之所以可以運行,是在於輸出資料流的輸出為Success ,小於256,但是如果運行指令出錯,返回一大推的錯誤,那麼上面的那一段將讀取所有的資料,讀逐一進行比較。