When my App crashes I create an Intent with a FLAG_CRASH.
I call PendingIntent.getActivity with that Intent, and hand the resulting PendingIntent over to AlarmManager.
After 1 Second it restarts my App. Yet on older API Levels (< 9) getFlags on the Intent always returns 0. API Level 15 returns my Flags. Any Idea why? Did some default behavior change happen between the Versions?
I ended up writing a broadcast receiver that I can fire an own distinct intent via pending intent. That broadcast receiver builds another intent for the activity and puts an extra into it for signaling the crash. In the Activty I have a handler method that I call from both onNewIntent and onCreate, the handler creates the error popup and resets the extra.
Related
I am facing a problem.
This is the code I have in my BroadcastReceiver extender class:
#Override
public void onReceive(Context context, Intent intent) {
// other
Intent myIntent = new Intent(context, ShowMessageActivity.class);
myIntent.putExtra(Utils.SHOW_MESSAGE_OPTION, messageToDisplay);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(lockScreenMessage);
}
which starts a new activity when a broadcast is raised.
When the application is in foreground and receives a broadcast, it starts a new Activity as many times as the code executes, but it is not the case when the app is in background. In that case it starts an Activity only once, and not each time a broadcast is received. Why? Is it possible to fix that?
that very depends on what do you expect in that receiver, is it any system-side call (declared in manifest) or your own? who an when calls it, thats very important
starting Android 10 there are some restrictions for starting Activity from onReceive, check out official DOC. basically you shouldn't start any Activity from there, and when it works for you I bet it works only for few secs after PendingIntent creation. check out exceptions list under link above, possible reasons would be:
The app has an activity in the back stack of an existing task on the Recents screen.
The app has an activity that was started very recently.
The app called finish() on an activity very recently.
you may check out your code on some emulator with Android 9, all your broadcast calls should work "always"
I have a Service that first creates a new Intent, and calls setAction('foo') on it. After this I call putExtra("key","value123"). Then I call PendingIntent.getService(this,999,intent,0) (no flags passed), and pass the pending intent to the AlarmManager.
But then before the alarm fires (or even after, it seems) I create another Intent and again call setAction('foo') on it, but don't set any extras.
Then I again pass it to PendingIntent.getService(this,999,intent,0). However, this time I call send() on the PendingIntent so as to receive the intent immediately.
What I observe is that the original extras are delivered with the new Intent. I appear to be able to do this over and over, and even if my app is killed, when I restart it, the extras are still there.
However, I don't see anything specifically in the documentation which says whether or not this is actually expected behavior. Is this a reliable method by which I can persist a small amount of data in RAM (only!) in case my app gets terminated? Currently I'm using file on a RAMdisk, but some devices apparently don't have such a thing.
This is the way PendingIntent works ;-)
The first call to PendingIntent.getService() creates a new PendingIntent with the requestCode set to 999 and the Intent set to ACTION="foo".
The second call to PendingIntent.getService) doesn't create a new PendingIntent. It just returns a token (reference) to the first PendingIntent. When you call send() on it, the original PendingIntent is sent.
The reason is that when you call PendingIntent.getService(), Android first tries to find a PendingIntent that matches the one you've specified. To determine if the Intent matches, it checks the ACTION, COMPONENT, DATA and it also checks for matching requestCode arguments. In your case, both calls to PendingIntent.getService() have the same requestCode and the Intents have the same ACTION. NOTE: "extras" in the Intent are not considered when determining if the Intents match.
If you always want to (re)use a single PendingIntent and just override the "extras" every time you use it, you can add the flag PendingIntent.FLAG_UPDATE_CURRENT to the call to PendingIntent.getService().
If you need to create several PendingIntents in parallel, with different "extras", you need to make sure to use a unique requestCode every time you call PendingIntent.getService().
I'm writing a simple reminder app. All reminders are stored in DB. I have a service that query DB and make a pendingIntents in AlarmManager with extras and different timestamps. Also I have a Broadcast Receiver to catch the Intents from AlarmManager. This Broadcast Receiver start a reminder Activity with options for reminder (dismiss, snooze, etc).
Now this scheme work, but not as good as I think it should. If I have a reminder activity in foreground, then new reminder activity starts upon it (current goes to background). I want to not override the current activity with new one and just notify the user, that there are some new reminders that will show after the current.
As I think, I've found a good solution for my task:
1) I've set in AndroidManifest that my reminder activity launchMode is "singleTop". More about launchMode is here http://developer.android.com/guide/topics/manifest/activity-element.html
In two word, if my Broadcast Receiver tries to start activity that already on foreground, it calls onNewIntent, not onCreate.
2) In my activity I've to override the onNewIntent method and store all incoming intents (from broadcast) in ArrayList .
3) Before finish() I've to remove current Intent from ArrayList and when it's size become zero I've actually finish() the activity.
One important addition. In broadcast receiver intent must have FLAG_ACTIVITY_SINGLE_TOP, like:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Without it if no main activity present onNewIntent will not be called. As I see, this is knows issue: http://code.google.com/p/android/issues/detail?id=4155
Bug found in Android 1.6 and still present. So now it is feature :)
Sorry for my English, it's easy for me to read, but hard to write :)
I have to do a task multiple times, and task is to broadcast an intent which will be intercepted by a different app. Lets say from App Sender to Receiver.
Receiving the intent in Receiver app is working fine, I have tested and guaranteed:
How I am doing this is,
I created a broadcast receiver in Sender app, with action SENDER_ACTION.
I create an intent with this action, set an extra with key frequency and value 4.
Get a PendingIntent from this and set an alarm of 10 sec, and fires this intent.
Idea is that sender app, will receive this intent, will fire the required intent to RECEIVER app, and then decreases the frequency value by 1, set it again to the intent, creates a pending intent and alarm and fires again.
So, ideally this counter of frequency should reach to 0 and process should terminate.
I can see that while setting the decreased value of frequency, it is happening (in logs), but when I receive its the same unchanged value.
I suspect that pending intent instance is kept on fired again and again.
Can some body please help me why is this happening?
If I had to guess -- which I do, since you provided no source code -- it is because you have not passed the right flags into getBroadcast() (or whatever factory method that you are using on PendingIntent to obtain the PendingIntent instance). Please bear in mind that Android caches PendingIntent objects and will reuse them, with their internal Intent extras unmodified, by default. Consider passing FLAG_UPDATE_CURRENT as the last parameter to getBroadcast().
I have a question regarding AppWidget intent handling. I have a widget which is clickable, and on click I want to send an intent to the AppWidgetProvider itself for further processing.
The problem: I receive the intents initially in onReceive(), but after a while (not sure what causes it), onReceive() is no longer called.
I have the following code, all in MyWidgetProvider extends AppWidgetProvider.
a) register for receiving broadcasts:
in onEnabled(...):
context.getApplicationContext().registerReceiver(this, new IntentFilter(MY_ACTION));
b) set intent to be fired on click:
in onUpdate(...)
Intent intent= new Intent(MY_ACTION);
PendingIntent pendingIntent= PendingIntent.getBroadcast(context, 0/*notusedanyway*/, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_root, pendingIntent);
c) react to event and do something:
in onReceive(...)
if (MY_ACTION.equals(intent.getAction())
doSomething();
When I deploy + add a widget, it works fine. However, after a while - not sure what exactly causes the problem, but a phone call, for example, seems to affect it - I no longer get any notifications in onReceive().
I am completely stumped why this is the case. Can someone point out to me the correct way of doing this?
Thanks!
Tom
You should use a BroadcastReceiver registered in your AndroidManifest.xml file. When you register it in onEnable it is tied to the process. Whenever Android kills your process (for example, when a phone call is received) then your receiver no longer exists and (as you observed) no longer works.