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.
Related
i want to unregister some broadcast receivers with single click.here is the flow.. lets say in Activity A i have below broadcast receivers.
public BroadcastReceiver upload = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
public BroadcastReceiver download = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
and in Activity B i have below broadcast receivers
public BroadcastReceiver wifi = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
public BroadcastReceiver data = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
my problem is i want to unregister all these BroadcastReceiver from Activity C with a button click. How can i do that? and how can i check is receiver is registered or not..?
Keeping broadcast receiver register even after activity is out of screen is memory leak and you should not do that.
Always register your broadcast receivers in onStart/onCreate/onResume and unregister them in onStop/onDestroy/onPause.
Why do you need to keep receiver active even in case activity is out of screen? You might as well use Android Service if you want something to execute out of activity scopes.
Create an Interface in your Activity C with a method unresisterRegisters()
Implement this Interface In Activity A and B. Overrrid the method and write code for unregistere Receivers
create object of A and B in Activity C inside OnButton click and call unresisterRegisters() method with both methods.
I hope this will help You.
I am working on music player app and I have included the basic functionality like Play, Pause, next and Previous tracks using service class.
Now I want to update myrecyclerview UI according to the action that user clicks(eg: on the play, there should be an image of the selected element in recyclerview).
I thought to use Broadcast Receiver that service class will broadcast on different actions and then recyclerview can update according to the broadcast action. But how do I add such functionality?
You'd need an in-activity broadcast receiver. Such receivers are registered when your activity is shown and unregistered once it's hidden.
public class MainActivity extends Activity {
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Here update your RecyclerView
}
};
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(YourService.YOUR_CUSTOM_ACTION);
registerReceiver(mReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
}
And in your service, simply send broadcasts:
Intent intent = new Intent(YOUR_CUSTOM_ACTION);
// put extras in the intent as you wish
sendBroadcast(intent);
In my App, there is a condition which check every day and if it gets true then I want my App get close in between the run like a crash and stack also gets clear .
I have try and tested many solutions but didn't find the one that works the way i wanted .
My BroadcastReceiver:
public void onReceive(Context context, Intent intent) {
PreferenceForApp prefs = new PreferenceForApp(context);
Bundle bundle = intent.getExtras();
if (bundle!=null){
if(bundle.containsKey("exception")) {
// String e = bundle.getString("exception")
if(bundle.get("exception").toString().equalsIgnoreCase("http request failed with error_msg No Match Found")) {
prefs.setIsDeviceValidated(false);
prefs.setIsLogIn(false);
Log.i("Time", "Exception Occur");
Intent CSPIntent=new Intent(context,CSPLoginActivity.class);
CSPIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
CSPIntent.putExtra("close_activity", true);
Log.i("Time", "IntentExit");
context.startActivity(CSPIntent);
}
}
}
}
}
And code to finish in an Activity I am calling from broadcastReceiver:
if (getIntent().getBooleanExtra("close_activity",false)) {
Log.i("Time", "ExitCSPLogin");
this.finish();
}
This code is not closing App in between the run.
You need to register BroadcastReceiver in your activity and send broadcast to BroadcastReceiver when you want to close application.
In your Activity try this:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_CLOSE");;
BroadcastReceiver Receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
registerReceiver(Receiver, intentFilter);
in onDestroy() method of you Activity unregister BroadcastReceiver:
#Override
protected void onDestroy() {
unregisterReceiver(Receiver);
super.onDestroy();
}
Now when you want close application send broadcast to BroadcastReceiver:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_CLOSE");
sendBroadcast(broadcastIntent);
Hope this helps!
you have to check below condition in your app's mainActivity's onCreate method every time when user enter in your app. or in onResume if you want to to close your app immediately
if (!prefs.getIsDeviceValidated()) {
Log.i("Time", "ExitCSPLogin");
this.finish();
}
i assume you have more then one activity in your app, so insted of check above flag in every activity we 'll put it in main activity. allow user to use your app until he/she come at mainActivity
Note: create Broadcast Receiver for your App(add in manifest), not for specific activity
Is it possible to register them all at once with a simple code?
Or do they have to be unregistered one by one?
I know it's an old question but why don't you use broadcastreceivers to pick up an intent which then triggers all receivers to unregister?
(Wanted to post something more accurate than the current answer provides)
In the responding fragments/ activities you put this:
public class PanicFragment extends Fragment {
IntentFilter killFilter = new IntentFilter("your.app.name.some.awesome.action.title");
BroadcastReceiver kill = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(receiver); // The actual receiver you want to unreigster
context.unregisterReceiver(this); // The one you just created
}
};
(Don't forget to register the receivers initially when creating the fragment/ activity)
And in your service or other activity or whatever you want this:
private void callThisToUnregisterAllYourReceivers(Context context) {
Intent killThemAll = new Intent();
killThemAll.setAction("your.app.name.some.awesome.action.title");
context.sendBroadcast(killThemAll);
}
I hope this was in any way helpful
You have to do it one by one. An activity should not have very many, if any, and so I would not expect this to be too tedious.
I wouldn't use another BroadcastReceiver to remove other broadcast receivers.
Here is what I added in my Application Class:
private static List<BroadcastReceiver> broadcastReceivers = new LinkedList<>();
public void addReceiver(BroadcastReceiver receiver, IntentFilter filter) {
mContext.registerReceiver(receiver, filter);
broadcastReceivers.add(receiver);
}
public void removeReceiver(BroadcastReceiver receiver) {
unregisterReceiver(receiver);
broadcastReceivers.remove(receiver);
}
public List<BroadcastReceiver> getAllReceivers() {
return broadcastReceivers;
}
public void removeAllReceivers() {
for (BroadcastReceiver receiver : getAllReceivers()) {
removeReceiver(receiver);
}
}
When i have a broadcastReceiver say android.intent.action.MEDIA_BUTTON and i want to update the current activity's UI without creating a new activity, is there any good practice on this one?
What i know (might not be correct)
1) I can put the BroadcastReceiver in the same class as the activity and call the updateUI function after certain activity
2) Create a ContentObserver?
3) Communicate to a service created by the activity, use aidl. (I dont know how to get the current service if its registered from an activity)
4) Create a custom filter on the broadcastReceiver located on the same class as the activity, and use context.sendBroadcast(msg of custom filter) and in the custom filter call updateUI (same as one but more generic?)
The final flow is it would come from a BroadcastReceiver and ends up updating the UI without renewing the activity (unless the activity is dead?)
Kindly provide links/source code on your how you tackle this kind of problem. Thanks a lot in advance :)
The easiest way to provide this functionality is to put the broadcast receiver in you Activity and bind / unbind it using registerReceiver and unregisterreceiver:
public class MyActivity extends Activity {
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
MyActivity.this.receivedBroadcast(intent);
}
};
#Override
public void onResume() {
super.onResume();
IntentFilter iff = new IntentFilter();
iff.addAction("android.intent.action.MEDIA_BUTTON");
// Put whatever message you want to receive as the action
this.registerReceiver(this.mBroadcastReceiver,iff);
}
#Override
public void onPause() {
super.onPause();
this.unregisterReceiver(this.mBroadcastReceiver);
}
private void receivedBroadcast(Intent i) {
// Put your receive handling code here
}
}
Depending on the intent you wish to receive, you may need to add the appropriate permissions to your AndroidManifest.xml file.
What I recently had to do to change a Button's text after receiving data from a LocalBroadcastManager is to store the value in a private field and then do the UI stuff in my onResume() method.
public class myClass extends Activity {
private String myString;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// register to receive data
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter("myAction"));
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// get the extra data included in the intent
myString = intent.getStringExtra("myString");
}
};
#Override
public void onResume() {
super.onResume();
System.out.println("onResume");
// do something to the UI
myButton.setText(myString != null ? myString : "Default");
}
}