Android 10 - 使用 PackageManager 代替 Intents 安装新版本的 apk 并没有真正起作用
Android 10 - Using PackageManager to install new version of apk instead of Intents doesn't really work
我的 apk 当前更新的方式是通过新的 apk 在旧的 apk 上安装自身(同时不覆盖本地数据库或设置)。
因此,由于 Android 10(API 29) ACTION_VIEW
已被弃用,因此这不再有效:
Intent intent = new Intent(Intent.ACTION_VIEW);
//output file is the apk downloaded earlier
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive");
startActivity(intent);
根据我在互联网上找到的不同答案,我需要开始使用 PackageInstaller。查看 Android 文档中的演示,我得到了这个:
Intent intent = new Intent(PSMentorActivity.this,InstallApkSessionApi.class);
intent.putExtra("apkFile",outputFile);
this.startActivity(intent);
其中 InstallApkSessionApi 包含一个按钮,按下该按钮将开始安装 window:
PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new
PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId);
addApkToInstallSession(file, session);
// Create an install status receiver.
Context context = InstallApkSessionApi.this;
Intent intent = new Intent(context, InstallApkSessionApi.class);
intent.setAction(PACKAGE_INSTALLED_ACTION);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();
// Commit the session (this will start the installation workflow).
session.commit(statusReceiver);
很简单,尽管比过去更复杂。我在 onNewIntent 中得到的响应总是:
case PackageInstaller.STATUS_FAILURE:
Toast.makeText(this, "Install failed!10 " + status + ", " + message,
Toast.LENGTH_SHORT).show();
break;
其中状态和消息采用以下值:status=1, message= "INSTALL_FAILED_INTERNAL_ERROR: Permission denied"
。
所以我认为这是权限问题。我已经拥有读取和写入存储的权限。其他相关权限是:INSTALL_PACKAGES
和 REQUEST_INSTALL_PACKAGES
我无法使用,因为第一个不是供第三方使用,而后者是签名级别。
有没有我非常想念的东西,或者没有办法让我在不通过 google 播放的情况下更新我的 Apk?
我遇到了同样的问题,并尝试了与您相同的方法 (PackageInstaller)。它不起作用。
所以,这里有一个解决方案,
if(android.os.Build.VERSION.SDK_INT >= 29){
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(Uri.fromFile(outputFile));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}else{
Intent intent = new Intent(Intent.ACTION_VIEW);
//output file is the apk downloaded earlier
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-
archive");
startActivity(intent);
}
我已经在 Android 10(Google Pixel 2、One+7、Samsung s10)中进行了测试,它工作正常。如果您仍然遇到任何问题,请告诉我。
注意: 您的版本号必须大于旧版本号。
因此,在获得帮助并在强大的互联网上进行更多搜索后,我已经能够使这两种方法都对我有用。我仍然不太明白是什么导致了这个问题。以前,我直接使用 Uri.fromFile(file)
从文件创建意图中使用的 Uri。这适用于 Android 10 以下的任何内容。我处理此问题的新方法是使用提供程序并使用它获取文件。
- 当前方法,在我可以正确安装 PackageManager 之前使用一段时间(还有一些问题需要解决)。
Uri urlapk = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID+".fileProvider",outputFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(urlapk, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
- 按照我的问题中指定的方式使用 PackageManager,但有以下区别(inputStream 现在是从 Uri 构建的):
private void addApkToInstallSession(Uri uri, PackageInstaller.Session session)
throws IOException {
try (OutputStream packageInSession = session.openWrite("package", 0, -1);
InputStream is = getContentResolver().openInputStream(uri)) {
byte[] buffer = new byte[16384];
int n;
while ((n = is.read(buffer)) >= 0) {
packageInSession.write(buffer, 0, n);
}
}
}
我对 PackageManager 的主要问题是它在安装时关闭了我的应用程序,没有向用户提供默认反馈。所以我想我将不得不 "make" 该反馈。我将继续使用 PackageManager,因为 ACTION_VIEW 已弃用 apks。
我的 apk 当前更新的方式是通过新的 apk 在旧的 apk 上安装自身(同时不覆盖本地数据库或设置)。
因此,由于 Android 10(API 29) ACTION_VIEW
已被弃用,因此这不再有效:
Intent intent = new Intent(Intent.ACTION_VIEW);
//output file is the apk downloaded earlier
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive");
startActivity(intent);
根据我在互联网上找到的不同答案,我需要开始使用 PackageInstaller。查看 Android 文档中的演示,我得到了这个:
Intent intent = new Intent(PSMentorActivity.this,InstallApkSessionApi.class);
intent.putExtra("apkFile",outputFile);
this.startActivity(intent);
其中 InstallApkSessionApi 包含一个按钮,按下该按钮将开始安装 window:
PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new
PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId);
addApkToInstallSession(file, session);
// Create an install status receiver.
Context context = InstallApkSessionApi.this;
Intent intent = new Intent(context, InstallApkSessionApi.class);
intent.setAction(PACKAGE_INSTALLED_ACTION);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();
// Commit the session (this will start the installation workflow).
session.commit(statusReceiver);
很简单,尽管比过去更复杂。我在 onNewIntent 中得到的响应总是:
case PackageInstaller.STATUS_FAILURE:
Toast.makeText(this, "Install failed!10 " + status + ", " + message,
Toast.LENGTH_SHORT).show();
break;
其中状态和消息采用以下值:status=1, message= "INSTALL_FAILED_INTERNAL_ERROR: Permission denied"
。
所以我认为这是权限问题。我已经拥有读取和写入存储的权限。其他相关权限是:INSTALL_PACKAGES
和 REQUEST_INSTALL_PACKAGES
我无法使用,因为第一个不是供第三方使用,而后者是签名级别。
有没有我非常想念的东西,或者没有办法让我在不通过 google 播放的情况下更新我的 Apk?
我遇到了同样的问题,并尝试了与您相同的方法 (PackageInstaller)。它不起作用。 所以,这里有一个解决方案,
if(android.os.Build.VERSION.SDK_INT >= 29){
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(Uri.fromFile(outputFile));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}else{
Intent intent = new Intent(Intent.ACTION_VIEW);
//output file is the apk downloaded earlier
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-
archive");
startActivity(intent);
}
我已经在 Android 10(Google Pixel 2、One+7、Samsung s10)中进行了测试,它工作正常。如果您仍然遇到任何问题,请告诉我。 注意: 您的版本号必须大于旧版本号。
因此,在获得帮助并在强大的互联网上进行更多搜索后,我已经能够使这两种方法都对我有用。我仍然不太明白是什么导致了这个问题。以前,我直接使用 Uri.fromFile(file)
从文件创建意图中使用的 Uri。这适用于 Android 10 以下的任何内容。我处理此问题的新方法是使用提供程序并使用它获取文件。
- 当前方法,在我可以正确安装 PackageManager 之前使用一段时间(还有一些问题需要解决)。
Uri urlapk = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID+".fileProvider",outputFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(urlapk, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
- 按照我的问题中指定的方式使用 PackageManager,但有以下区别(inputStream 现在是从 Uri 构建的):
private void addApkToInstallSession(Uri uri, PackageInstaller.Session session)
throws IOException {
try (OutputStream packageInSession = session.openWrite("package", 0, -1);
InputStream is = getContentResolver().openInputStream(uri)) {
byte[] buffer = new byte[16384];
int n;
while ((n = is.read(buffer)) >= 0) {
packageInSession.write(buffer, 0, n);
}
}
}
我对 PackageManager 的主要问题是它在安装时关闭了我的应用程序,没有向用户提供默认反馈。所以我想我将不得不 "make" 该反馈。我将继续使用 PackageManager,因为 ACTION_VIEW 已弃用 apks。