在Android中监控许多片段中的互联网连接

时间:2014-01-31 13:05:52

标签: android broadcastreceiver

我正在使用BroadcastReceiver来监控互联网连接的可能变化:

public class NetworkChangeReceiver extends BroadcastReceiver 

现在,我需要分别检查ViewPager中的每个片段。因为如果用户连接起来,那么它将分别反映在每个片段的UI上。

如果我假设一次创建的片段的最大数量是3,那么我的问题是:

为每个片段定义一个NetworkChangeReceiver实例单独工作是危险的,或者我应该只定义一个?

4 个答案:

答案 0 :(得分:15)

您只需将Observer Pattern结构应用于您的问题。

首先,您需要定义一个必须由Fragments观察的内部类。

我将粘贴一些代码段以说明如何应用。

以下是NetworkChangeReceiverNetworkObservable类。

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        Log.d("NetworkChangeReceiver","Connection status changed");
        getObservable().connectionChanged();
    }

    public static class NetworkObservable extends Observable{
        private static NetworkObservable instance = null;

        private NetworkObservable() {
            // Exist to defeat instantiation.
        }

        public void connectionChanged(){
            setChanged();
            notifyObservers();
        }

        public static NetworkObservable getInstance(){
             if(instance == null){
                 instance = new NetworkObservable();
             }
             return instance;
        }
    }

    public static NetworkObservable getObservable() {
        return NetworkObservable.getInstance();
    }
}

此外,您需要为广播接收器设置清单。以下是如何做到这一点:

<receiver android:name="com.your.package.name.NetworkChangeReceiver" >
    <intent-filter>
       <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
       <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
    </intent-filter>
</receiver>

每当您的连接更改隐式调用onReceive方法时。因此,您需要调用一个通知所有观察者的方法。

对于您的情况,观察者将是Fragment个班级。

我将粘贴另一个代码块以显示示例观察者类。

/*
* If you have memory concerns,
* you need to add your observer while application is resuming
* you need to remove that observer object while application is pausing...
* 
*/
public class FirstFragment extends Fragment implements Observer{        
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
    } 

    @Override
    public void onPause() {
      super.onPause();
      NetworkChangeReceiver.getObservable().deleteObserver(this);
    }

    @Override
    public void onResume() {
      super.onResume();
      NetworkChangeReceiver.getObservable().addObserver(this);
    }

    @Override
    public void update(Observable observable, Object data) {
        // Whenever connection changes, this method will be called so edit your text here
    }
}

您还可以通过向notiftyObservers()方法添加任何参数来传递网络状态。

希望这可能会有所帮助。

答案 1 :(得分:2)

感谢gokhanakkurt的答案,但我不知道为什么在我将'observable'对象变成单身人士之前,没有调用'update'函数!

public class NetworkStateReceiver extends BroadcastReceiver
{
    private static NetworkObservable observable;

    public void onReceive(Context context, Intent intent)
    {
        getObservable().connectionChanged();
    }

    public static class NetworkObservable extends Observable
    {
        public void connectionChanged()
        {
            setChanged();
            notifyObservers();          
        }
    }

    public static NetworkObservable getObservable()
    {
        if(observable == null)
        {
            observable = new NetworkObservable();
        }

        return observable;
    }
}

在我的片段中:

NetworkStateReceiver.getObservable().addObserver(this);

希望你检查并修改你的答案,如果我是正确的或澄清你是否正确。无论如何,你的答案仍然被接受。

答案 2 :(得分:1)

我已经按照以下方式完成了这项工作


<强> FirstFragment.java

public class FirstFragment extends Fragment {

    public static int TYPE_WIFI = 1;
    public static int TYPE_MOBILE = 2;
    public static int TYPE_NOT_CONNECTED = 0;
    TextView noInternetView;

    private BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            String status = getConnectivityStatusString(context);

            if(status.equals("No")) {
                noInternetView.setVisibility(View.VISIBLE);
            } else {
                noInternetView.setVisibility(View.GONE);
            }
        }
    };

    public static String getConnectivityStatusString(Context context) {
        int conn = getConnectivityStatus(context);
        String status = null;
        if (conn == TYPE_WIFI) {
            status = "Wifi";//"Wifi enabled";
        } else if (conn == TYPE_MOBILE) {
            status = "Mobile";//"Mobile data enabled";
        } else if (conn == TYPE_NOT_CONNECTED) {
            status = "No";//"Not connected to Internet";
        }
        return status;
    }

    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                return TYPE_WIFI;

            if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                return TYPE_MOBILE;
        } 
        return TYPE_NOT_CONNECTED;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.first_fragment, container, false);

        IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        getActivity().registerReceiver(myReceiver, filter);

        noInternetView = (TextView)rootView.findViewById(R.id.nointernet);
        .......
        .......

        return rootView;
    }

    public void onDestroyView() {
      super.onDestroyView();
      getActivity().getApplicationContext().unregisterReceiver(myReceiver);
    }
}

<强> first_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#DFE6F5"
    android:orientation="vertical" >

    <TextView
            android:id="@+id/nointernet"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"         
            android:textColor="#FFFFFF" 
            android:textSize="8pt"
            android:text="No internet connection!"
            android:background="#FF0000"
            android:gravity="center"/>

</RelativeLayout>

答案 3 :(得分:0)

也许您可以在static boolean中添加onReceive变量集(连接开启时为true,否则为false)并在onCreateView中检索值或onResume你不同的片段。