I have two applications. One is a receiver and its starting my application. It works fine. Now i want destroy my application from the receiver itself. Is that possible ? Please note that these are my own application
It is possible but the activity has to finish itself using the finish()-method.
You can register an activity to a receiver using registerReceiver(..) and handle your logic in your activity. Don't forget to unregisterReceiver(...) inside the OnDestroy.
Example:
BroadcastReceiver mReceiver;
#Overrride
public void onCreate(Bundle savedInstanceState){
IntentFilter filter = new IntentFilter();
filter.addAction(...);
mReceiver= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// implement logic
finish();
}
}
registerReceiver(mReceiver, filter);
}
you cant directly control the lifecycle of one activity from another actvity
alternates to this could be :
you can set a timer in the new activity, if you want to end it after a certain amount of time, and call finish()' inrun()`
you can finish() the new activity on some events with EventListeners
Related
I have a simple Fragment within my Activity in which I enable and disable Bluetooth adapter and I want to listen to Bluetooth Adapter state changes with a BroadcastReceiver from within the Fragment. The reason is that I want to directly change the Fragment's UI elements upon Bluetooth state change. This is my code:
public class FragmentBT extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
IntentFilter iFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(BtStateChangedReceiver, iFilter);
}
#Override
public void onDestroy()
{
super.onDestroy();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(BtStateChangedReceiver);
}
public BroadcastReceiver BtStateChangedReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
... change UI based on the extra data from intent ...
}
}
}
When I enable or disable BT in my device using Action Buttons in my Fragment's ActionBar, the BT goes on and off, but my receiver never gets called. I never get into the receiver's onReceive method. I realize this is a pretty common question here, but I tried the sollutions from several but neither worked (and all are incorporated into my current code).
Thank you for any advice!
Try this:
getActivity().registerReceiver(BtStateChangedReceiver, iFilter);
getActivity().unregisterReceiver(BtStateChangedReceiver);
The docs say that 'LocalBroadcastManager' is used to 'register for and send broadcasts of Intents to local objects within your process'.
I have a receiver, it does call details saving task like storing incoming call, outgoing call etc.. all these details goes to sqlite DB. If my activity is not running, then its fine.
Sometime, when my activity is running, i get some incoming call. the receiver runs & stores data to DB. UI wont get refreshed because it never knows about change in DB.
Here i need to manually tell from receiver that, if activity is running refresh screen. How to implement this process in android.
I'm slightly confused in this part
You can use a LocalBroadcastManager to send a local broadcast to your Activity (more efficient and more secure than using a global broadcast):
Intent intent = new Intent(action);
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(context);
mgr.sendBroadcast(intent);
http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
Your Activity would have to register a BroadcastReceiver in onStart and unregister it in onStop:
private BroadcastReceiver mBroadcastReceiver;
mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do your thing
}
};
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this);
mgr.registerReceiver(mBroadcastReceiver, new IntentFilter(action));
in onStop:
mgr.unregisterReceiver(mBroadcastReceiver)
Now that's the official Android way to do it. I most certainly prefer to use an event/message bus like Otto or EventBus (https://github.com/greenrobot/EventBus). You can use those to broadcast messages/events across different components in your app. The advantage is you don't need access to a Context (like you do when using Broadcasts), it's faster and it forces the developer to object oriented programming (since the events are always objects). Once you start using an event bus you'll never look back to local broadcasts and you'll replace many of the sometimes messy observer / listener patterns used across your app.
You can create a BroadcastReceiver inside an activity. Register it in onResume() and unregister it in onPause(). Whenever your other receiver receives a broadcast, send a broadcast to this receiver too. If the activity is running(i.e. on front), the broadcast will be received. Do whatever you want in its onReceive().
Example:
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Do stuff
}
};
Also override methods:
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(br);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter("intent_filter"));//Use any string for IntentFilter you like
}
You can update fragments from activiy by creating methods inside fragment and access them from Fragment object inside activity.
I am using broadcast receiver in my app to detect incomming call and it works fine. But problem is I can not send action to activity. I mean.. I want do something in activity not in receiver. I read many tutorial but they all are performing action in receiver. Any idea ?
You can declare a BroadcastReceiver as inner class of the Activity. In this case you can directly call activity's methods:
public class MyActivity extends Activity {
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
activityMethod();
}
};
private final IntentFilter filter = new IntentFilter("android.intent.action.PHONE_STATE");
#Override
protected void onStart() {
super.onResume();
registerReceiver(receiver, filter);
}
#Override
protected void onStop() {
super.onPause();
unregisterReceiver(receiver);
}
private void activityMethod() {
}
}
You can start the Activity using an Intent and put a command code in the Intent extra fields. In your Activity you can then decide the behaviour based on the command code or resort to a default behaviour if none is present.
You can start an activity from your receiver via the normal means:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, YourActivity.class);
startActivity(i);
}
Note though that the user is going to expect that the phone application starts up since they are receiving a phone call. It is very likely a bad idea to hijack the phone call by dumping your own activity on top of the stock dialer app.
I have an issue with BroadcastReceiver which I'm using in my activities. I'm actually doing this :
In onCreate() :
receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("finish")) {
// some code
}
}
};
registerReceiver(receiver, intentFilter);
and in onResume() and onPause() I'm doing this :
#Override
public void onResume(){
super.onResume();
MyCollectionList.this.registerReceiver(receiver, intentFilter);
}
#Override
public void onPause(){
super.onPause();
MyCollectionList.this.unregisterReceiver(receiver);
}
where intentFilter is :
IntentFilter intentFilter = new IntentFilter("finish");
and when I do this in 6 activities where I need to add this broadcast receiver my application start lagging and getting slow than before.
So is there any other better way to watch for intent filters without slowing the app/or best way in my situation.
Thanks in advance!
Instead of registering your receiver with Activity's context, register it with your application's context in your 1st activity as below:
getApplication().registerReceiver(receiver, intentFilter);
This way even if your activities goes into 'pause' state, your receiver will remain active as your application will keep on running in the background.
Hope this helps.
dont register your broadcast receiver in onCreate. Registering it in onResume and unregistering in onPause is safe and enough in your case
you must be doing some heavy load processing in your receiver method. Android offers a 10sec window to perform what ever you want in your receiver otherwise it will declare it as ANR
To avoid lag, load your processing on a new worker thread
Maybe it's easy, but I couldn't really figure this out right so far... I got a BroadcastReceiver waiting to get triggered by the AlarmMangager - this works fine.
Now: because the event, if it occurs, needs to refresh some elements on screen of the main Activity, I would like to send an Intent from that background BroadcastReceiver to my Activity - but only if it is currently in the foreground, aka active.
If it is not running or not visible, I don't care - and the last thing I want to do is start the Activity by my intent! I handle repainting of the views in my onResume() method, so I don't care at all.
Any hints on how to do that?
Thanks!
EDIT: my BroadcastReceiver is waiting for alarms that must be notified to the user. So, it must be there and declared in the manifest. The problem is: it will have to decide whether the mentioned Activity is currently up in front or not.
I believe that you're familiar with AlarmManager now (creating a new Alarm, register a receiver...) so I will not talk about that. Just give you a solution for your question.
Instead of registering a BroadcastReceiver in a class file and in manifest, you only create a new BroadcastReceiver in your activity, and then, register it in onResume method, and unregister it in onPause method, sth like this in your activity:
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//do something
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("your alarm action");
...
}
#Override
protected void onResume() {
registerReceiver(mIntentReceiver, mIntentFilter);
...
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(mIntentReceiver);
...
super.onPause();
}
The receiver will only receive the alarm intent when your activity is in foreground :)
(Sorry if my English is not clear)
So this is almost Bino's answer, but: instead of moving the receiver into the activity, use two receivers, with different Intents. The first one is your original alarm Intent, with a receiver registered in the manifest as you already have, and then that receiver sends a second broadcast intent, which is handled by a receiver registered by the activity as Bino says.
I've done this in my own timer project, on github. Here are the alarm receiver and the requery receiver. Hope that helps.