AOSP - 在没有用户确认的情况下在后台安装包
AOSP - install packages in background without user confirmation
我正在为 Android 8.1 版构建 AOSP,我想实现自己的应用商店,因此需要在系统上安装 apks。
到目前为止,我看到的唯一方法是使用如下内容:
val intent = Intent(Intent.ACTION_VIEW)
val file = File(Environment.getExternalStorageDirectory().toString() + "/APKs/" + "spotify.apk")
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
但是,这需要用户在安装每个包之前进行确认。如果该应用程序是图像中内置的系统应用程序,是否有任何其他方法可以在没有用户确认的情况下实现此目的?另外,安装在后台有效地做什么?只是将 APK 文件移动到 /data/app
或者到底发生了什么?
看看runInstall()
方法
所需权限:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
我是这样解决的:
先决条件:
如前所述,您的 APK 需要由系统签名。实现这一目标的一种方法是自己构建 AOSP 映像并将源代码添加到构建中。
代码:
作为系统应用程序安装后,您可以使用程序包管理器方法安装和卸载 APK,如下所示:
安装:
public boolean install(final String apkPath, final Context context) {
Log.d(TAG, "Installing apk at " + apkPath);
try {
final Uri apkUri = Uri.fromFile(new File(apkPath));
final String installerPackageName = "MyInstaller";
context.getPackageManager().installPackage(apkUri, installObserver, PackageManager.INSTALL_REPLACE_EXISTING, installerPackageName);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
卸载:
public boolean uninstall(final String packageName, final Context context) {
Log.d(TAG, "Uninstalling package " + packageName);
try {
context.getPackageManager().deletePackage(packageName, deleteObserver, PackageManager.DELETE_ALL_USERS);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
要在您的 APK 为 installed/uninstalled 后进行回调,您可以使用此方法:
/**
* Callback after a package was installed be it success or failure.
*/
private class InstallObserver implements IPackageInstallObserver {
@Override
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
if (packageName != null) {
Log.d(TAG, "Successfully installed package " + packageName);
callback.onAppInstalled(true, packageName);
} else {
Log.e(TAG, "Failed to install package.");
callback.onAppInstalled(false, null);
}
}
@Override
public IBinder asBinder() {
return null;
}
}
/**
* Callback after a package was deleted be it success or failure.
*/
private class DeleteObserver implements IPackageDeleteObserver {
@Override
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
if (packageName != null) {
Log.d(TAG, "Successfully uninstalled package " + packageName);
callback.onAppUninstalled(true, packageName);
} else {
Log.e(TAG, "Failed to uninstall package.");
callback.onAppUninstalled(false, null);
}
}
@Override
public IBinder asBinder() {
return null;
}
}
/**
* Callback to give the flow back to the calling class.
*/
public interface InstallerCallback {
void onAppInstalled(final boolean success, final String packageName);
void onAppUninstalled(final boolean success, final String packageName);
}
我正在为 Android 8.1 版构建 AOSP,我想实现自己的应用商店,因此需要在系统上安装 apks。
到目前为止,我看到的唯一方法是使用如下内容:
val intent = Intent(Intent.ACTION_VIEW)
val file = File(Environment.getExternalStorageDirectory().toString() + "/APKs/" + "spotify.apk")
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
但是,这需要用户在安装每个包之前进行确认。如果该应用程序是图像中内置的系统应用程序,是否有任何其他方法可以在没有用户确认的情况下实现此目的?另外,安装在后台有效地做什么?只是将 APK 文件移动到 /data/app
或者到底发生了什么?
看看runInstall()
方法
所需权限:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
我是这样解决的:
先决条件:
如前所述,您的 APK 需要由系统签名。实现这一目标的一种方法是自己构建 AOSP 映像并将源代码添加到构建中。
代码:
作为系统应用程序安装后,您可以使用程序包管理器方法安装和卸载 APK,如下所示:
安装:
public boolean install(final String apkPath, final Context context) {
Log.d(TAG, "Installing apk at " + apkPath);
try {
final Uri apkUri = Uri.fromFile(new File(apkPath));
final String installerPackageName = "MyInstaller";
context.getPackageManager().installPackage(apkUri, installObserver, PackageManager.INSTALL_REPLACE_EXISTING, installerPackageName);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
卸载:
public boolean uninstall(final String packageName, final Context context) {
Log.d(TAG, "Uninstalling package " + packageName);
try {
context.getPackageManager().deletePackage(packageName, deleteObserver, PackageManager.DELETE_ALL_USERS);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
要在您的 APK 为 installed/uninstalled 后进行回调,您可以使用此方法:
/**
* Callback after a package was installed be it success or failure.
*/
private class InstallObserver implements IPackageInstallObserver {
@Override
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
if (packageName != null) {
Log.d(TAG, "Successfully installed package " + packageName);
callback.onAppInstalled(true, packageName);
} else {
Log.e(TAG, "Failed to install package.");
callback.onAppInstalled(false, null);
}
}
@Override
public IBinder asBinder() {
return null;
}
}
/**
* Callback after a package was deleted be it success or failure.
*/
private class DeleteObserver implements IPackageDeleteObserver {
@Override
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
if (packageName != null) {
Log.d(TAG, "Successfully uninstalled package " + packageName);
callback.onAppUninstalled(true, packageName);
} else {
Log.e(TAG, "Failed to uninstall package.");
callback.onAppUninstalled(false, null);
}
}
@Override
public IBinder asBinder() {
return null;
}
}
/**
* Callback to give the flow back to the calling class.
*/
public interface InstallerCallback {
void onAppInstalled(final boolean success, final String packageName);
void onAppUninstalled(final boolean success, final String packageName);
}