正在从 BroadcastReceiver 获取方法以更新 UI
Fetching methods from BroadcastReceiver to update UI
我正在尝试根据 BroadcastReceiver
中变量的变化来更新 UI。因此,我需要调用 class 的方法(以获取我提到的变量),它在 MainActivity
中扩展 BroadcastReceiver
取决于但我无法获得真正的 return 值无论如何。
扩展BroadcastReceiver
的class是这样的:
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;
}
}
我需要获取 isProviderActive
的真实值以用于 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);
}
});
}
}
我知道将 isProviderActive
指示为静态不是一个好方法,但我只是想观察它的变化。如您所料,我一直得到无意义的 return 值。对于 boolean isProviderActive
的值没有问题,您有什么建议?
编辑:我根据 BroadcastReceiver
中的变化更新 UI 的临时解决方案。
忘记为 ProviderChangeReceiver
创建一个单独的 class。应在 MainActivity
中添加以下代码段,而不是上面的代码段。另外,不言而喻,onCreate()
.
中有ProviderChangeReceiver
的初始化
...
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;
}
当然也可以在onCreate()
中注册接收者:
registerReceiver(pcr, new IntentFilter("android.location.PROVIDERS_CHANGED"));
每次 isProvidrActive
更改整个 activity 重新生成的原因是因为我使用 context.startActivity(i)
发送了意图,但这次我们使用 [=15= 发送了意图] 到 ProviderChangeReceiver_updateUI
内部 class,它只更新 UI 的所需部分。下面是新代码。
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;
}
//Send value of isProviderActive to ProviderChangeReceiver_updateUI
Intent i = new Intent(context, ProviderChangeReceiver_updateUI.class);
i.putExtra("isProvidrActv", isProviderActive);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.sendBroadcast(i);
}
编辑您的清单文件以启用内部 class ProviderChangeReceiver_updateUI
来侦听我们的 broadcastReciever
发送的广播,将以下条目添加到清单
<receiver android:name="<package-name>.MainActivity$ProviderChangeReceiver_updateUI"
android:enabled="true" >
<intent-filter>
</intent-filter>
</receiver>
$ 符号表示内部 class。除非需要,否则无需添加 intent-filters
。
并且在你的ProviderChangeReceiver_updateUI
class中的onReceive()
方法中得到isProviderActive
的值
...
//changed the identifiers from private to public static and the class extends //BroadcastReceiver
public static class ProviderChangeReceiver_updateUI extends BroadcastReceiver {
//Empty constructor to prevent exception can't instantiate no empty constructor
public ProviderChangeReceiver_updateUI(){
}
//Removed the final keyword from handler
private Handler handler; // Handler used to execute code on the UI thread
public ProviderChangeReceiver_updateUI(Handler handler) {
this.handler = handler;
}
@Override
public void onReceive(final Context context, final Intent intent) {
boolean isProvidrActv = intent.getBooleanExtra("isProvidrActv", false);
//mapsActivity is a global static object of the class MapsActivity<br/>
//instantiate it the onCreate() method of mainactivity for ex:<br/>
/*public class MapsActivity extends Activity{<br/>
static MapsActivity mapsActivity;
@Override
protected void onCreate(Bundle savedInstancestate){
ma = new MapsActivity();
}*/
mapsActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (isProvidrActv)
originButton.setVisibility(View.VISIBLE);
else
originButton.setVisibility(View.INVISIBLE);
}
});
}
}
我认为处理此类事情的一个好方法是使用事件总线。
看看 Squares Otto 库。
在您的广播接收器中,您将发布更改事件,然后在您的 activity 中,您将订阅该事件并更新 ui。
根据你问题的上下文,我认为你可以完全避免广播接收器,因为我怀疑你有东西在监视你的提供者然后广播事件。
更新:(基于评论)
我认为它的工作方式应该是这样的
在检测位置提供商变化的代码中:
if (bothProvidersAreStopped()) {
bus.publish(new BothProvidersStoppedEvent());
} else if (onlyNetworkProviderIsStopped() {
bus.publish(new NetworkProviderStoppedEvent());
} else if (onlyGpsProviderIsStopped() {
bus.publish(new GpsProviderStoppedEvent());
}
在你的 activity
@Subscribe public void onBothProvidersStopped(BothProvidersStopped event) {
// handle case were both providers just stopped
}
@Subscribe public void onNetworkProvidersStopped(BothProvidersStopped event) {
// handle case were network provider just stopped
}
@Subscribe public void onGpsProvidersStopped(BothProvidersStopped event) {
// handle case were gps provider just stopped
}
我正在尝试根据 BroadcastReceiver
中变量的变化来更新 UI。因此,我需要调用 class 的方法(以获取我提到的变量),它在 MainActivity
中扩展 BroadcastReceiver
取决于但我无法获得真正的 return 值无论如何。
扩展BroadcastReceiver
的class是这样的:
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;
}
}
我需要获取 isProviderActive
的真实值以用于 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);
}
});
}
}
我知道将 isProviderActive
指示为静态不是一个好方法,但我只是想观察它的变化。如您所料,我一直得到无意义的 return 值。对于 boolean isProviderActive
的值没有问题,您有什么建议?
编辑:我根据 BroadcastReceiver
中的变化更新 UI 的临时解决方案。
忘记为 ProviderChangeReceiver
创建一个单独的 class。应在 MainActivity
中添加以下代码段,而不是上面的代码段。另外,不言而喻,onCreate()
.
ProviderChangeReceiver
的初始化
...
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;
}
当然也可以在onCreate()
中注册接收者:
registerReceiver(pcr, new IntentFilter("android.location.PROVIDERS_CHANGED"));
每次 isProvidrActive
更改整个 activity 重新生成的原因是因为我使用 context.startActivity(i)
发送了意图,但这次我们使用 [=15= 发送了意图] 到 ProviderChangeReceiver_updateUI
内部 class,它只更新 UI 的所需部分。下面是新代码。
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;
}
//Send value of isProviderActive to ProviderChangeReceiver_updateUI
Intent i = new Intent(context, ProviderChangeReceiver_updateUI.class);
i.putExtra("isProvidrActv", isProviderActive);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.sendBroadcast(i);
}
编辑您的清单文件以启用内部 class ProviderChangeReceiver_updateUI
来侦听我们的 broadcastReciever
发送的广播,将以下条目添加到清单
<receiver android:name="<package-name>.MainActivity$ProviderChangeReceiver_updateUI"
android:enabled="true" >
<intent-filter>
</intent-filter>
</receiver>
$ 符号表示内部 class。除非需要,否则无需添加 intent-filters
。
并且在你的ProviderChangeReceiver_updateUI
class中的onReceive()
方法中得到isProviderActive
...
//changed the identifiers from private to public static and the class extends //BroadcastReceiver
public static class ProviderChangeReceiver_updateUI extends BroadcastReceiver {
//Empty constructor to prevent exception can't instantiate no empty constructor
public ProviderChangeReceiver_updateUI(){
}
//Removed the final keyword from handler
private Handler handler; // Handler used to execute code on the UI thread
public ProviderChangeReceiver_updateUI(Handler handler) {
this.handler = handler;
}
@Override
public void onReceive(final Context context, final Intent intent) {
boolean isProvidrActv = intent.getBooleanExtra("isProvidrActv", false);
//mapsActivity is a global static object of the class MapsActivity<br/>
//instantiate it the onCreate() method of mainactivity for ex:<br/>
/*public class MapsActivity extends Activity{<br/>
static MapsActivity mapsActivity;
@Override
protected void onCreate(Bundle savedInstancestate){
ma = new MapsActivity();
}*/
mapsActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (isProvidrActv)
originButton.setVisibility(View.VISIBLE);
else
originButton.setVisibility(View.INVISIBLE);
}
});
}
}
我认为处理此类事情的一个好方法是使用事件总线。
看看 Squares Otto 库。
在您的广播接收器中,您将发布更改事件,然后在您的 activity 中,您将订阅该事件并更新 ui。
根据你问题的上下文,我认为你可以完全避免广播接收器,因为我怀疑你有东西在监视你的提供者然后广播事件。
更新:(基于评论)
我认为它的工作方式应该是这样的
在检测位置提供商变化的代码中:
if (bothProvidersAreStopped()) {
bus.publish(new BothProvidersStoppedEvent());
} else if (onlyNetworkProviderIsStopped() {
bus.publish(new NetworkProviderStoppedEvent());
} else if (onlyGpsProviderIsStopped() {
bus.publish(new GpsProviderStoppedEvent());
}
在你的 activity
@Subscribe public void onBothProvidersStopped(BothProvidersStopped event) {
// handle case were both providers just stopped
}
@Subscribe public void onNetworkProvidersStopped(BothProvidersStopped event) {
// handle case were network provider just stopped
}
@Subscribe public void onGpsProvidersStopped(BothProvidersStopped event) {
// handle case were gps provider just stopped
}