android 通过Service和Receiver来监听网络状态
注:本内容部分来自网络
?
需要在Activity中得到网络状态,就是需要在接收到网络状态改变的广播的时候,要能够与Activity进行交互,通知Activity当前的网络状态,这就需要写一个Service,并且绑定到Activity,把广播监听到的实时的网络状态返回给Activity。
public class ReceiveMsgService extends Service {// 实时监听网络状态改变 private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { Timer timer = new Timer(); timer.schedule(new QunXTask(getApplicationContext()), new Date()); } } };public interface GetConnectState { public void GetState(boolean isConnected); // 网络状态改变之后,通过此接口的实例通知当前网络的状态,此接口在Activity中注入实例对象 } private GetConnectState onGetConnectState; public void setOnGetConnectState(GetConnectState onGetConnectState) { this.onGetConnectState = onGetConnectState; } private Binder binder = new MyBinder(); private boolean isContected = true; @Override public IBinder onBind(Intent intent) { return binder; } @Override public void onCreate() {// 注册广播 IntentFilter mFilter = new IntentFilter(); mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); // 添加接收网络连接状态改变的Action registerReceiver(mReceiver, mFilter); } class QunXTask extends TimerTask { private Context context; public QunXTask(Context context) { this.context = context; } @Override public void run() { if (isConnectNet()) { isContected = true; } else { isContected = false; } if (onGetConnectState != null) { onGetConnectState.GetState(isContected); // 通知网络状态改变 } } /** * 判断是否连通网络 * * @return */ private boolean isConnectNet() { ConnectivityManager connectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo Mobile = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); NetworkInfo Wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (Mobile.getState().equals(State.DISCONNECTED) && Wifi.getState().equals(State.DISCONNECTED)) { return false; } return true; } } public class MyBinder extends Binder { public ReceiveMsgService getService() { return ReceiveMsgService.this; } } @Override public void onDestroy() { super.onDestroy(); unregisterReceiver(mReceiver); // 删除广播 } }接下来在Activity中,绑定服务
public class MainActivity extends Activity {protected String TAG = "mylog";ReceiveMsgService receiveMsgService;private boolean conncetState = true; // 记录当前连接状态,因为广播会接收所有的网络状态改变wifi/3g等等,所以需要一个标志记录当前状态@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.page_main);bind();}private void bind() {Intent intent = new Intent(MainActivity.this, ReceiveMsgService.class);bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);}private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {receiveMsgService = ((ReceiveMsgService.MyBinder) service).getService();receiveMsgService.setOnGetConnectState(new GetConnectState() { // 添加接口实例获取连接状态@Overridepublic void GetState(boolean isConnected) {if (conncetState != isConnected) { // 如果当前连接状态与广播服务返回的状态不同才进行通知显示conncetState = isConnected;if (conncetState) {// 已连接handler.sendEmptyMessage(1);} else {// 未连接handler.sendEmptyMessage(2);}}}});}};private void unbind() {if (receiveMsgService != null ) {unbindService(serviceConnection);Log.i("mylog", "执行unbind()");}}Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 1:// 已连接Toast.makeText(MainActivity.this, "网络已经连接" ,Toast.LENGTH_LONG).show();break;case 2:// 未连接Toast.makeText(MainActivity.this, "网络未连接" ,Toast.LENGTH_LONG).show();break;default:break;};};};@Overrideprotected void onDestroy(){// TODO Auto-generated method stubsuper.onDestroy();unbind();}}?
?
当然也可以直接在Activity中注册一个广播,在接收到广播之后进行判断,这种情况就稍简单些,Activity可以直接访问到广播中的一些变量;最后,需要添加一些权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
?
?单纯用广播来监控网络状态,前提是不需要与Activity通信
private ConnectivityManager connectivityManager;???private NetworkInfo info; @Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubString action = intent.getAction(); if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { Log.d("mylog", "网络状态已经改变"); connectivityManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE); info = connectivityManager.getActiveNetworkInfo(); if(info != null && info.isAvailable()) { String name = info.getTypeName(); Log.d("mylog", "当前网络名称:" + name); } else { Log.d("mylog", "没有可用网络"); } }}?
如果分别需要得到3G和WIFI连接方式如下:
?
ConnectivityManager connectMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);//3GNetworkInfo mobNetInfo = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);//WIFINetworkInfo wifiNetInfo = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
?
最后别忘了在XML中注册广播,当然也可以在代码中注册广播。
?
<receiver android:name="com.yooeee.freepass.service.NetworkReceiver" android:label="NetworkConnection" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver>
?
?