如何解决如果启动模式设置为“singleTop”,如何防止pendingintent 重新创建活动?
我在使用 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,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!","Installation failed. Aborted.");
break;
case PackageInstaller.STATUS_FAILURE_BLOCKED:
Toast.makeText(this,"Install: failure blocked!","Installation failed. Blocked.");
break;
case PackageInstaller.STATUS_FAILURE_CONFLICT:
Toast.makeText(this,"Install: failure conflicted!","Installation failed. Found conflicts.");
break;
case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE:
Toast.makeText(this,"Install: incompatible!","Installation failed. Incompatible.");
break;
case PackageInstaller.STATUS_FAILURE_INVALID:
Toast.makeText(this,"Install: invalid!","Installation failed. Invalid.");
break;
case PackageInstaller.STATUS_FAILURE_STORAGE:
Toast.makeText(this,"Install failed: storage error! " + status + "," + message,"Install failed. Storage error.");
break;
default:
Toast.makeText(this,"Unrecognized status received from installer: " + status,"Dont know what happened");
}
}
}
此活动以 singleTop 模式运行以接收安装结果。除非用户在提示时取消它,否则它运行良好。
因为如果是这样,活动将再次重新创建,而不是将结果传递回@onNewIntent 中的原始活动,从而在后台堆栈中产生相同活动的两个实例。
我怀疑这个问题发生在 android 7 上,当测试 android 10 时,而不是重新创建任务路由到 @onNewIntent (STATUS_FAILURE_ABORTED) 的活动,因为它应该是。
如果用户中止安装,我该如何捕捉?
这样做的真正目的是防止用户使用我的旧版本应用程序。
或者有没有办法以某种方式防止这种重复活动?
解决方法
在 Android 7 上创建 Activity
的新实例时,如果 Intent
包含软件包安装程序状态,您可以在 onCreate()
中执行此操作:
Intent x = getIntent(); // This contains the package installer status
x.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
startActivity(x);
finish();
这将完成 Activity
的新实例并恢复 Activity
的前一个实例并将 Intent
传递给前一个 {{1} 的 onNewIntent()
}.
注意:标志 Activity
告诉 Android 在决定如何处理 FLAG_ACTIVITY_PREVIOUS_IS_TOP
调用时应该忽略当前最顶层的 Activity
。当您设置此标志时,您是在告诉 Android:“此 startActivity()
将要完成,因此在决定是否需要创建新实例或使用现有实例时不要考虑它”
这是一个黑客,但应该工作:-)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。