Goal Tracking

My Android application receives a call for the intention of transmitting the information (pendingintent in the status bar).

When I press the home button and reopen the application while holding the home button, it again calls the intention, and the same additional functions still exist.

@Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } 

this is code that is not supposed to work

  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 } } 

And my intention:

 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); } 

Is there a way to clear an intent or check if it has been used before?

+91
android android-intent
Nov 07 '10 at 1:36
source share
20 answers

UPDATE:

I did not understand that this answer would be mentioned so when I first wrote it more than 5 years ago!

I will explain that according to @ tato-rodrigo's answer, this will not help you detect an already processed intention in some situations.

I must also point out that I put “clearly” in quotation marks for some reason - you are not really clearing the intention, by doing this, you are simply using the deletion as a flag that the intention has already been shown in activity.




I had exactly the same problem.

Above answer put me on the correct track, and I found an even simpler solution using:

 getIntent().removeExtra("key"); 

Calling the "clear" intent method.

Its a bit late to answer, as it was asked a year ago, but hopefully this will help others in the future.

+154
Nov 11
source share

EDIT: I am editing to post the complete solution that I am using.

This solution will work if the problem is: "Do not execute any code when the action begins with" History (recent applications). "

First of all, declare boolean in Activity to indicate whether Intent has already been used:

  private boolean consumedIntent; 

Then safely store and restore this value using the onSaveInstanceState and onCreate to handle configuration changes and when the system can kill your Activity when it goes into the background.

  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 } 

Now check if you can run your code under 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 } } 

Also, if your Activity set to singleTop , you must reset your flag when a new Intent is delivered.

  @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); consumedIntent = false; } 
+37
Aug 27 '14 at 19:57
source share

Max is responsible for cleaning:

  getIntent().removeExtra("key"); 

Another useful command:

  getIntent().setAction(""); 

You can also mark an intent by calling:

  getIntent().putExtra("used", true); 

and then just check the value.

+19
Feb 11
source share

When we launch Android applications from the history (recent applications), the application can be launched using basically three different Intent flags.

  • FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
    This is when the activity is launched from the history of the application, which was minimized (long press the home key).
    Constant value: 1048576 (0x00100000)
  • FLAG_ACTIVITY_NEW_TASK
    This is when the activity is triggered through the "click on the application icon" or through the " Intent filters ". Here the action will be the beginning of a new challenge in this story stack.
    Constant Value: 268435456 (0x10000000)
  • FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
    This is when the application was closed by clicking the "Back" button, and then resuming it from the "History" (recent applications).
    Constant value: 269484032 (0x10100000)

A constant value can be obtained using getIntent().getFlags()

In the third case, Android reloads the latest Intent from its memory. This way your application ( getIntent ) will have values ​​from the last intention that the application started.

In fact, the application should behave as if it is a new launch, with the goal of creating values ​​for the new launch, and not the intent values ​​of the previous launch. This behavior can be seen if you launch the application by clicking the application icon, it will never have the old intent values. This is because Android uses the following intent filter for this scenario.

  <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> 

But in the third case (the application that was closed is launched from the history of recent applications), Android OS uses the last intention, which launched the application before its release (using the "Back" button). This way you get the old intent values, and the application flow is not correct.

Removing an intent is one way to solve it, but it will not solve the problem completely! Because the Android OS restarts the Intent from the last application launch, not the last instance of the launch intent.

The pure way to avoid this is to process it by getting an Intent type to determine the type of startup.

So, in your LaunchActivity (one that has an intent filter defined in the manifest), you can use the following code in the onCreate() , onStart() or 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(); } } 

I assume normalLaunch() should not use parameters from Intent; otherwise, you will need to separate and optimize the default startup method so that you do not use Intent parameters.

+12
Dec 29 '16 at 2:35
source share

Purpose object intent:

 intent.replaceExtras(new Bundle()); intent.setAction(""); intent.setData(null); intent.setFlags(0); 
+11
Apr 29 '15 at 15:14
source share

Short answer No way

