I am currently firing an Intent to a Broadcast Receiver which in turns starts an Activity.
Then from the same Service another Intent is fired to a Broadcast Receiver thats in the Activity.
The problem is that the Activity isn't getting the Intent meant for it because it is fired before it is alive and the Broadcast Reciever is registered.
I was wondering is there anyway to make sure an Activity is alive before sending an Intent?
Or any other solution to this?
Why not start the activity if it is not yet alive?
The general mechanism to start a new
activity if its not running— or to
bring the activity stack to the front
if is already running in the
background— is the to use the
NEW_TASK_LAUNCH flag in the
startActivity() call.
That or simply give the activity a chance to start before firing the Intent.
Alternatively you could try using sendOrderedBroadcast to retrieve data back from the broadcast and then possibly do a retry.
public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
Related
Is it possible to send an intent from a service to an Application class? Not Activity?
I wouldn't know what activity would be running at a particular time, so I am adding a boolean flag in the activity class that detects the activity and sends the appropriate data based on the broadcast received.
If your Service is active, then your Application class is active as well.
Otherwise you wouldn't be able to use getApplicationContext().
Although I'm skeptic about a service that runs forever there is a very clean way to make the Service communicate with a certain Activity, should the last one be currently active.
Such clean way is called LocalBroadcastManager.
The Activity meant to receive the data should register a BroadcastReceiver in onResume() and unregister it in onPause().
You instantiate your BroadcastReceiver in your Activity's onCreate()
this.localBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Do what you have to do here if you receive data from the Service.
}
}
You create a Filter so your Activity only listens to a certain type of signals.
private IntentFilter notifIntentFilter new IntentFilter("com.you.yourapp.MY_SIGNAL");
in onResume()
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(this.localBroadcastReceiver, notifIntentFilter);
in onPause()
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);
Now whenever you want to send data to your Activity, your Service can call:
final Intent intent = new Intent();
intent.setAction("com.you.yourapp.MY_SIGNAL");
// put your data in intent
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
If your Activity is awake, it will respond to the signal. Otherwise, if it's in the background, or it is not instantiated it won't.
You can apply this pattern to as many Activities as you wish.
Still, I have never used this inside the Application class. But you can try to register your receiver there. It might work, since if the Application class is destroyed, the BroadcastReceiver is destroyed too and thus probably unregistered as well.
The point is, if your Application gets destroyed, your Service will be killed as well. Unless you launched it in another process. But then it will have it's own instance of Application; and this is a complex thing you probably do not want to get into details now...
Important: since the Application class is not tied to any UI component, you can do whatever you need directly inside your service. If you need to manipulate the UI, then the pattern described above will work for you.
Please read about new Android's background limitations.
Edit:
Oh yeah right, if you need your Service to call a function declared in your Application class, you can just do
((MyApplication) getApplication()).myFunctionToHandleData(Intent intent);
I didn't really understand your question though, but either of the methods described above should work for you.
I'm using service to run Bluetooth in background,but i don't no how to send data from another activity to service
Service and other activities work in the same process
To start a Service, use following statement:
Intent intent = new Intent(context, Service.class);
// intent put some extra
startService(intent);
Calling this statement firstly, Service call onCreate() method and onStartCommand().
Not firstly, Service just call onStartCommand().
You can check if it is called firstly by extra in intent.
So you can send data with the same method startService(Intent intent).
Service works in another process
use [bindService](https://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)) and AIDL
It is suggested that make service and other activities work in the same process when your target is not complex.
Is it possible to startActivityForResult from something other than activity?
Eg: we have broadcastReceiver class which starts activity, those activity takes some action, finishes returning result which this broadcastReceiver class should interpret according to result itself(finish app or perform more sophisticated actions).
BroadcastReceiver cannot handler onActivityResult callback.
A better idea would be to create a different BroadcastReceiver that handles the response of the activity started by first Receiver.
So you will have one Receiver that starts an activity on some action, the activity, in turn, sends a broadcast to other receiver which is supposed to perform further tasks
I have a BroadcastReceiver which handles System Broadcasts like AC Connected and disconnected. The BroadcastReceiver receives POWER_CONNECTED and starts an Activity "MainActivity", which unlocks KeyGuard and acquires WakeLock. In the onCreate and in onResume I register dynamically a BroadcastReceiver to listen on POWER_DISCONNECTED.
The "MainActivity" starts a second "VideoPlayer Activity", which also register a BroadcastReceiver listening on POWER_DISCONNECTED.
When I send the ACTION_POWER_DISCONNECT over adb I see through LogCat that the "MainActivity" stops first. Why?
How can I handle that the "VideoPlayerActivity" finishes first?
Thanks
Look here (http://developer.android.com/reference/android/content/BroadcastReceiver.html):
Normal broadcasts (sent with Context.sendBroadcast) are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time. This is more efficient, but means that receivers cannot use the result or abort APIs included here.
You can't guarantee that VideoPlayerActivity will receive.
I would recommend to create a separate BroadcastReceiver (which isn't part of activities). And in this broadcast receiver do something like this:
videoPlayerActivity.finish();
mainActivity.finish();
Sure, you need to initialize both of these variables in onCreate or onResume of your activities.
Actually you Registered the Broadcast Receiver in your main activity so its passing the context of main activity in the BroadcastReceiver so i will able to finish only that activity.
So lets screw up this what you need to do just write these lines of code in the onReceive() of Power Disconnected action receiver:
public void onReceive(Context context, Intent intent) {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startMain);
}
Enjoy
There's a service which runs always and listens to some events, will push them into a log someday. I would like to display those events in the main actvity when it's running, but how to send the event details to the activity? You don't receive the intent itself, when you send it to the activity with Context.startActivity(), so that you can't retrive the data with Intent.getXxxExtra().
(The activity would "subscribe" and "unsibscribe" to the events in onStart() and onStop() with an intent sent to the service, so that the events wouldn't open the activity if it's not in foreground)
Or is there any other way to send data (20-30 characters long String) from a service to an intent?
Issue a Broadcast from your Service and implement a private BroadcastReceiver in your activity.
Yes, you can use the Handler class for message passing between your Service and your main Activity.