Many PendingIntents, BroadcastReceiver and activity - android

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 :)

Related

Android - Not able to start multiple activities from background

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"

Share datas at the end of a Service

I would like to have your opinion.
I have got an Activity A with a button (and a listener of course). It starts a Service and a Notification.
I would like that when I click on the notification, it runs a new Activity B and it stops the Service.
My problem is : how use an Indent to send the datas from the Service to the Activity B when the Service is stop? (I need the very last values of datas in my Service)
Thanks in advance for yours answers.
Intent has a couple of methods called putExtra(String name, ...) which allow you to put a number of EXTRAS on the intent. You don't specify a whole lot of detail in your question. This is the most generic answer I can give you.
Before calling stopSelf() on the service you should start the Activity B with the intent (say I). Immediately after calling startActivity(B, I), you should call stopSelf on service.
While creating I, you can put data into the intent as EXTRAs.

start a another version of an existing broadcastreceiver

I have a fragment with a button that starts a BroadcastReceiver. This BroadcastReciever creates a notification after a time retrieved from the fragment. This part works.
However, when I press the button more than once, the existing broadcast receiver is overwritten. I don't want this as I want multiple notifications to be created.
Any solutions?
Thank you
I found the answer - The pending intent used in the alarm manager was not unique so it was overwritten each time I created another alarm. What I needed to do was create multiple alarms. This is done by adding a unique id to the 2nd parameter (argument?) of the pending intent.
See this answer for more details: https://stackoverflow.com/a/10090378/2442638

Start Activity for result in a Broadcast Receiver?

I have managed to get an Activity to start from my onReceive() methdod, but I really need to do a startActivityForResult();.
Is there any way I could do this?
On a side note, how would I make my app become a 'camera' app, as in it would appear when an app started the intent to take a picture?
The important thing to know about broadcast receivers is that you should not add long running processes in it, because after something like 5 seconds your app will crash.
The best thing to do in your case is to intent to other Activity from your broadcast receiver, and from that activity use startActivityForResult(), get the picture and continue from there...
startActivityForResult can only be called from an Activity since it is defined in the Activity class and require instance of activity.
You can only call startAcivity() from broadcast receiver since in onRecieve() you only have access to generic context object and it does not have startActivityForResult method defined in the class..

Correct way of handling (pending) intents in AppWidgets

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.

Categories

Resources