Uiautomator2監聽網路狀態,連線指定Wi-Fi
阿新 • • 發佈:2019-01-23
工作中接觸到uiautomator測試框架,從1.0到2.0,改動還是挺大的,1.0是以jar的形式push到手機中,主要是已Eclipse開發為主,到了2.0則是以apk形式安裝到手機中,主要是以Android Studio開發為主,個人感覺還是2.0要強大,而且方便一些。下面直接進入主題,利用uiautomator2實現監聽網路狀態的變化。
1.首先新建一個Android工程,測試部分主要在androidTest包下編寫,
2.在gradle中defaultConfig標籤下增加:
在dependencies下新增testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'
還有就是不要忘記新增Wi-Fi許可權:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
3.在androidTest包下編寫測試用例:
package com.example.macbook.myapplication; import android.content.Context; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.RemoteException; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiDevice; import android.util.Log; import com.example.macbook.myapplication.broadcast.NetWorkConnectChangedReceiver; import com.example.macbook.myapplication.config.AppConfig; import com.example.macbook.myapplication.util.WifiAdminTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class TestEnv { private Context context; private UiDevice device; private WifiAdminTest wifiAdminTest; @Before public void setUp() throws RemoteException { context = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); if (!device.isScreenOn()) { device.wakeUp(); } wifiAdminTest=new WifiAdminTest(context); device.pressHome(); IntentFilter filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); filter.addAction("android.net.wifi.WIFI_STATE_CHANGED"); filter.addAction("android.net.wifi.STATE_CHANGE"); context.registerReceiver(new NetWorkConnectChangedReceiver(),filter); } @Test public void test_ssid() { if(!wifiAdminTest.getWifiManager().isWifiEnabled()){ Log.e("xujun","wifi沒開啟"); wifiAdminTest.openWifi(context); }else{ WifiConfiguration wifiConfiguration = wifiAdminTest.CreateWifiInfo(AppConfig.FLAG_SSID, AppConfig.FLAG_PWD, 3); wifiAdminTest.addNetwork(wifiConfiguration); ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); WifiManager wifiManager = (WifiManager) context .getSystemService(Context.WIFI_SERVICE); String wifiSSID = wifiManager.getConnectionInfo() .getSSID(); if (wifiInfo.isConnected()) { Log.e("TAG = ",wifiSSID + "連線成功"); }else { Log.e("TAG = ",wifiSSID + "連線不成功"); } } } @After public void tearDown(){ } }
廣播類:
package com.example.macbook.myapplication.broadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Parcelable;
import android.util.Log;
/*網路改變監控廣播
*<p>
*監聽網路的改變狀態,只有在使用者操作網路連線開關(wifi,mobile)的時候接受廣播,
*然後對相應的介面進行相應的操作,並將 狀態 儲存在我們的APP裡面
*<p>
*<p>
*Created by xujun
*/
public class NetWorkConnectChangedReceiver extends BroadcastReceiver {
private static final String TAG_1 = "TAG_broad";
public static final String TAG_2 = "xxx";
@Override
public void onReceive(Context context, Intent intent) {
// 這個監聽wifi的開啟與關閉,與wifi的連線無關
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
Log.e(TAG_2, "wifiState" + wifiState);
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLED:
Log.e(TAG_1, "wifi closed");
break;
case WifiManager.WIFI_STATE_DISABLING:
break;
case WifiManager.WIFI_STATE_ENABLING:
break;
case WifiManager.WIFI_STATE_ENABLED:
Log.e(TAG_1, "wifi open");
break;
case WifiManager.WIFI_STATE_UNKNOWN:
break;
default:
break;
}
}
// 這個監聽wifi的連線狀態即是否連上了一個有效無線路由,當上邊廣播的狀態是WifiManager
// .WIFI_STATE_DISABLING,和WIFI_STATE_DISABLED的時候,根本不會接到這個廣播。
// 在上邊廣播接到廣播是WifiManager.WIFI_STATE_ENABLED狀態的同時也會接到這個廣播,
// 當然剛開啟wifi肯定還沒有連線到有效的無線
if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
Parcelable parcelableExtra = intent
.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (null != parcelableExtra) {
NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
NetworkInfo.State state = networkInfo.getState();
boolean isConnected = state == NetworkInfo.State.CONNECTED;// 當然,這邊可以更精確的確定狀態
Log.e(TAG_2, "isConnected" + isConnected);
if (isConnected) {
Log.e(TAG_1, "wifi true");
} else {
Log.e(TAG_1, "wifi false");
}
}
}
// 這個監聽網路連線的設定,包括wifi和移動資料的開啟和關閉。.
// 最好用的還是這個監聽。wifi如果開啟,關閉,以及連線上可用的連線都會接到監聽。見log
// 這個廣播的最大弊端是比上邊兩個廣播的反應要慢,如果只是要監聽wifi,我覺得還是用上邊兩個配合比較合適
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
Log.i(TAG_2, "CONNECTIVITY_ACTION");
NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
if (activeNetwork != null) { // connected to the internet
if (activeNetwork.isConnected()) {
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
// connected to wifi
Log.e(TAG_1, "當前WiFi連線可用 ");
} else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
// connected to the mobile provider's data plan
Log.e(TAG_1, "當前行動網路連線可用 ");
}
} else {
Log.e(TAG_1, "當前沒有網路連線,請確保你已經開啟網路 ");
}
Log.e(TAG_2, "info.getTypeName()" + activeNetwork.getTypeName());
Log.e(TAG_2, "getSubtypeName()" + activeNetwork.getSubtypeName());
Log.e(TAG_2, "getState()" + activeNetwork.getState());
Log.e(TAG_2, "getDetailedState()"
+ activeNetwork.getDetailedState().name());
Log.e(TAG_2, "getDetailedState()" + activeNetwork.getExtraInfo());
Log.e(TAG_2, "getType()" + activeNetwork.getType());
} else { // not connected to the internet
Log.e(TAG_1, "當前沒有網路連線,請確保你已經開啟網路 ");
}
}
}
}
WifiAdmin類:
package com.example.macbook.myapplication.util;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.widget.Toast;
import java.util.List;
public class WifiAdminTest {
// 定義WifiManager物件
private WifiManager mWifiManager;
// 定義WifiInfo物件
private WifiInfo mWifiInfo;
// 掃描出的網路連線列表
private List<ScanResult> mWifiList;
// 網路連線列表
private List<WifiConfiguration> mWifiConfiguration;
// 定義一個WifiLock
WifiLock mWifiLock;
// 構造器
public WifiAdminTest(Context context) {
// 取得WifiManager物件
mWifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
// 取得WifiInfo物件
mWifiInfo = mWifiManager.getConnectionInfo();
}
// 開啟WIFI
public void openWifi(Context context) {
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
Toast.makeText(context,"親,Wifi正在開啟,不用再開了", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"親,Wifi已經開啟,不用再開了", Toast.LENGTH_SHORT).show();
}
}
// 關閉WIFI
public void closeWifi(Context context) {
if (mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(false);
}else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED){
Toast.makeText(context,"親,Wifi已經關閉,不用再關了", Toast.LENGTH_SHORT).show();
}else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING) {
Toast.makeText(context,"親,Wifi正在關閉,不用再關了", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"請重新關閉", Toast.LENGTH_SHORT).show();
}
}
public WifiManager getWifiManager(){
if(mWifiManager!=null){
return mWifiManager;
}
return null;
}
// 檢查當前WIFI狀態
public void checkState(Context context) {
if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING) {
Toast.makeText(context,"Wifi正在關閉", Toast.LENGTH_SHORT).show();
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
Toast.makeText(context,"Wifi已經關閉", Toast.LENGTH_SHORT).show();
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
Toast.makeText(context,"Wifi正在開啟", Toast.LENGTH_SHORT).show();
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
Toast.makeText(context,"Wifi已經開啟", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context,"沒有獲取到WiFi狀態", Toast.LENGTH_SHORT).show();
}
}
// 鎖定WifiLock
public void acquireWifiLock() {
mWifiLock.acquire();
}
// 解鎖WifiLock
public void releaseWifiLock() {
// 判斷時候鎖定
if (mWifiLock.isHeld()) {
mWifiLock.acquire();
}
}
// 建立一個WifiLock
public void creatWifiLock() {
mWifiLock = mWifiManager.createWifiLock("Test");
}
// 得到配置好的網路
public List<WifiConfiguration> getConfiguration() {
return mWifiConfiguration;
}
// 指定配置好的網路進行連線
public void connectConfiguration(int index) {
// 索引大於配置好的網路索引返回
if (index > mWifiConfiguration.size()) {
return;
}
// 連線配置好的指定ID的網路
mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
true);
}
public void startScan(Context context) {
mWifiManager.startScan();
// 得到掃描結果
mWifiList = mWifiManager.getScanResults();
// 得到配置好的網路連線
mWifiConfiguration = mWifiManager.getConfiguredNetworks();
if (mWifiList == null) {
if(mWifiManager.getWifiState()==WifiManager.WIFI_STATE_ENABLED){
Toast.makeText(context,"當前區域沒有無線網路", Toast.LENGTH_SHORT).show();
}else if(mWifiManager.getWifiState()==WifiManager.WIFI_STATE_ENABLING){
Toast.makeText(context,"WiFi正在開啟,請稍後重新點選掃描", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"WiFi沒有開啟,無法掃描", Toast.LENGTH_SHORT).show();
}
}
}
// 得到網路列表
public List<ScanResult> getWifiList() {
return mWifiList;
}
// 檢視掃描結果
public StringBuilder lookUpScan() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < mWifiList.size(); i++) {
stringBuilder
.append("Index_" + new Integer(i + 1).toString() + ":");
// 將ScanResult資訊轉換成一個字串包
// 其中把包括:BSSID、SSID、capabilities、frequency、level
stringBuilder.append((mWifiList.get(i)).toString());
stringBuilder.append("/n");
}
return stringBuilder;
}
// 得到MAC地址
public String getMacAddress() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
}
// 得到接入點的BSSID
public String getBSSID() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
}
// 得到IP地址
public int getIPAddress() {
return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
}
// 得到連線的ID
public int getNetworkId() {
return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
}
// 得到WifiInfo的所有資訊包
public String getWifiInfo() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();
}
// 新增一個網路並連線
public void addNetwork(WifiConfiguration wcg) {
int wcgID = mWifiManager.addNetwork(wcg);
boolean b = mWifiManager.enableNetwork(wcgID, true);
System.out.println("a--" + wcgID);
System.out.println("b--" + b);
}
// 斷開指定ID的網路
public void disconnectWifi(int netId) {
mWifiManager.disableNetwork(netId);
mWifiManager.disconnect();
}
public void removeWifi(int netId) {
disconnectWifi(netId);
mWifiManager.removeNetwork(netId);
}
//然後是一個實際應用方法,只驗證過沒有密碼的情況:
public WifiConfiguration CreateWifiInfo(String SSID, String Password, int Type)
{
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
WifiConfiguration tempConfig = this.IsExsits(SSID);
if(tempConfig != null) {
mWifiManager.removeNetwork(tempConfig.networkId);
}
if(Type == 1) //WIFICIPHER_NOPASS
{
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
if(Type == 2) //WIFICIPHER_WEP
{
config.hiddenSSID = true;
config.wepKeys[0]= "\""+Password+"\"";
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
if(Type == 3) //WIFICIPHER_WPA
{
config.preSharedKey = "\""+Password+"\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
//config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
}
return config;
}
private WifiConfiguration IsExsits(String SSID)
{
List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs)
{
if (existingConfig.SSID.equals("\""+SSID+"\""))
{
return existingConfig;
}
}
return null;
}
}
本例子的廣播是在setUp方法中動態註冊,我們知道動態註冊廣播的特點就是廣播的生命週期跟隨這個類,並且該測試類從setUp()到tearDown()執行時間特別快,導致wifi狀態還沒監聽完就被銷燬了,不過指定的Wi-Fi一定會成功的。