java - 从 BroadcastReceiver 获取方法来更新 UI

标签 java android static broadcastreceiver

我正在尝试根据 BroadcastReceiver 中变量的变化来更新 UI。因此,我需要调用一个类的方法(以获取我提到的变量),该类在 MainActivity 中扩展 BroadcastReceiver 取决于但我无法获得任何真实的返回值方式。

扩展 BroadcastReceiver 的类是这样的:

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 指示为静态不是一个好方法,但我只想观察它的变化。如您所料,我总是得到无意义的返回值。对于 boolean isProviderActive 的值没有问题,您有什么建议?

编辑:我根据 BroadcastReceiver 的变化更新 UI 的临时解决方案。

忘记为 ProviderChangeReceiver 创建一个单独的类。 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()中注册receiver:

registerReceiver(pcr, new IntentFilter("android.location.PROVIDERS_CHANGED"));

最佳答案

每次 isProvidrActive 更改时整个 Activity 都重新生成的原因是因为我使用 context.startActivity(i) 发送了 Intent ,但这次我们发送了 Intent 使用 contect.sendBroadcast(i)ProviderChangeReceiver_updateUI 内部类,它只更新 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);
}

编辑您的 list 文件,使内部类 ProviderChangeReceiver_updateUI 能够监听我们的 broadcastReciever 发送的广播,将以下条目添加到 list 中

<receiver  android:name="<package-name>.MainActivity$ProviderChangeReceiver_updateUI"
            android:enabled="true" >
            <intent-filter>
            </intent-filter>
        </receiver>

$ 符号表示内部类。除非需要,否则无需添加 intent-filters

并在 ProviderChangeReceiver_updateUI 类中的 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);
            }
        });
    }
}

关于java - 从 BroadcastReceiver 获取方法来更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29053674/

相关文章:

C++:破坏静态内容的最佳方式

java - 设置背景颜色 [JAVA]

java - 将文件utf8转换为utf16 java

android - 部署到 Android、桌面和浏览器的单个 Kotlin+libgdx 代码库?

java - 如何在圆形范围内的android map 上生成标记

java - 全局执行器服务

java - JAVA中的 double

java - JTextArea 麻烦

android - 如何通过 USB 电缆从 Android 应用程序访问 tomcat 服务器?

java - 在类外共享静态数据