I am trying to update the UI according to change of a variable in BroadcastReceiver
. Thus, I need to call a method (to get the variable I mentioned) of a class which extends BroadcastReceiver
in MainActivity
depending on but I cannot get the true return value in any way.
The class which extends BroadcastReceiver
is this:
public class ProviderChangeReceiver extends BroadcastReceiver {
private static boolean isProviderActive;
@Override
public void onReceive(Context context, Intent intent) {
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER) && lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Log.v("-> ", "GPS + NETWORK");
isProviderActive = true;
}
else if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER) && !lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Log.v("-> ", "GPS");
isProviderActive = true;
}
else if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) && !lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Log.v("-> ", "NETWORK");
isProviderActive = true;
}
else
{
Log.v("-> ", "DISCONNECT");
isProviderActive = false;
}
}
public static boolean isProviderActive(){
return isProviderActive;
}
}
I need to get true value of isProviderActive
to use in this part of MainActivity
:
...
private class ProviderChangeReceiver_updateUI extends ProviderChangeReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
MapsActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v("-A", ""+ isProviderActive());
if (isProviderActive())
originButton.setVisibility(View.VISIBLE);
else
originButton.setVisibility(View.INVISIBLE);
}
});
}
}
I know that indicating isProviderActive
as static is not a good approach but I just want to observe its changes. As you guess, I got nonsensical return values all the time. To values of boolean isProviderActive
without problem, what do you advise?
Edit: My temporary solution to update UI according to changes in BroadcastReceiver
.
Forget about creating a separate class for ProviderChangeReceiver
. Instead of the code segment above, following segment should be added in MainActivity
. Also, it goes without saying that there is the initialization of ProviderChangeReceiver
in onCreate()
.
...
private class ProviderChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
MapsActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v("COUNT: ", "" + count++);
if (isLocationProviderActive()) {
originButton.getBackground().setAlpha(220);
originButton.setEnabled(true);
//marker.setVisible(true);
}
else {
originButton.getBackground().setAlpha(77);
originButton.setEnabled(false);
marker.setVisible(false);
}
}
});
}
}
private boolean isLocationProviderActive(){
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER) && lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
return true;
return false;
}
Of course then register the receiver in onCreate()
as well:
registerReceiver(pcr, new IntentFilter("android.location.PROVIDERS_CHANGED"));
I think a nice way to handle something like this is with an eventbus.
Take a look at Squares Otto library.
In your broadcast receiver you would publish the change event and then in your activity you would subscribe to the event and update the ui.
Based on the context of your question, I think you would be able to avoid the broadcast receiver entirely, since I suspect you have something watching your provider and then broadcasting the event.
Update: (based on comments)
I think the way this would work would be something like this
In the code that detects the change in location provider:
in your activity
The reason that every time
isProvidrActive
changed the whole activity got regenerated is because I sent the intent usingcontext.startActivity(i)
but rather this time we send the intent usingcontect.sendBroadcast(i)
to theProviderChangeReceiver_updateUI
inner class which update only desired part of the UI. So below is the new code.Edit your manifest file to enable the inner class
ProviderChangeReceiver_updateUI
to listen for broadcast sent by ourbroadcastReciever
, add the following entry to manifestthe $ sign indicates inner class. No need to add
intent-filters
unless required.And in your
ProviderChangeReceiver_updateUI
class in theonReceive()
method get the value ofisProviderActive