从BroadcastReceiver的抓取方法来更新UI [英] Fetching methods from BroadcastReceiver to update UI

查看:474
本文介绍了从BroadcastReceiver的抓取方法来更新UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据变量的的BroadcastReceiver 的变化来更新UI。因此,我需要调用一个方法(以获得我所提到的变量)一类,它扩展了的BroadcastReceiver MainActivity 视,但我不能以任何方式真正的返回值。

它扩展类的BroadcastReceiver 是这样的:

 公共类ProviderChangeReceiver扩展的BroadcastReceiver {

    私有静态布尔isProviderActive;
    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){
        LocationManager LM =(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        如果(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)及&安培; lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
            Log.v( - >中,GPS + NETWORK);
            isProviderActive = TRUE;
        }

        否则如果(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)及&安培;!lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
            Log.v( - >中,全球定位系统);
            isProviderActive = TRUE;
        }

        否则如果(lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)及&安培;!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            Log.v( - >中,网络);
            isProviderActive = TRUE;
        }

        其他
        {
            Log.v( - >中,DISCONNECT);
            isProviderActive = FALSE;
        }
    }

    公共静态布尔isProviderActive(){
        返回isProviderActive;
    }
}
 

我需要获得 isProviderActive 的真正价值在这部分使用 MainActivity

  ...
私有类ProviderChangeReceiver_updateUI扩展ProviderChangeReceiver {
    @覆盖
    公共无效的onReceive(最终上下文的背景下,最终的意图意图){
        MapsActivity.this.runOnUiThread(新的Runnable(){
            @覆盖
            公共无效的run(){
                Log.v( -  A,+ isProviderActive());
                如果(isProviderActive())
                    originButton.setVisibility(View.VISIBLE);
                其他
                    originButton.setVisibility(View.INVISIBLE);
            }
        });
    }
}
 

我知道,指示 isProviderActive 静态不是一个好办法,但我只是想观察其变化。正如你猜,我得到了无意义的返回值,所有的时间。要对布尔isProviderActive 没有问题的值,你有什么指教?

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

忘记了 ProviderChangeReceiver 创建一个单独的类。相反,高于code段,下段应 MainActivity 添加。而且,不用说,有 ProviderChangeReceiver 在初始化的onCreate()

  ...
私有类ProviderChangeReceiver扩展的BroadcastReceiver {
    @覆盖
    公共无效的onReceive(最终上下文的背景下,最终的意图意图){
        MapsActivity.this.runOnUiThread(新的Runnable(){
            @覆盖
            公共无效的run(){
                Log.v(计数,+计数++);
                如果(isLocationProviderActive()){
                    originButton.getBackground()setAlpha(220)。
                    originButton.setEnabled(真正的);
                    //marker.setVisible(true);
                }
                其他 {
                    originButton.getBackground()setAlpha(77)。
                    originButton.setEnabled(假);
                    marker.setVisible(假);
                }
            }
        });
    }
}

私人布尔isLocationProviderActive(){
    如果(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)及&安培; lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
        返回true;
    返回false;
}
 

当然,然后注册在的onCreate接收器()以及

  registerReceiver(PCR,新的IntentFilter(android.location.PROVIDERS_CHANGED));
 

解决方案

究其原因,每次 isProvidrActive 改变了整个活动得到了再生,是因为我用送的意图 context.startActivity(我)而这个时候,我们使用 contect.sendBroadcast(我)发送意图的 ProviderChangeReceiver_updateUI 该更新只需要的用户界面的一部分,内部类。所以,下面是新的code。

 私有静态布尔isProviderActive;
@覆盖
公共无效的onReceive(上下文的背景下,意图意图){
    LocationManager LM =(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    如果(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)及&安培; lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
        Log.v( - >中,GPS + NETWORK);
        isProviderActive = TRUE;
    }

    否则如果(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)及&安培;!lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
        Log.v( - >中,全球定位系统);
        isProviderActive = TRUE;
    }

    否则如果(lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)及&安培;!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
        Log.v( - >中,网络);
        isProviderActive = TRUE;
    }

    其他
    {
        Log.v( - >中,DISCONNECT);
        isProviderActive = FALSE;
    }

    //发送isProviderActive的价值ProviderChangeReceiver_updateUI
    意图I =新的意图(背景下,ProviderChangeReceiver_updateUI.class);
    i.putExtra(isProvidrActv,isProviderActive);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.sendBroadcast(ⅰ);
}
 


编辑您的manifest文件,以使内部类 ProviderChangeReceiver_updateUI 来收听广播通过我们的 broadcastReciever ,添加发送下面进入正体现

 <接收器安卓名=<包名称> .MainActivity $ ProviderChangeReceiver_updateUI
            机器人:启用=真正的>
            <意向滤光器>
            &所述; /意图滤光器>
        < /接收器>
 

$符号表示内部类。无需添加意图过滤器除非必需的。

而在你的 ProviderChangeReceiver_updateUI 类中的的onReceive()方法来获取的价值isProviderActive

  ...
//改变标识符从私人到公共静态和类扩展//的BroadcastReceiver
公共静态类ProviderChangeReceiver_updateUI扩展的BroadcastReceiver {

    //空构造函数prevent异常不能实例化没有空的构造
    公共ProviderChangeReceiver_updateUI(){

    }

    //删除了处理final关键字
    私人处理程序处理程序; //处理程序用于执行code在UI线程

    公共ProviderChangeReceiver_updateUI(处理程序处理){
        this.handler =处理程序;
    }

    @覆盖
    公共无效的onReceive(最终上下文的背景下,最终的意图意图){
        布尔isProvidrActv = intent.getBooleanExtra(isProvidrActv,假);
        // mapsA​​ctivity是类MapsActivity℃的全局静态对象峰; br />
        //实例化它的onCreate()mainactivity为前方法:其中; BR />
/ *公共类MapsActivity延伸活动{< BR />
         静态MapsActivity mapsA​​ctivity;

         @覆盖
         保护无效的onCreate(包savedInstancestate){
        MA =新MapsActivity();
        } * /
        mapsA​​ctivity.runOnUiThread(新的Runnable(){
            @覆盖
            公共无效的run(){
                如果(isProvidrActv)
                    originButton.setVisibility(View.VISIBLE);
                其他
                    originButton.setVisibility(View.INVISIBLE);
            }
        });
    }
}
 

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"));

解决方案

The reason that every time isProvidrActive changed the whole activity got regenerated is because I sent the intent using context.startActivity(i) but rather this time we send the intent using contect.sendBroadcast(i) to the ProviderChangeReceiver_updateUI inner class which update only desired part of the UI. So below is the new code.

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);
}


Edit your manifest file to enable the inner class ProviderChangeReceiver_updateUI to listen for broadcast sent by our broadcastReciever, add the following entry to manifest

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

the $ sign indicates inner class. No need to add intent-filters unless required.

And in your ProviderChangeReceiver_updateUI class in the onReceive() method get the value of 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);
            }
        });
    }
}

这篇关于从BroadcastReceiver的抓取方法来更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