Android - Not able to start multiple activities from background - android

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"

Related

Getting an activity to start as soon as Android app is in the foreground

I'm using a running service to detect whether network is available or not. When it is not available, it calls an activity to start that displays a blank screen with "no network available" on it. When the network is back, it sends a broadcast to finish this activity.
The only problem is that this activity may start at any time (as a popup), even when using other apps. I want it to start (or be visible) only if the network is out and my app is in the foreground. Any help?
One option would be to have your foreground activity register for the broadcast, and then display the relevant notification from within the activity.
Alternatively you could start your service when your foreground activity starts/resumes (i.e, onResume), and stop it when your activity leaves the foreground.
You can use START_STICKY in your service to ensure it stays around until you stop it, like so:
#Override
public int onStartCommand(Intent intent, int flags, int startId){
//On start work here
return START_STICKY;
}
and then stop the service using stopService when your activity leaves the foreground (i.e onPause).
If you need the former behaviour across multiple activities you can register broadcast receivers programmatically:
BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(MY_ACTION.equals(intent.getAction()))
{
//show appropriate dialog
}
}
};
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(MY_ACTION);
registerReceiver(myBroadcastReceiver,myIntentFilter);
You can unregister like so:
unregisterReceiver(myBroadcastReceiver);
You could extend Activity and make your own custom subclass that reuses similar code to register and unregister whilst entering/leaving the foreground. Or you can extract this into utility methods/classes and call from the appropriate places.
I think you need Shared Preference to do this. store one Boolean value on finish you activity (you can use onpause() or onStop()) and for showing popup check the value and do what you want
for understnding to use sharePreference see this and developer.android.com
Try the following:
Intent intent = new Intent(this, YourActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
This worked in the context of my own app already running, I'm not sure if it will start your app if it is not already running in the background
EDIT: Not sure if I understand your question entirely. If you only want this activity to come to the foreground while your app is in the foreground, get rid of the addFlags line, also you can do some boolean stuff to check if your app is in the foreground like so, this way your code won't even run if the app isn't in the foreground.
EDIT: There are a few ways to check if your app is in the foreground, the link I posted above has one such solution, another one is to create a static boolean isForeground variable: in the onResume() methods of your app set isForeground = true and in onPuase() set isForeground = false. This isn't the best practice, using ActivityManager is better, but for purposes of testing this should be ok.
Then have something like the following:
if(isForeground){
//Start your activity
}
This should be quick to write, if this is the behavior you want, I would recommend replacing the isForeground static variable with the test for foreground provided by ActivityManager in the link I posted.

Calling an Activity from a broadcastreceiver, but keep it in the background

I have an alarm set to trigger every n minutes, and it works fine.
However I discovered that reading the application's SharedPreferences from a broadcast receiver caused some problems (It read an older version of those preferences, probably due to a different PID)
I were told that to do what I needed to do, I should call an Activity, that solved the SharedPreferences problem, but created a new one.
The activity must run in the background exclusively. It is essentially a heartbeat, sending off some information to a Presence solution, keeping the users presence alive.
The Alarm Receiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent alarmIntent = new Intent(context, AlarmActivity.class);
alarmIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmIntent);
}
}
The activity in the manifest
<activity android:name=".AlarmActivity" android:theme="#android:style/Theme.Translucent.NoTitleBar"/>
The Alarm Activity only sends an HTTP update, but even if I remove all but the super.onCreate line, it still forces the application into the foreground, and focus. But it only happens if the application itself is only "minimized" via the home button. If I close it with the back button, it won't get forced into focus, while the heartbeat still fires just fine in the background.
How can I prevent this?
I'm developing for API version 7 (Android 2.1), but can update to API 8 if needed.
Consider using Service for performing background tasks.

Recommended method of starting a scheduled activity on start up?

Im trying to make an scheduled activity go off every hour or so, all working in the background.
Right now i have a BroadcastReceiver that picks up when the device is booted.
The BroadcastReceiver creates a PendingIntent to an activity (Called AlarmController) that creates has all necessary methods that i need for making the scheduled activity to go off.
How ever, this doesnt seem to work.
This is how my BroadcastReciever class onReceive{} looks like and is indentical to my main activity onCreate{}(Only for testing)
Intent intent = new Intent(serviceactivirt.this, AlarmController.class);
PendingIntent sender = PendingIntent.getActivity(serviceactivirt.this, 0, intent, 0);
try {
sender.send();
} catch (CanceledException e) {
Toast.makeText(getApplicationContext(), "FEJLSAN", Toast.LENGTH_LONG).show();
}
This actually works, except that my app crashes at launch, but the scheduled activity is working...
Any ideas? Is this "The way to do it" or is there a more recommended way?
Cheers!
Solution:
Instead of having a BroadcastReciever calling an Activity, i made the BroadcastReciever starting a Service. And changed my Activity to a Service, programmaticly and in manifest.
Works great!
Im trying to make an scheduled activity go off every hour or so, all working in the background.
Please allow users to configure other options, such as using a Notification, rather than being interrupted by an activity taking over the foreground.
Right now i have a BroadcastReceiver that picks up when the device is booted.
You would only need that to set up an AlarmManager schedule for your hourly events. Your PendingIntent for the AlarmManager could be one you obtain via getActivity().
How ever, this doesnt seem to work.
If you want to start an activity, call startActivity(). Do not create a PendingIntent, then immediately send() the PendingIntent.
Also, get rid of getApplicationContext() and simply use this.
except that my app crashes at launch
Use adb logcat, DDMS, or the DDMS perspective in Eclipse to examine LogCat and look at the stack trace associated with your crash.

What is the correct way for an Activity NOT in the foreground to launch another Activity in the same app?

An app I'm working on can receive asynchronous events in the background. The way I've architected the app, when the client receives such events, it sends a Message to a Handler that an Activity owns. The activities handles messages in various ways.
In one scenario, when a particular event arrives while the app is not in the foreground, I need to bring up an Activity and some UI to the user. Like how when a call arrives, the Answer or Decline UI comes to the foreground no matter what other app is currently active.
What's the best way to do this? I'm re-reading the documentation on Activities, Intents, and Tasks, but it's not always clear or easy to digest. I'm also actively looking for example code or tutorials that do similar things, but no luck there so far. Any pointers or references are welcomed.
You mean like
startActivity( new Intent(this, YourClass.class), Intent.FLAG_ACTIVITY_NEW_TASK);
Edit: ah you don't have the background stuff yet
`
private IntentFilter mNoticeFilter = new IntentFilter("com.you.yourapp.NEW_NOTICE");
private BroadcastReceiver mNoticeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Do something! ie launch your activity
startActivity( new Intent(this, YourClass.class));
}
};`
When you create your activity then you can
registerReceiver(mNoticeReceiver, mNoticeFilter);
and don't forget to unregisterReceiver(mNoticeReceiver);
see here: http://developer.android.com/reference/android/content/BroadcastReceiver.html
Sounds like you need a BroadcastReceiver.

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