靜默安裝建车,就是apk在后臺悄悄地安裝扩借。很多流氓軟件喜歡干。但從現(xiàn)在的情況看缤至,只有root了的手機潮罪,或者你能搞到手機廠商的簽名,才能靜默安裝。
關(guān)于靜默安裝领斥,基本上有兩種情況嫉到。
1.root情況下靜默安裝
2.非root下面靜默安裝
root情況靜默安裝##
1.調(diào)用pm指令,下面就是調(diào)用pm指令(pm install -r)把/sdcard/haha.apk安裝掉月洛。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
runShellCommand("pm install -r /sdcard/haha.apk")何恶; //執(zhí)行命令
}
private void runShellCommand(String command) {
Process process = null;
BufferedReader bufferedReader = null;
StringBuilder mShellCommandSB =new StringBuilder();
Log.d("wenfeng", "runShellCommand :" + command);
mShellCommandSB.delete(0, mShellCommandSB.length());
String[] cmd = new String[] { "/system/bin/sh", "-c", command }; //調(diào)用bin文件
try {
byte b[] = new byte[1024];
process = Runtime.getRuntime().exec(cmd);
bufferedReader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
mShellCommandSB.append(line);
}
Log.d("wenfeng", "runShellCommand result : " + mShellCommandSB.toString());
process.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
// TODO: handle exception
}
}
if (process != null) {
process.destroy();
}
}
}
2.調(diào)用cp指令,把apk拷貝到data/app目錄下,把上面的runShellCommand("pm install -r /sdcard/haha.apk")替換成下面這句嚼黔。然后用戶下次重啟時细层,apk就會自動安裝。
runShellCommand("cp /sdcard/haha.apk /data/app")
非root下面靜默安裝##
1.調(diào)用輔助功能唬涧,跟搶紅包原理差不多疫赎。其實這種方式并不算嚴格的靜默安裝,因為用戶可以看到安裝的界面爵卒。很多應(yīng)用商店都用到這種方式批量安裝apk虚缎,下載后自動彈出安裝界面,然后自動幫你點擊安裝。就能搶紅包一樣实牡,自動打開紅包頁面陌僵,自動點擊紅包的道理一樣一樣的。
這個輔助功能最開始google設(shè)計是用于殘疾人的创坞,讓他們更加方便的使用手機碗短。一個應(yīng)用要獲取輔助功能,要在設(shè)置里面授權(quán)题涨。
2.反射調(diào)用PackageManager
這個在百度搜索偎谁,大多數(shù)是出現(xiàn)這篇文章
Android 無需root實現(xiàn)apk的靜默安裝
關(guān)于這種方式,想法很好纲堵。
但是其實是不可行的巡雨。
而且文章的實現(xiàn)過于復(fù)雜了,其實不需要這么復(fù)雜席函,拉出一大坨類铐望。如果你有Android系統(tǒng)源碼的話,在源碼環(huán)境編譯只需要在Android.mk增加一句就可以了,把framework.jar包含進去編譯茂附,自然就可以找到那一大坨類正蛙。
LOCAL_JAVA_LIBRARIES := \
framework \
然后就可以直接在代碼里面引用IPackageManager那些類了。
public static void install()
{
String path = "sdcard";
String fileName = path + "/haha.apk";
File file = new File(fileName);
try {
Class<?> clazz = Class.forName("android.os.ServiceManager");
Method method = clazz.getMethod("getService", String.class);
IBinder iBinder = (IBinder) method.invoke(null, "package");
IPackageManager ipm = IPackageManager.Stub.asInterface(iBinder);
@SuppressWarnings("deprecation")
VerificationParams verificationParams = new VerificationParams(null, null, null, VerificationParams.NO_UID, null);
ipm.installPackageAsUser(fileName, null, 2, null, verificationParams, "armeabi-v7a",0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
上面我說這種方式是不可行的营曼,原因是:
1.installPackageAsUser會遠程調(diào)用PackageManagerService進行安裝乒验,但安裝前需要校驗權(quán)限,只有System權(quán)限以上才能通過校驗蒂阱。所以為了編譯System權(quán)限的app锻全,需要在AndroidManifest增加一句 android:sharedUserId="android.uid.system"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.haha"
android:sharedUserId="android.uid.system"
android:versionName="V1.01" >
2.但你以為你這個System權(quán)限的app可以安裝到現(xiàn)實手機中嗎?不可能的蒜危,系統(tǒng)在安裝AndroidManifest包含android:sharedUserId="android.uid.system"的app時虱痕,都會首先看下app的簽名。app簽名不對直接就安裝失敗的辐赞。
所以部翘,那篇文章的app根本不可能安裝到手機中去。除非响委,你能搞到手機廠家的簽名P滤肌!W阜纭夹囚!簽名這個可是重大機密,泄露可是要出人命的邀窃。