Mar*_*ars 98 android android-intent
我的Android应用程序被传递信息的意图调用(状态栏中的pendingintent).
当我按下主页按钮并通过按住主页按钮重新打开我的应用程序时,它再次调用了意图,并且仍然存在相同的附加功能.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Run Code Online (Sandbox Code Playgroud)
这是不像它应该运行的代码
String imgUrl;
Bundle extras = this.getIntent().getExtras();
if(extras != null){
imgUrl = extras.getString("imgUrl");
if( !imgUrl.equals(textView01.getText().toString()) ){
imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
layout1.setVisibility(0);
textView01.setText(imgUrl);//textview to hold the url
}
}
Run Code Online (Sandbox Code Playgroud)
我的意图是:
public void showNotification(String ticker, String title, String message,
String imgUrl){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(ns);
int icon = R.drawable.icon; // icon from resources
long when = System.currentTimeMillis(); // notification time
CharSequence tickerText = ticker; // ticker-text
//make intent
Intent notificationIntent = new Intent(this, activity.class);
notificationIntent.putExtra("imgUrl", imgUrl);
notificationIntent.setFlags(
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
//make notification
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, message, contentIntent);
//flags
notification.flags = Notification.FLAG_SHOW_LIGHTS |
Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_ONLY_ALERT_ONCE |
Notification.FLAG_AUTO_CANCEL;
//sounds
notification.defaults |= Notification.DEFAULT_SOUND;
//notify
mNotificationManager.notify(1, notification);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法清除意图或检查它是否曾被使用过?
Mak*_*aks 158
当我5年前第一次写这篇文章时,我没有意识到这个答案会被提到这么多!
我要澄清一点,根据@ tato-rodrigo的回答,这不会帮助你在某些情况下检测已经处理过的意图.
另外我应该指出我把"明确"放在引号中是有原因的 - 你并没有真正通过这样做清除意图,你只是使用额外的删除作为一个标志,这个意图已被活动看到.
我有完全相同的问题.
以上回答让我走上正轨,我发现更简单的解决方案,使用:
getIntent().removeExtra("key");
Run Code Online (Sandbox Code Playgroud)
方法调用"清除"意图.
自从一年前被问到这个问题以后,它的回答有点迟了,但希望这对未来的其他人有所帮助.
tat*_*igo 39
编辑:我正在编辑发布我正在使用的完整解决方案.
如果问题是"当活动从历史记录(最近的应用程序)启动时不执行某些代码",则此解决方案将起作用.
首先,boolean
在你的声明中Activity
指示是否Intent
已经消耗了:
private boolean consumedIntent;
Run Code Online (Sandbox Code Playgroud)
然后,使用onSaveInstanceState
和onCreate
方法安全地存储和恢复此值,以处理配置更改以及系统Activity
在进入后台时可能会将其杀死的情况.
private final String SAVED_INSTANCE_STATE_CONSUMED_INTENT = "SAVED_INSTANCE_STATE_CONSUMED_INTENT";
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT, consumedIntent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set content view ...
if( savedInstanceState != null ) {
consumedIntent = savedInstanceState.getBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT);
}
//other initializations
}
Run Code Online (Sandbox Code Playgroud)
现在,检查您是否可以在onResume
方法下运行代码.
@Override
protected void onResume() {
super.onResume();
//check if this intent should run your code
//for example, check the Intent action
boolean shouldThisIntentTriggerMyCode = [...];
Intent intent = getIntent();
boolean launchedFromHistory = intent != null ? (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 : false;
if( !launchedFromHistory && shouldThisIntentTriggerMyCode && !consumedIntent ) {
consumedIntent = true;
//execute the code that should be executed if the activity was not launched from history
}
}
Run Code Online (Sandbox Code Playgroud)
此外,如果您Activity
的配置为singleTop
,则应在Intent
交付新标志时重置标记.
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
consumedIntent = false;
}
Run Code Online (Sandbox Code Playgroud)
Sly*_*ynk 19
Maks的答案适用于清除额外的:
getIntent().removeExtra("key");
Run Code Online (Sandbox Code Playgroud)
另一个有用的命令是:
getIntent().setAction("");
Run Code Online (Sandbox Code Playgroud)
您还可以通过调用标记意图:
getIntent().putExtra("used", true);
Run Code Online (Sandbox Code Playgroud)
然后只需检查值.
B.B*_*.B. 17
当我们从历史(最近的应用程序)启动Android应用程序时,可以使用主要三种不同的Intent标志启动应用程序.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
可以通过检索常量值 getIntent().getFlags()
在第三种情况下,Android从其内存重新加载最后的Intent值.因此,您的应用的intent(getIntent
)将具有启动应用的最后一个意图的值.
实际上,应用应该表现得好像是一个新的发布,新的发布的意图值而不是上一次发布的意图值.如果通过单击应用程序图标启动应用程序,则可以看到此行为,它将永远不会具有旧的意图值.这是因为Android为此方案使用以下intent过滤器
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
Run Code Online (Sandbox Code Playgroud)
但在第三种情况下(已退出的应用程序,是从最近的应用程序的历史记录启动),Android OS使用在退出之前启动应用程序的最后一个意图(通过按下后退按钮).所以你最终得到旧的意图值并且应用流程不合适.
删除意图是解决问题的一种方法,但它不能完全解决问题!随着Android OS从上次启动的应用程序重新加载Intent,而不是启动意图的最后一个实例.
避免这种情况发生的一种干净方法是通过获取Intent类型来确定启动类型来处理它.
因此,在您LaunchActivity(这在清单中定义的意图过滤器中的一个),你可以在使用下面的代码onCreate()
,onStart()
或onResume()
方法.
if(getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) {
//app is launched from recent apps after it was closed
normalLaunch();
} else {
String intentAction = getIntent().getAction();
String scheme = getIntent().getScheme();
//app is launched via other means
// URL intent scheme, Intent action etc
if("https".equalsIgnoreCase(scheme)) {
// URL intent for browser
} else if("com.example.bb".equalsIgnoreCase(intentAction)) {
// App launched via package name
} else {
// App was launched via Click on App Icon, or other means
normalLaunch();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为normalLaunch()
,不应该使用Intent中的参数; 否则你需要隔离并优化你的默认启动方法,不要使用Intent参数.
Mic*_*Tin 12
intent.replaceExtras(new Bundle());
intent.setAction("");
intent.setData(null);
intent.setFlags(0);
Run Code Online (Sandbox Code Playgroud)
简短的回答是没有办法
答案很长.没有"一次性"的意图.从实验中可以看出,现代机器人最近的活动历史只不过是"意图历史".传递给活动的最新意图只是登录到系统,这就是交易.上面的人建议使用
setAction("")
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为意图已经记录,直到你在onNewIntent()或onStart()方法中获取它.
我通过避免使用意图来解决问题.我的问题与作者发布的问题相似.我尝试通过通知区域中的控件实现应用程序的全局退出.它应该停止底层服务并关闭应用程序的所有活动.您可以在Waze应用程序中找到相同的行为.
算法:
我希望这会对某人有所帮助,因为我没有在互联网上找到答案.
确保您为PendingIntent使用PendingIntent.FLAG_UPDATE_CURRENT标志。
PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, mPutIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)
哪里mPutIntent
是你的Intent
。
希望这会帮助你。
归档时间: |
|
查看次数: |
65720 次 |
最近记录: |