[英]How to prevent pendingintent from recreating an activity if launchmode set to 'singleTop'?
我在使用 Packagemanager 安装应用程序更新时遇到了一些麻烦。 我的应用程序是为我公司内部使用而设计的,因此我们不能使用 Google Play 来处理这些更新。 因此,在启动应用程序后,它会快速检查版本并下载更新(如果有)。
这是我在我的活动中尝试的(该文件是同一应用程序的下载和更新版本)
public void installNewApkVersion(File file){
PackageInstaller.Session session = null;
try{
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(session, file);
// Create an install status receiver.
Context context = LoginActivity.this;
Intent intent = new Intent(context, LoginActivity.class);
intent.setAction(ACTION_INSTALL_COMPLETE);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();
// Commit the session (this will start the installation workflow).
session.commit(statusReceiver);
} catch(IOException e){
throw new RuntimeException("Couldn't install package", e);
} catch (RuntimeException e){
if(session != null){
session.abandon();
}
throw e;
}
}
为此,我必须像这样覆盖 onNewIntent:
@Override
protected void onNewIntent(Intent intent) {
Bundle extras = intent.getExtras();
boolean isloggedin = pref.getBoolean("Loggedin", false);
if (ACTION_INSTALL_COMPLETE.equals(intent.getAction())) {
int status = extras.getInt(PackageInstaller.EXTRA_STATUS);
String message = extras.getString(PackageInstaller.EXTRA_STATUS_MESSAGE);
switch (status) {
case PackageInstaller.STATUS_PENDING_USER_ACTION:
// This test app isn't privileged, so the user has to confirm the install.
Intent confirmIntent = (Intent) extras.get(Intent.EXTRA_INTENT);
startActivity(confirmIntent);
break;
case PackageInstaller.STATUS_SUCCESS:
Log.w(TAG, "Install finished successfully");
break;
case PackageInstaller.STATUS_FAILURE:
Toast.makeText(this, "Install failed!", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Installation failed - status failure.");
break;
case PackageInstaller.STATUS_FAILURE_ABORTED:
Toast.makeText(this, "Install failure aborted!", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Installation failed. Aborted.");
break;
case PackageInstaller.STATUS_FAILURE_BLOCKED:
Toast.makeText(this, "Install: failure blocked!", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Installation failed. Blocked.");
break;
case PackageInstaller.STATUS_FAILURE_CONFLICT:
Toast.makeText(this, "Install: failure conflicted!", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Installation failed. Found conflicts.");
break;
case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE:
Toast.makeText(this, "Install: incompatible!", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Installation failed. Incompatible.");
break;
case PackageInstaller.STATUS_FAILURE_INVALID:
Toast.makeText(this, "Install: invalid!", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Installation failed. Invalid.");
break;
case PackageInstaller.STATUS_FAILURE_STORAGE:
Toast.makeText(this, "Install failed: storage error! " + status + ", " + message,
Toast.LENGTH_SHORT).show();
Log.w(TAG, "Install failed. Storage error.");
break;
default:
Toast.makeText(this, "Unrecognized status received from installer: " + status,
Toast.LENGTH_SHORT).show();
Log.w(TAG, "Dont know what happened");
}
}
}
此 Activity 在 singleTop 模式下运行,以便接收安装结果。 除非用户在提示时取消它,否则它运行良好。
因为如果是这样,则重新创建活动,而不是将结果传递回@onNewIntent 中的原始结果,从而在后台堆栈中产生相同活动的两个实例。
我怀疑这个问题发生在 android 7 上,当测试 android 10 时,而不是重新创建任务路由到 @onNewIntent (STATUS_FAILURE_ABORTED) 的活动,因为它应该是。
如果用户中止安装,我该如何捕捉?
这样做的真正目的是防止用户使用我的应用程序,如果他们有旧版本。
或者有没有办法以某种方式防止这种重复活动?
在 Android 7 上创建Activity
的新实例时,如果Intent
包含 package 安装程序状态,您可以在onCreate()
中执行此操作:
Intent x = getIntent(); // This contains the package installer status
x.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
startActivity(x);
finish();
这将完成Activity
的新实例并恢复Activity
的前一个实例并将Intent
传递给前一个Activity
的onNewIntent()
。
注意:标志FLAG_ACTIVITY_PREVIOUS_IS_TOP
告诉 Android 在决定如何处理startActivity()
调用时,它应该忽略当前最顶层的Activity
。 当您设置此标志时,您是在告诉 Android:“此Activity
即将结束,因此在决定是否需要创建新实例或使用现有实例时不要考虑它”
这是一个黑客,但应该工作:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.