Long answer. There is no such thing as a “one-time” intention. From the experiment it can be seen that the recent history of activity in modern androids is nothing but the "Intentional History". The last intention transferred to the action is simply registered in the system and that transaction. People offering to use

 setAction("") 

But this does not work, because the intention is already registered before it is received inside the onNewIntent () or onStart () method.

I solved the problem by avoiding using intentions. My problem was familiar with the one that was published by the author. I tried to implement Global Exit from the application through management in the notification area. He must stop the basic service and close all the actions of the application. You can find the same behavior in the Waze app.

Algorithm:

  • Create a PendingIntent to control the notification that passes the Exit action to the action. But to a special activity, which is a simple proxy.
  • The onStart () code proxy activity analyzes the intent, checks the action and sets the state of any model to "Exit".
  • Proxy activity: the onStart () code clears the original intent with setIntent (") and then redirects it to the destination" Root ", calling startActivity (intent).
  • Proxy activity onStart () calls invoke finish ().
  • Inside onStart () and onNewIntent () the status of checking the status of the target and ending the call () if it is "Exit" (as well as the call to stopService () in my case).

Hope this helps someone because I did not find the answer on the Internet.

+7
Jan 25 '14 at 17:41
source share

Verify that PendingIntent.FLAG_UPDATE_CURRENT is used for PendingIntent ..

 PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, mPutIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

Where mPutIntent is your Intent .

Hope this helps you.

+4
Dec 31 '15 at 13:19
source share

I have exactly the same problem. My solution was to add the boolean variable that was set when the Intent was “used” and if based on that boolean to check if Intent should be used or not.

+1
09 Feb '11 at 18:55
source share

When you are finished processing the intent, do the following:

 setIntent(null); 

You will not see this processed Intent again, and you will not mask the problem by editing the contents of the processed Intent.

+1
Aug 10 '16 at 5:03
source share

I recently had this problem and solved it by adding a timestamp as an extra parameter for the intent:

 private void launchActivity(Context context) { Intent intent = new Intent(context, MainActivity.class); intent.putExtra("KEY_EXTRA_TIMESTAMP", System.currentTimeMillis()); context.startActivity(intent); } 

After that, save the timestamp for general settings:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); long time = getIntent().getLongExtra("KEY_EXTRA_TIMESTAMP", -1); long previousTime = getPreferences(MODE_PRIVATE).getLong("timestamp", -1); //ignore if the timestamp is the same as the previous one if (time != previousTime) { handleIntent(getIntent()); if (time != -1) { //save the timestamp getPreferences(MODE_PRIVATE).edit().putLong("timestamp", time).apply(); } } } 
+1
Sep 23 '16 at 9:46
source share

I could not find a way to remove Intent Extra . None of the answers about removing additional intentions work if you enable "Do not perform actions" from the developer’s settings (this way you can destroy Activity and return to the check if Extras still exists).

As a solution to the problem, I saved a logical value in SharedPreferences after processing Intent Extras. When the same Intent is re-added to the Activity, I check the SharedPreference value and decide to handle Intent Extra. In case you send another new Intent Extra to the same activity, you make the SharedPreference false, and the Activity will handle it. An example :

 // Start Activity with Intent Extras Intent intent = new Intent(context, MyActivity.class); intent.putExtra("someData", "my Data"); // Set data as not processed context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).edit().putBoolean("myActivityExtraProccessed", false).commit(); context.startActivity(intent); ... public class MyActivity{ ... public void someMethod(){ boolean isExtrasProcessed = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).getBoolean("myActivityExtraProccessed", false); if (!isExtrasProcessed) { // Use Extras //Set data as processed context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).edit().putBoolean("myActivityExtraProccessed", true).commit(); } } } 
+1
Jul 28 '17 at 8:04 on
source share

This method worked with me:

  Intent intent = getIntent(); intent.replaceExtras(new Bundle()); intent.setAction(""); intent.setData(null); intent.setFlags(0); 
0
Aug 01 '16 at 19:21
source share

Even after manually clearing the Intent and Intent settings after analyzing them, it seems that Activity.getIntent () always returns the original intent that launched the Activity.

