I have 5 fragments on a ViewPager (they're all in memory all the time, onPause() and such are never called while the containing Activity is on screen).
Anyway, I need to update one fragment (GroupsListFragment) depending on what's happening in another one (TimetableListFragment). I'm using LocalBroadcastManager and a BroadcastReceiver for this.
Now on to the relevant parts.
Registering for the broadcast Intent (severely abbreviated):
public class GroupsListFragment extends Fragment {
#Override
public void onResume() {
super.onResume();
mBroadcastManager = LocalBroadcastManager.getInstance(getActivity());
mBroadCastReceiver = new UpdateGroupsReceiver(this);
IntentFilter iFilter = new IntentFilter(UpdateGroupsReceiver.UPDATE_TIMETABLE_ACTION);
Log.d("GroupsListFragment", "Registering for receiver with intentfilter:[action=" + iFilter.getAction(0) + "]");
mBroadcastManager.registerReceiver(mBroadCastReceiver, iFilter);
}
}
Sending the broadcast (once again severely abbreviated):
public class TimetableListFragment extends Fragment {
public void updateStatus() {
Intent intent = new Intent(UpdateGroupsReceiver.UPDATE_TIMETABLE_ACTION);
mBroadcastManager.sendBroadcast(intent);
Log.d(TAG, "Sending broadcast with intent:[action=" + intent.getAction() + "]");
}
}
The problem is that my UpdateGroupsReceiver never receives it (onReceive() is never fired).
Any advice on what might be the culprit?
I am using this code that is working well
#Override
public void onResume() {
super.onResume();
if (myReceiver == null) {
myReceiver = new UpdateGroupsReceiver(this);
IntentFilter filter = new IntentFilter(
UpdateGroupsReceiver.UPDATE_TIMETABLE_ACTION);
registerReceiver(myReceiver, filter);
}
}
public void updateStatus() {
Intent intent = new Intent();
intent.setAction(UpdateGroupsReceiver.UPDATE_TIMETABLE_ACTION);
sendBroadcast(intent);
}
A runnig minimal example testapp can be found at https://github.com/k3b/EzTimeTracker/ under BroadCastTest.
Related
I think I may be missing some little detail and will feel very stupid once this is solved but....
I have many activities that all extend a base class. In the base class there is a Broadcast receiver to catch ACTION_SCREEN_OFF and ACTION_SCREEN_ON.
This will log out the user and return to the main screen.
public class ScreenBReceiver extends BroadcastReceiver
{
public void autoLogout(Context context)
{
MainActivity ma = new MainActivity();
ma.setLoggedIn(false);
Intent homeIntent = new Intent(context, MainActivity.class);
homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
FDFragmentActivity.this.finish();
context.startActivity(homeIntent);
}
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF) || intent.getAction().equals(Intent.ACTION_SCREEN_ON));
{
this.autoLogout(context);
}
}
}
public ScreenBReceiver screenLogout;
However, there is one (1) activity that is not receiving the action.
I cannot for the life of me figure out why the one activity is not receiving this action.
I don't know what else to post. If more info is needed please say so.
All of the activities in the manifest are declared identical.
Neither the xml layout nor the activity code specify that the screen be kept on.
What else could there be?
EDIT:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mContext = this;
mHandler = new Handler();
pi = new PollInterface(mContext);
screenLogout = new ScreenBReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
IntentFilter filter2 = new IntentFilter(Intent.ACTION_SCREEN_ON);
registerReceiver(screenLogout, filter);
registerReceiver(screenLogout, filter2);
.......
#Override
public void onDestroy()
{
super.onDestroy();
try
{
unregisterReceiver(screenLogout);
}
catch (IllegalArgumentException iae)
{
// Android can't just let it pass that a receiver was already unregistered.
// So, just ignore the daft exception it throws when unregistering twice.
}
}
I use broadcast receiver, and in Fragment.java i register. But it's not working.
My code:
Intent intent = new Intent("android.intent.action.LOGIN");
intent.putExtra("message", obj.getToken());
intent.setAction("com.sunrise.android.LOGIN");
loginView.getContext().sendBroadcast(intent);
In Fragment:
#Override
public void onResume() {
super.onResume();
informationStudentPresenter = new InformationStudentPresenter(this);
IntentFilter intentFilter = new IntentFilter("android.intent.action.LOGIN");
getActivity().registerReceiver(broadcastReceiver, intentFilter);
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getActivity(), "CLGT", Toast.LENGTH_SHORT);
if(intent.getAction().equalsIgnoreCase("com.sunrise.android.LOGIN")){
if(!"".equals(findToken())) {
informationStudentPresenter.getProfileStudent();
informationStudentPresenter.showToast();
}
}
}
};
Could you tell me where my mistake and how to fix it?
Thanks.
You're changing the Intent's action name right after initializing it with a different name. Then you're registering the broadcast receiver with an IntentFilter that waits for the old action name.
I need to send broadcast intent for specific receiver.
I use this function for it:
void sendTestBroadcast(Class<? extends BroadcastReceiver> clazz) {
Intent intent = new Intent(context, clazz);
intent.setAction(MY_ACTION);
context.sendBroadcast(intent);
}
Then I handle results in my Activity:
#Override
protected void onStart() {
super.onStart();
mReceiver = new Receiver();
registerReceiver(mReceiver, new IntentFilter(MY_ACTION));
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(mReceiver);
mReceiver = null;
}
Receiver is private and non-static class. I pass Receiver.class to my receiver sender as an argument. I also tried to use ComponentName to set destanation target, but it's still not working. I even tried to do Receiver class static -- same result.
What am I doing wrong?
Simple question, Is it possible to send/receive intents in the same class through LocalBroadcastReceiver? If yes can you show me an example?
Yes, LocalBroadcastReceiver works everywhere. Here's an example for an Activity:
BroadcastReceiver localBroadcastReciever = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("BroadcastReceiver", "Message received " + intent.getAction());
}
};
#Override
protected void onStart()
{
super.onStart();
final LocalBroadcastManager localBroadcastManager =
LocalBroadcastManager.getInstance(this);
final IntentFilter localFilter = new IntentFilter();
localFilter.addAction("com.my.package.intent.ACTION_NAME_HERE");
localBroadcastManager.registerReceiver(localBroadcastReceiver, localFilter);
}
#Override
protected void onStop()
{
super.onStop();
final LocalBroadcastManager localBroadcastManager =
LocalBroadcastManager.getInstance(this);
// Make sure to unregister!!
localBroadcastManager.unregisterReceiver(localBroadcastReceiver);
}
Somewhere, either in the same Activity or elsewhere in your application (it doesn't matter):
final LocalBroadcastManager localBroadcastManager =
LocalBroadcastManager.getInstance(context);
localBroadcastManager.sendBroadcast(new Intent("com.my.package.intent.ACTION_NAME_HERE"));
You can, of course, use intent.putExtra to add any additional data or use multiple actions to differentiate broadcast messages.
I want to dynamically register and unregister my receiver class with the broadcast:
"android.net.wifi.STATE_CHANGE"
This works very well if I do this in the manifest. But this makes it static. I want to do it dynamically in the activity class. What is its correspondent command in the activity class?
This is what my code is...
and I am getting a problem because of registering and unregistering(multiple times) my receiver(which is starting a service).
public class startScreen extends Activity {
/** Called when the activity is first created. */
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.example.MyService");
context.startService(serviceIntent);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.initial);
final IntentFilter filter = new IntentFilter();
filter.addAction("android.net.wifi.STATE_CHANGE");
Button button = (Button) findViewById(R.id.button1);
final ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleButton1);
try {
...some code...
if (bool == true) {
toggleButton.setChecked(true);
this.registerReceiver(receiver, filter);
} else
toggleButton.setChecked(false);
} catch (Exception e) {
Log.e("Error", "Database", e);
} finally {
...
}
toggleButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if ((toggleButton.isChecked())) {
getBaseContext().registerReceiver(receiver, filter);
} else {
if (receiver != null) {
getBaseContext().unregisterReceiver(receiver);
receiver = null;
}
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (bool == true) {
if (receiver == null)
this.registerReceiver(receiver, filter);
}
}
#Override
protected void onPause() {
super.onPause();
if (receiver != null) {
this.unregisterReceiver(receiver);
receiver = null;
}
}
}
The LocalBroadcastManager class is used to register for and send broadcasts of Intents to local objects within your process. This is faster and more secure as your events don't leave your application.
The following example shows an activity which registers for a customer event called my-event.
#Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));
}
// handler for received Intents for the "my-event" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
// This method is assigned to button in the layout
// via the onClick property
public void onClick(View view) {
sendMessage();
}
// Send an Intent with an action named "my-event".
private void sendMessage() {
Intent intent = new Intent("my-event");
// add data
intent.putExtra("message", "data");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
use the below methods to register/unregister your receiver:
registerReceiver(BroadcastReceiver receiver, new IntentFilter("android.net.wifi.STATE_CHANGE"));
unregisterReceiver(BroadcastReceiver receiver);
For reference have a look at this
Don't add dynamic broadcast receiver in onReceive on broadcast file. Add it on first activity or main activity of your application. If you needed it only when your application is open. But if you need it always received response just added it on manifest file
Register dynamic broadcast receiver on main activity
MyReceiver reciver;
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
intentFilter.addAction("android.net.wifi.STATE_CHANGE");
reciver = new MyReceiver();
registerReceiver(reciver, intentFilter);
}
Unregister that broadcast receiver on activity stop or closed
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(reciver);
}
Perhaps I'm a bit too late, but the problem lies on the fact that you are setting the receiver = null in your onPause method, and then never setting it again. You are also trying to register it in your onResume method but only if it is null, which makes no sense too.
You should change the logic where you set/test the null value of the receiver, to instead just use a boolean variable to keep track of the receiver status (if it's registered or not).
public void registerBroadcastReceiver(View view) {
this.registerReceiver(broadCastReceiver, new IntentFilter(
"android.intent.action.TIME_TICK"));
}
public void unregisterBroadcastReceiver(View view) {
this.unregisterReceiver(broadCastReceiver);
}