Android 安裝應用的兩種方式--外部應用安裝器安裝和靜默安裝(系統應用)
阿新 • • 發佈:2018-12-27
1.呼叫外部安裝器安裝
/** * 外部應用安裝器安裝apk(原生介面) * @param context * @param path apk的路徑 * @return */ public static boolean installApkByPath(Context context, String path) { try { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } return false; }
2.靜默安裝(系統應用才有許可權)
這裡使用反射的方式呼叫
對應的原始碼的介面public class PackageManager_R { private static final String TAG = "PackageManager_R"; private static final String ERROR_TAG = "ReflectError " + TAG; private static Method sMethod_installPackage; /** * 靜默安裝(原生介面) * * @param path * @return */ public static boolean installPackage(String path, final SystemAppInstall.InstalledCallBack callBack) { if (sMethod_installPackage == null) { try { sMethod_installPackage = PackageManager.class.getMethod("installPackage", Uri.class, IPackageInstallObserver.class, int.class, String.class); } catch (Exception e) { LogUtils.w(ERROR_TAG, "", e); e.printStackTrace(); } } IPackageInstallObserver observer = new IPackageInstallObserver.Stub() { public void packageInstalled(String packageName, int returnCode) { if (returnCode != 1) { callBack.onResult(packageName, false); } else { callBack.onResult(packageName, true); } } }; PackageManager pm = AppContextUtils.getAppContext().getPackageManager(); try { sMethod_installPackage.invoke(pm, Uri.parse("file://" + path), observer, 0, null); return true; } catch (Exception e) { LogUtils.w(ERROR_TAG, "", e); e.printStackTrace(); } return false; } }
/** * @hide Install a package. Since this may take a little while, the result * will be posted back to the given observer. An installation will * fail if the calling context lacks the * {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if * the package named in the package file's manifest is already * installed, or if there's no space available on the device. * @param packageURI The location of the package file to install. This can * be a 'file:' or a 'content:' URI. * @param observer An observer callback to get notified when the package * installation is complete. * {@link IPackageInstallObserver#packageInstalled(String, int)} * will be called when that happens. This parameter must not be * null. * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK}, * {@link #INSTALL_REPLACE_EXISTING}, * {@link #INSTALL_ALLOW_TEST}. * @param installerPackageName Optional package name of the application that * is performing the installation. This identifies which market * the package came from. * @deprecated Use {@link #installPackage(Uri, PackageInstallObserver, int, * String)} instead. This method will continue to be supported * but the older observer interface will not get additional * failure details. */ // @SystemApi public abstract void installPackage( Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName);
3.監聽應用的安裝與解除安裝
//註冊監聽
IntentFilter installFilter = new IntentFilter();
installFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
installFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
installFilter.addDataScheme("package");
mContext.registerReceiver(mAppReceiver, installFilter);
//移除監聽
mContext.unregisterReceiver(mAppReceiver);
//廣播接收回調
private BroadcastReceiver mAppReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
LogUtils.d(TAG, "onReceive = " + action);
String pkgName = intent.getData().getSchemeSpecificPart();
if(action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
//解除安裝
}else if(action.equals(Intent.ACTION_PACKAGE_ADDED)) {
//安裝
}
}
};