To get around this, I recommend something like this:

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // The Intent provided by getIntent() (and its extras) will persist through a restore // via savedInstance. Because of this, restoring this activity from a // an instance that was originally started with extras (deep-link or // pre-defined destination) may cause un-desired behavior // (ie...infinite loop of sending the user directly to somewhere else because of a // pre-defined alternate destination in the Intent extras). // // To get around this, if restoring from savedInstanceState, we explicitly // set a new Intent *** to override the original Intent that started the activity.*** // Note...it is still possible to re-use the original Intent values...simply // set them in the savedInstanceState Bundle in onSavedInstanceState. if (savedInstanceState != null) { // Place savedInstanceState Bundle as the Intent "extras" setIntent(new Intent().putExtras(savedInstanceState)); } processIntent(getIntent()) } private void processIntent(Intent intent) { if (getIntent().getExtras() == null) { // Protection condition return; } doSomething(intent.getExtras.getString("SOMETHING_I_REALLY_NEED_TO_PERSIST")); final String somethingIDontWantToPersist = intent.getExtras.getString("SOMETHING_I_DONT_WANT_TO_PERSIST"); if(somethingIDontWantToPersist != null) { doSomething(somethingIDontWantToPersist); } } @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save selective extras from original Intent... savedInstanceState.putString("SOMETHING_I_REALLY_NEED_TO_PERSIST", "persistedValued"); super.onSaveInstanceState(savedInstanceState); } 

Thus, there is a mechanism for resetting the original intention, while maintaining the ability to explicitly save certain parts of the original Intent / Intent options.

Please note that I have not tested all Activity launch modes.

0
Feb 26 '17 at 0:54
source share

The direct way is to avoid calling getIntent () from methods other than onCreate (). But this will cause a problem during the next launch if the user leaves our activity by clicking the "Home" button. I think this problem does not have a fully functional solution.

0
Sep 15 '17 at 20:10
source share

I am facing the same problem and trying to use the above methods, but it does not work.

I think this may be the reason for starting the activity mode that I used in SingleTop mode.

When I create a background application and use RamEater to simulate a problem, the intent always has additional intentions, even if I set it to zero or deleted the key.

The issue was resolved by using preferred Android storage to verify what went through.

0
Mar 06 '18 at 9:41
source share

How about this? Sets newIntent as an intent.

 @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); } 
-one
Jan 07 '14 at 19:13
source share

How about when you want to clear an intent - replace it with an empty one?

eg.

 @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); } @Override public void onResume() { super.onResume(); Intent theIntent = getIntent(); if ("myaction".equals(theIntent.getAction()) { handleIntent(); onNewIntent(new Intent()); // <--- "clear" the intent by setting empty one } } 
-one
Nov 05 '14 at 12:42 on
source share

This will hopefully help everyone. So first we get the intention

 //globally Intent myIntent; 

Put it somewhere on the Create link

 myIntent = getIntent(); String data = myIntent.getStringExtra("yourdata"); //Your process here 

Now let's set this so that every time our application is destroyed or exits, we will delete the data

 @Override protected void onDestroy() { //TODO: Clear intents super.onDestroy(); myIntent.removeExtra("data"); } @Override protected void onBackPressed() { //TODO: Clear intents super.onBackPressed(); myIntent.removeExtra("data"); } 

You get the idea if this is not enough, just find more 'on' callbacks

-one
May 28 '17 at 11:31 a.m.
source share

While Intent.removeExtra("key") will remove one special key from additional functions, there is also an Intent.replaceExtras (Bundle) method, which can be used to remove all additional objects from Intent if null is passed as a parameter.

From the docs:

Completely replace additional features in the intent with this set of extras.

Options
Advanced Options A new set of advanced features in Intent, or null to remove all advanced features.

Since putXXX () methods initialize additional components with a new Bundle light, if its value is null, this is not a problem.

-2
May 24 '14 at 7:13
source share
 Intent intent = new Intent(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addCategory(Intent.CATEGORY_HOME); startActivity(intent); 
-3
Jul 30 '12 at 12:24
source share



All Articles