码迷,mamicode.com
首页 > 移动开发 > 详细

android中NetWorkReceive以及获取当前的网络连接状态详解

时间:2015-07-26 00:34:27      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:判断网络状态   android网络状态receiver   测网速   

我们现在APP是断然很难离开网络存活下去,会有很多很频繁的网络操作,请求数据,传递数据等等,所以,我们需要对网络状态有多一点的了解。

首先,假如我们的APP在运行的时候,假如这时候用户掉线了,没有网络了,我们就应该给用户提示,然后用户连上网络了,我们这时候应该也给用户提示,这样他就可以继续玩我们的APP,我们应该怎么做了,没错,就是通过Receiver来实现,因为断网和联网系统都会发送广播,然后,我们可以收到,通过广播去判断当前的网络是否可用,具体代码如下:其中,接受广播需要的action是"android.net.conn.CONNECTIVITY_CHANGE"和"ta.android.net.conn.CONNECTIVITY_CHANGE",我们需要注册该广播接受者的时候添加过滤器,这样他就可以收到了。

import com.iyueju.guanggong.util.NetWorkUtil;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

/**
 * 用于接受网络状态的变化的receiver
 * 
 * @author Administrator
 *
 */
public class NetWorkReceiver extends BroadcastReceiver
{

	private static Boolean networkAvailable = false;// 默认网络状态
	private static com.iyueju.guanggong.util.NetWorkUtil.netType type;
	private final static String ANDROID_NET_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
	public final static String TA_ANDROID_NET_CHANGE_ACTION = "ta.android.net.conn.CONNECTIVITY_CHANGE";
	private static NetWorkReceiver receiver;

	private NetWorkReceiver()
	{
		super();
	}

	public static NetWorkReceiver getNetWorkReceiver()
	{
		// TODO Auto-generated constructor stub
		if (receiver == null)
		{
			synchronized (NetWorkReceiver.class)
			{
				if (receiver == null)
				{
					receiver = new NetWorkReceiver();
				}
			}
		}
		return receiver;
	}

	@Override
	public void onReceive(Context context, Intent intent)
	{
		// TODO Auto-generated method stu
		receiver = NetWorkReceiver.this;
		if (intent.getAction().equalsIgnoreCase(ANDROID_NET_CHANGE_ACTION)
		    || intent.getAction().equalsIgnoreCase(TA_ANDROID_NET_CHANGE_ACTION))
		{
			Log.i("Main", "有收到网络连接的相关讯息");
			if (!NetWorkUtil.isNetworkAvailable(context) && networkAvailable == true)
			{
				Log.i("Main", "断开了网络");
				networkAvailable = false;
				Toast.makeText(context, "网络不可用", 1).show();
			} else if (NetWorkUtil.isNetworkAvailable(context) && networkAvailable == false)
			{
				Log.i("Main", "网络连接成功");
				networkAvailable = true;
				type = NetWorkUtil.getAPNType(context);
				Toast.makeText(context, "网络连接成功", 1).show();
			}
		}
	}

	/**
	 * 注册网络监听
	 * 
	 * @param context
	 */
	public static void registerNetworkStateReceiver(Context context)
	{
		Intent intent = new Intent();
		intent.setAction(TA_ANDROID_NET_CHANGE_ACTION);
		context.sendBroadcast(intent);
	}

	/**
	 * 显示当前网络状态
	 * 
	 * @param context
	 */
	public static void checkNetWorkState(Context context)
	{
		Intent intent = new Intent();
		intent.setAction(TA_ANDROID_NET_CHANGE_ACTION);
		context.sendBroadcast(intent);
	}

	/**
	 * 注销网络监听
	 * 
	 * @param context
	 */
	public static void unRegisterNetworkStateReceiver(Context context)
	{
		if (receiver != null)
		{
			try
			{
				context.getApplicationContext().unregisterReceiver(receiver);
			} catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	public static Boolean isNetWorkAvailable()
	{
		return networkAvailable;
	}

	public static com.iyueju.guanggong.util.NetWorkUtil.netType getNetWorkType()
	{
		return type;
	}

}

注册监听:

/**
	 * 注册监听
	 */
	private void registerMessageReceiver()
	{
		// TODO Auto-generated method stub
		NetWorkReceiver receiver = NetWorkReceiver.getNetWorkReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		filter.addAction("android.gzcpc.conn.CONNECTIVITY_CHANGE");
		registerReceiver(receiver, filter);

	}


然后,需要在不适用APP的时候注销

则是:

	unregisterReceiver(NetWorkReceiver.getNetWorkReceiver());


然后,假如是我们的APP中,我们通过一些view的点击或者其他的事件触发一些网络操作,为了避免一些错误,我们需要先去判断当前网络是否可用,当前连接的网络不是是wifi(为用户考虑)以及当前是否有网络连接,还有当前的网速是多大,是否适合我们的操作等等。

下面是具体的代码实现:

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import com.iyueju.guanggong.constant.APPConstant;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

/**
 * 网络工具类
 * 
 * @author Administrator
 *
 */
public class NetWorkUtil
{
	// Private fields
	private static final String TAG = NetWorkUtil.class.getSimpleName();
	private static final int EXPECTED_SIZE_IN_BYTES = 1048576;// 1MB 1024*1024
	private static final double BYTE_TO_KILOBIT = 0.0078125;
	private static final double KILOBIT_TO_MEGABIT = 0.0009765625;

	private static Handler mHandler;
	public static int timer;

	// 网络状态,连接wifi,cmnet是直连互联网的,cmwap是需要代理,noneNet是无连接的
	// 一速度来说:wifi > cmnet >cmwap > noneNet
	public static enum netType
	{
		wifi, CMNET, CMWAP, noneNet
	}

	/**
	 * 网络是否可用
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isNetworkAvailable(Context context)
	{
		// 获取网络manager
		ConnectivityManager mgr = (ConnectivityManager) context
		    .getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo[] info = mgr.getAllNetworkInfo();

		// 遍历所有可以连接的网络
		if (info != null)
		{
			for (int i = 0; i < info.length; i++)
			{
				if (info[i].getState() == NetworkInfo.State.CONNECTED)
				{
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 判断是否有网络连接
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isNetworkConnected(Context context)
	{
		if (context != null)
		{
			ConnectivityManager mConnectivityManager = (ConnectivityManager) context
			    .getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
			if (mNetworkInfo != null)
			{
				return mNetworkInfo.isAvailable();
			}
		}
		return false;
	}

	/**
	 * 判断WIFI网络是否可用
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isWifiConnected(Context context)
	{
		if (context != null)
		{
			ConnectivityManager mConnectivityManager = (ConnectivityManager) context
			    .getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo mWiFiNetworkInfo = mConnectivityManager
			    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			if (mWiFiNetworkInfo != null)
			{
				return mWiFiNetworkInfo.isAvailable();
			}
		}
		return false;
	}

	/**
	 * 判断MOBILE网络是否可用
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isMobileConnected(Context context)
	{
		if (context != null)
		{
			ConnectivityManager mConnectivityManager = (ConnectivityManager) context
			    .getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo mMobileNetworkInfo = mConnectivityManager
			    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
			if (mMobileNetworkInfo != null)
			{
				return mMobileNetworkInfo.isAvailable();
			}
		}
		return false;
	}

	/**
	 * 获取当前网络连接的类型信息
	 * 
	 * @param context
	 * @return
	 */
	public static int getConnectedType(Context context)
	{
		if (context != null)
		{
			ConnectivityManager mConnectivityManager = (ConnectivityManager) context
			    .getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
			if (mNetworkInfo != null && mNetworkInfo.isAvailable())
			{
				return mNetworkInfo.getType();
			}
		}
		return -1;
	}

	/**
	 * 
	 * @author 白猫
	 * 
	 *         获取当前的网络状态 -1:没有网络 1:WIFI网络2:wap 网络3:net网络
	 * 
	 * @param context
	 * 
	 * @return
	 */
	public static netType getAPNType(Context context)
	{
		ConnectivityManager connMgr = (ConnectivityManager) context
		    .getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
		if (networkInfo == null)
		{
			return netType.noneNet;
		}
		int nType = networkInfo.getType();

		if (nType == ConnectivityManager.TYPE_MOBILE)
		{
			if (networkInfo.getExtraInfo().toLowerCase().equals("cmnet"))
			{
				return netType.CMNET;
			}

			else
			{
				return netType.CMWAP;
			}
		} else if (nType == ConnectivityManager.TYPE_WIFI)
		{
			return netType.wifi;
		}
		return netType.noneNet;

	}

	/**
	 * 测试网速
	 * 
	 * @param handler
	 */
	public static void textSpeed(Handler handler)
	{
		mHandler = handler;
		new Thread(mWorker).start();
	}

	/**
	 * Our Slave worker that does actually all the work
	 */
	private static final Runnable mWorker = new Runnable()
	{

		@Override
		public void run()
		{
			InputStream stream = null;
			try
			{
				int bytesIn = 0;
				String downloadFileUrl = "http://120.24.237.77/test";
				long startCon = System.currentTimeMillis();
				URL url = new URL(downloadFileUrl);
				URLConnection con = url.openConnection();
				con.setUseCaches(false);
				long connectionLatency = System.currentTimeMillis() - startCon;
				stream = con.getInputStream();

				Message msgUpdateConnection = Message.obtain(mHandler,
				    APPConstant.MSG_UPDATE_CONNECTION_TIME);
				msgUpdateConnection.arg1 = (int) connectionLatency;
				mHandler.sendMessage(msgUpdateConnection);

				long start = System.currentTimeMillis();
				int currentByte = 0;
				long updateStart = System.currentTimeMillis();
				long updateDelta = 0;
				int bytesInThreshold = 0;

				while ((currentByte = stream.read()) != -1)
				{
					bytesIn++;
					bytesInThreshold++;
					if (updateDelta >= APPConstant.UPDATE_THRESHOLD)
					{
						int progress = (int) ((bytesIn / (double) EXPECTED_SIZE_IN_BYTES) * 100);
						Message msg = Message.obtain(mHandler, APPConstant.MSG_UPDATE_STATUS,
						    calculate(updateDelta, bytesInThreshold));
						msg.arg1 = progress;
						msg.arg2 = bytesIn;
						mHandler.sendMessage(msg);
						// Reset
						updateStart = System.currentTimeMillis();
						bytesInThreshold = 0;
					}
					updateDelta = System.currentTimeMillis() - updateStart;
				}

				long downloadTime = (System.currentTimeMillis() - start);
				// Prevent AritchmeticException
				if (downloadTime == 0)
				{
					downloadTime = 1;
				}

				Message msg = Message.obtain(mHandler, APPConstant.MSG_COMPLETE_STATUS,
				    calculate(downloadTime, bytesIn));
				msg.arg1 = bytesIn;
				mHandler.sendMessage(msg);
			} catch (MalformedURLException e)
			{
				Log.e(TAG, e.getMessage());
			} catch (IOException e)
			{
				Log.e(TAG, e.getMessage());
			} finally
			{
				try
				{
					if (stream != null)
					{
						stream.close();
					}
				} catch (IOException e)
				{
					// Suppressed
				}
			}

		}
	};

	/**
	 * 
	 * 1 byte = 0.0078125 kilobits 1 kilobits = 0.0009765625 megabit
	 * 
	 * @param downloadTime
	 *          in miliseconds
	 * @param bytesIn
	 *          number of bytes downloaded
	 * @return SpeedInfo containing current speed
	 */
	private static SpeedInfo calculate(final long downloadTime, final long bytesIn)
	{
		SpeedInfo info = new SpeedInfo();
		// from mil to sec
		long bytespersecond = (bytesIn / downloadTime) * 1000;
		double kilobits = bytespersecond * BYTE_TO_KILOBIT;
		double megabits = kilobits * KILOBIT_TO_MEGABIT;
		info.downspeed = bytespersecond;
		info.kilobits = kilobits;
		info.megabits = megabits;

		return info;
	}

	/**
	 * Transfer Object
	 * 
	 * @author devil
	 *
	 */
	public static class SpeedInfo
	{
		public double kilobits = 0;
		public double megabits = 0;
		public double downspeed = 0;
	}
}


其中,涉及到了四个其他常量是:

	public static final int MSG_UPDATE_STATUS = 0;
	public static final int MSG_UPDATE_CONNECTION_TIME = 1;
	public static final int MSG_COMPLETE_STATUS = 2;
	public static final int UPDATE_THRESHOLD = 300;


注意:使用的时候需要加入一些权限,

,比如查看wifi状态等,具体请看:http://blog.csdn.net/liweijie_chengxuyuan/article/details/41822883

版权声明:本文为博主原创文章,未经博主允许不得转载。

android中NetWorkReceive以及获取当前的网络连接状态详解

标签:判断网络状态   android网络状态receiver   测网速   

原文地址:http://blog.csdn.net/liweijie_chengxuyuan/article/details/47060825

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!