在实际开发中,我们可能会遇到需要判断当前Android设备的网络等方面的需求,这里所说的网络是指WiFi和手机移动网络,也就是指手机的上网方式。最近有空,就来总结有关Android网络方面的。废话不多说,速度进入下文!
一、前言。
正文开始之前,先了解几个类。
1.ConnectivityManager。
Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes.
Get an instance of The primary responsibilities of this class are to:
Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)
Send broadcast intents when network connectivity changes
Attempt to "fail over" to another network when connectivity to a network is lost
Provide an API that allows applications to query the coarse-grained or fine-grained state of the available networks
Provide an API that allows applications to request and select networks for their data traffic
简单翻译:
这个类,用来答复网络连接状态的查询。它也通知应用当网络连接发生改变时。得到这个类的实例通过Context.getSystemService(Context.CONNECTIVITY_SERVICE)。
这个类的主要职责:
(1).监控网络连接(WIFI ,GPRS , UMTS 等);
(2).当网络连接发生改变时,发生广播;
(3).当网络连接丢失时,尝试连接另一个网络;
(4).提供了一个接口允许应用程序用来查询可用网络的粗粒度和细粒度;
(5).提供了一个接口允许应用程序请求和选择网络进行数据通信。
2.NetworkInfo。
Describes the status of a network interface.
Use getActiveNetworkInfo() to get an instance that represents the current network connection.
描述网络接口的状态。
使用 getActiveNetworkInfo() 来获取当前网络连接的实例。
(1). getType()
报告此NetworkInfo中所属的网络类型。
返回值可为:TYPE_MOBILE, TYPE_WIFI, TYPE_WIMAX, TYPE_ETHERNET, TYPE_BLUETOOTH。
可以看出还可以监控蓝牙的连接状态。
(2).isAvailable()
指示是否可以进行网络连接。该设备不在任何此类网络类型覆盖范围内;该设备在除了家庭网络的以外的网络上(例如,漫游),并且数据漫游已被禁止;设备的无线电被关闭,例如开启了飞行模式。
返回值 如果网络可用,返回true,否则返回false。
(3).isConnected()
指示网络是否连接并且可以建立连接并传递数据。在数据传递之前,总要调用它。
返回值 如果网络连接存在,返回true,否则返回false。
(4).isConnectedOrConnecting()
指示网络是否连接或者正在建立过程中。这对于需要执行网络相关的任何操作而不是读或者写数据的应用程序来说很有用。对于后者,调用isConnected()替代,保证网络完全可用。
返回 如果网络连接存在或者正在建立过程中,返回true,否则返回false。
(5).getTypeName()
返回一个可读的名称用来描述网络的类型,例如“WIFI”和“MOBILE”。
(6).int getSubtype ()
返回描述网络子类型的网络类型特定整形。
(7).NetworkInfo getNetworkInfo (int networkType)
6.0已经废弃了该方法。该方法不支持相同类型的多个连接网络。可以使用getAllNetworks() 和etNetworkInfo(android.net.Network)代替。
返回特定网络类型的连接状态信息。使用时,需要添加权限‘ACCESS_NETWORK_STATE’。
Provides access to information about the telephony services on the device. Applications can use the methods in this class to
determine telephony services and states, as well as to access some types of subscriber information. Applications can
also register a listener to receive notification of telephony state changes.
You do not instantiate this class directly; instead, you retrieve a reference to an instance through
Context.getSystemService(Context.TELEPHONY_SERVICE). The returned TelephonyManager will use the default subscription for all
calls. To call an API for a specific subscription, use createForSubscriptionId(int).
e.g. telephonyManager = defaultSubTelephonyManager.createForSubscriptionId(subId);
Note that access to some telephony information is permission-protected. Your application cannot access the protected
information unless it has the appropriate permissions declared in its manifest file. Where permissions apply,
they are noted in the the methods through which you access the protected information.
DATA_CONNECTING----数据连接状态为当前正在设置数据连接;
DATA_CONNECTED----数据连接状态为连接状态,IP流量应该可用;
DATA_SUSPENDED----数据连接状态为暂停状态,连接已启动,但IP流量暂时不可用,例如,在2G网络中,当语音呼叫到达时,数据活动可能被停止;
This class provides the primary API for managing all aspects of Wi-Fi connectivity. Get an instance
of this class by calling Context.getSystemService(Context.WIFI_SERVICE). It deals with several categories of items:
The list of configured networks. The list can be viewed and updated, and attributes of individual entries can be modified.
The currently active Wi-Fi network, if any. Connectivity can be established or torn down,
and dynamic information about the state of the network can be queried.
Results of access point scans, containing enough information to make decisions about what access point to connect to.
It defines the names of various Intent actions that are broadcast upon any sort of change in Wi-Fi state.
This is the API to use when performing Wi-Fi specific operations. To perform operations that pertain to
network connectivity at an abstract level, use ConnectivityManager.
简单翻译
网络的SSID。可以是ASCII字符串,必须用双引号引起来(例如,“mynetwork”,或一个字符串进制数字,不加引号(例如,01a243f405)。
<manifest ...>
<uses-feature android:name="android.hardware.wifi" />
...
</manifest>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.test.MainActivity" >
<Button
android:id="@+id/btn1"
android:text="开启wifi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/btn2"
android:text="关闭wifi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
运行后的效果图,如下所示,有两个按钮,一个是打开WiFi,另一个是关闭WiFi。
public class MainActivity extends Activity {
private WifiManager wifiManager;
private String tag="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
findViewById(R.id.btn1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!wifiManager.isWifiEnabled())
{
wifiManager.setWifiEnabled(true);
Log.e(tag, "正在打开wifi");
}
}
});
findViewById(R.id.btn2).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (wifiManager.isWifiEnabled())
{
wifiManager.setWifiEnabled(false);
Log.e(tag, "正在关闭wifi");
}
}
});
}
}
打开、关闭WiFi需要几秒的执行过程。代码比较简单,就不多说了!下面是应用运行的视频,
public class SecondActivity extends Activity {
TextView tv;
Button btn;
ConnectivityManager mConnectivityManager;
private static final String TAG="SecondActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
tv=(TextView)findViewById(R.id.tv);
btn=(Button)findViewById(R.id.btn1);
mConnectivityManager =(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);//获取一个ConnectivityManager对象
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getNetworkInfo();
}
});
}
/**
* 获取网络信息
*/
private void getNetworkInfo(){
NetworkInfo info=(NetworkInfo)mConnectivityManager.getActiveNetworkInfo();
if(info!=null){
int type=info.getType();
Log.e(TAG, "type="+type+", typeName="+info.getTypeName());
tv.setText(info.getTypeName());
if(info.isConnected()){
switch (type) {
case ConnectivityManager.TYPE_WIFI:
break;
case ConnectivityManager.TYPE_MOBILE:
break;
default:
break;
}
}
}else{
Log.e(TAG, "无连接");
}
}
}
public static int getNetworkClass(int networkType) {
switch (networkType) {
case NETWORK_TYPE_GPRS:
case NETWORK_TYPE_GSM:
case NETWORK_TYPE_EDGE:
case NETWORK_TYPE_CDMA:
case NETWORK_TYPE_1xRTT:
case NETWORK_TYPE_IDEN:
return NETWORK_CLASS_2_G;
case NETWORK_TYPE_UMTS:
case NETWORK_TYPE_EVDO_0:
case NETWORK_TYPE_EVDO_A:
case NETWORK_TYPE_HSDPA:
case NETWORK_TYPE_HSUPA:
case NETWORK_TYPE_HSPA:
case NETWORK_TYPE_EVDO_B:
case NETWORK_TYPE_EHRPD:
case NETWORK_TYPE_HSPAP:
return NETWORK_CLASS_3_G;
case NETWORK_TYPE_LTE:
return NETWORK_CLASS_4_G;
default:
return NETWORK_CLASS_UNKNOWN;
}
}
该方法提供的移动网络类型有16种(其中有一种是隐藏类型-NETWORK_TYPE_GSM,并且笔者的Api版本是21(5.0.1))。至于该方法为何是隐藏的,笔者认为,该方法还不稳定,Api版本会持续更新。
public void getNetworkClass(int networkType){
Class c;
try {
c = Class.forName("android.telephony.TelephonyManager");
Method m = c.getMethod("getNetworkClass", new Class[] {int.class});
Object o = m.invoke(null, new Object[]{networkType});
Log.e(TAG, o.toString());
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
其中,参数int networkType值为NetworkInfo.getSubtype()。下面是运行后,手机切换移动网络后的log截图,