Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 靜默安裝apk的方法--Android是否可以實現靜默安裝模式

靜默安裝apk的方法--Android是否可以實現靜默安裝模式

編輯:關於Android編程

只對於能看懂能編譯安卓源碼的兄弟們:


pakcagemanagerservice.java中三個installpackage打頭的函數

最後一個函數第一行代碼就是檢查這個PERMISSION,去掉就可以了。

但是您不能直接去掉原來的函數裡面的代碼,您可以自行添加一個API,函數和installpackage裡面的一樣,差別就是少了檢查PERMISSION這行


下面這個文章有點老了

(1)在網上搜尋該問題的解決方法,且查閱android開發文檔,沒有發現可以實現該功能的顯示API調用,網絡上很多人請教同樣的問題,但都沒有能夠實現解答;說是android為了用戶的安全,已屏蔽該實現該方法的功能,第三方法應用是無法實現靜默安裝的。
(2)然後自己試圖去看看android實現普通安裝程序的源碼文件,能否找到解決的辦法,打算繞過普通安裝時的提示框,直接調用通過確認後調用的函數進行安裝;在查看android應用程序的普通安裝過程後,發現應用程序安裝過程的方法調用過程為:首先進入到com/android/packageinstaller/PackageInstallerActivity.java這個Activity中,在這個Activity中首先檢查所欲安裝的程序是否是正確的安裝文件,以及當前系統中是否已安裝了此應用程序,提示用戶是否重復安裝,另外還獲取所欲安裝的程序所講用到的權限,然後將這些信息通過一個對話框提示給用戶,當用戶確定安裝時,啟動com.android.packageinstaller.InstallAppProgress.java這個Activity,在這個Activity中,調用

android.content.pm.PackageManager.installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName)進行安裝應用程序,在InstallAppProgress中得到的PackageManager是通過PackageManager pm = getPackageManager()得到的,得到的對象是一個android.app.ContextImpl.ApplicationPackageManager對象,而

ApplicationPackageManager對象經過封裝,

ApplicationPackageManager(ContextImpl context,
IPackageManager pm) {
mContext = context;
mPM = pm;
}
其installPackage方法為
@Override
public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName) {
try {
mPM.installPackage(packageURI, observer, flags, installerPackageName);
} catch (RemoteException e) {
// Should never happen!
}
}

可見調用的installPackage方法為 IPackageManager.installPackage(packageURI, observer, flags, installerPackageName);
在ContextImpl中,由IPackageManager pm = ActivityThread.getPackageManager()獲得IPackageManager實例對象;在ActivityThread.getPackageManager()方法中,
static IPackageManager sPackageManager;
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}

最終得到的installPackage確實是IPackageManager.installPackage方法;

因為class PackageManagerService extends IPackageManager.Stub所以IPackageManager.installPackage調用的是:PackageManagerService.java (frameworks/base/services/java/com/android/server)文件中的
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
installPackage(packageURI, observer, flags, null);
}
(這裡不明白為何IPackageManager.installPackage方法調用的是PackageManagerService.java,只是在網上的一篇文章中它給出了上面的原因,因為class PackageManagerService extends IPackageManager.Stub,我不明白,但也找不到其他的函數,通過PackageManagerService.java的源碼,可以看出它確實是進行應用程序安裝的,所以應該可以確定最終調用的方法就是

PackageManagerService.installPackage(final Uri packageURI, final IPackageInstallObserver observer, final int flags))

於是考慮如何得到PackageManagerService.installPackage(),考慮通過反射的方法得到installPackage(),但其中難以得到的是其參數中的IPackageInstallObserver類型,IPackageInstallObserver是由aidl文件定義的,通過aidl文件的特性,將IPackageInstallObserver.aidl文件拷到本地程序中,可以得到類IPackageInstallObserver.calss,通過它反射出installPackage()方法,但在invoke該方法時,卻無法得到IPackageInstallObserver的實例對象,IPackageInstallObserver的實例對象必須通過

IPackageInstallObserver.Stub.asInterface(IBinder binder)方式得到,無法得到與其綁定的IBinder對象,因而無法執行反射出來的方法;另外PackageManagerService.installPackage()似乎是不能被第三方應用程序執行的,有權限的限制,這從下面的實例中似乎可以得到證實。

(3)在程序中執行Runtime.getRuntime().exec("pm install -r " + new File(Environment.getExternalStorageDirectory(),
"download/Shuffle-1.6.3.apk")); 進行安裝,這個命令的執行在 com.android.commands.pm.Pm中,直接調用IPackageManager.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags,installerPackageName)方法,在此方法中,
IPackageManager mPm;
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
且class PackageManagerService extends IPackageManager.Stub
所以IPackageManager.installPackage調用的是:PackageManagerService.java (frameworks/base/services/java/com/android/server)文件中的
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
installPackage(packageURI, observer, flags, null);
}

在此方法執行中會出現 Not granting permission android.permission.DELETE_PACKAGES錯誤,這應該是該權限不能授給第三方應用,因而在程序中不能執行,與android中普通安裝應用程序最終調用的方法是相同的,但是卻對第三方應用是沒有權限執行的。。

(4) 另外解決思路:

1> 使用android:sharedUserId="android.uid.system"屬性來使應用程序獲得系統權限,看看是否能夠執行行Runtime.getRuntime().exec("pm install -r ... ")方法。
2> 閱讀android實現應用程序安裝更底層的代碼,看看能否可以調用的底層方法進行安裝或者自己實現一個安裝程序的代碼,但這可能性不大,因為這涉及到android更底層的調用,

肯定會有一定的權限限制。
3> 在網上看到一個文件管理程序,據說是可以實現批量寂寞安裝應用程序,但說明運行時需要用戶確定得到手機的root權限,所以沒有太大意義。
4> 定制自己的android系統,可以解決。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved