在手机跟平板的生产中,除了工厂模式测试PCBA之外,工程模式也是整机测试中很有必要的。通常的做法就是用拨号键拨入一串操作码,发出一个Intent,测试APK中接收这个intent后,启动调用apk的acitivity就可以了。这里说明测试WIFI的activity的大致实现过程。
(1)在工程的AndroidManifest.xml中加上对WIFI的权限申明,否则不让访问
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
(2)页面上放入两个textview控件,第一个控件提示WIFI测试过程,以及以List的形式显示搜索到的WIFI scan result结果;第二个控件提示测试结果是PASS或者FAIL。思路就是启动一个WIFI搜索的线程,里面要分别进行获取WIFI服务、使能WIFI、WIFI扫描、获取WIFI信息、异常和失败处理。检测成功的路径是注册了一个WifiReceiver在收到SCAN_RESULTS_AVAILABLE_ACTION这个intent时显示扫描结果并结束线程。
需要用到的import类
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.view.View;
import android.net.wifi.WifiManager;
import android.net.wifi.ScanResult;
import android.content.BroadcastReceiver;
import android.util.Log;
import java.util.List;
import android.net.wifi.WifiInfo;
该activity类的开头要定义若干所需变量
private TextView mMainView, mTV;
private WifiManager mWifiManager = null;
private boolean mWifiEnabled = false; //WIFI是否使能
WifiReceiver mReceiverWifi = null; //自定义WIFI receiver变量
List<ScanResult> mWifiList; //以List回显ScanResult的变量
StringBuilder mSb = new StringBuilder(); //存储WIFI回显的STRING
private final int WAIT_TIMEOUT_S = 30;
private int mFlag = -1; //WIFI线程运行时的状态标志
static int mCount = 0;
private String strEnableWifi = "";
private String strScanningWifi = "";
private String strSuccess = "";
private String strFaild = "";
private String cannotgetwifiservice = "";
private String cannotgetwifistate = "";
private String wifistateunknown = "";
private boolean mTestResult = false; //WIFI测试的结果
onCreate的主要内容
super.onCreate(savedInstanceState);
setContentView(R.layout.led);
mTV = (TextView)findViewById(R.id.test);
mMainView = (TextView)findViewById(R.id.testinfo);
mFlag = -1; //WIFI扫描的初始化状态
mCount = 0;
strEnableWifi = getString(R.string.WIFI_enable_wifi).toString();
strScanningWifi = getString(R.string.WIFI_scanning_wifi).toString();
strSuccess = getString(R.string.Success).toString();
strFaild = getString(R.string.Fail).toString();
cannotgetwifiservice = getString(R.string.cannotgetwifiservice).toString();
cannotgetwifistate = getString(R.string.cannotgetwifistate).toString();
wifistateunknown = getString(R.string.wifistateunknown).toString();
<pre name="code" class="java"> //新建一个WifiReceiver变量,并用IntentFilter跟SCAN_RESULTS_AVAILABLE_ACTION绑定
mReceiverWifi = new WifiReceiver();
registerReceiver(mReceiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
try{
mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
mSb.append(strEnableWifi + " ... ");
mMainView.setText(mSb);
mFlag = 1; //获得WIFI系统服务
mHandler.postDelayed(task, 200);//延时200ms后,把task插入消息队列等待执行.
}catch(Exception e) {
Log.e(TAG, e.toString());
mMainView.setText(strFaild + ":" + cannotgetwifiservice);
mFlag = 0; //线程退出标志
mHandler.postDelayed(task, 2000);
}
自定义的WIFI receiver实现
class WifiReceiver extends BroadcastReceiver
{
public void onReceive(Context c, Intent intent)
{
mHandler.removeCallbacks(task); //搜到结果就结束线程
mWifiList = mWifiManager.getScanResults();
if (mWifiList == null || mWifiList.size() < 1) {
String strWifiScanNoHotspot = getString(R.string.WIFI_scan_no_hotspot).toString();
mMainView.setText(strWifiScanNoHotspot);
}
else
{
for (int i = 0; i < mWifiList.size(); i++)
{
mSb.append(new Integer(i + 1).toString() + ".");
mSb.append((mWifiList.get(i)).toString());
mSb.append("\n"); //存储一系列搜到的WIFI SSID等详细信息
}
for (ScanResult result : mWifiList)
{
if(result.level >= -80)
{
mTestResult = true; //信号强度大于-80db,就PASS
mTV.setText("PASS");
}
}
mMainView.setText(mSb); //显示ScanResult等消息WIFI INFO
}
}
}
线程退出函数:
private void destroy(int res)
{
mHandler.removeCallbacks(task);
if(mReceiverWifi != null){
unregisterReceiver(mReceiverWifi);//注销掉WifiReceiver
mReceiverWifi = null;
}
Intent mIntent = new Intent();
setResult(res, mIntent);
finish();
}
WIFI的scan线程
private Handler mHandler = new Handler();
private Runnable task = new Runnable() {
public void run() {
Log.e(TAG, "run");
int wifiState;
switch(mFlag){
case 0://EXIT
destroy(-1);
break;
case 1://enable wifi
try{
wifiState = mWifiManager.getWifiState();
}catch(Exception e) {
Log.e(TAG, e.toString());
mMainView.setText(strFaild + ":" + cannotgetwifistate);
mFlag = 0;
mHandler.postDelayed(task, 2000);//如果无法getwifistate,就认为无法打开wifi,设mFlag退出.
break;
}
Log.w(TAG, "getWifiState wifiState=" + wifiState);
if (wifiState == WifiManager.WIFI_STATE_ENABLED)
{
Log.d(TAG, "WIFI is already enabled");
mWifiEnabled = true; //WIFI使能OK
mFlag = 3;//start scan
mHandler.postDelayed(task, 200);
}
else if(wifiState == WifiManager.WIFI_STATE_DISABLED || wifiState == WifiManager.WIFI_STATE_ENABLING)
{
Log.d(TAG, "Turning wifi on...");
if (wifiState == WifiManager.WIFI_STATE_DISABLED)
{
try{
mWifiManager.setWifiEnabled(true); //使能WIFI
}catch(Exception e) {
Log.e(TAG, e.toString());
mMainView.setText(strEnableWifi + " ... " + strFaild + "\n");
mFlag = 0;
mHandler.postDelayed(task, 2000);
break;
}
mFlag = 2;//start scan
mHandler.postDelayed(task, 1000);
}
}
else //wifiState == WifiManager.WIFI_STATE_ENABLING
{
Log.d(TAG, "WIFI Service is unreachable");
mFlag = 2;//start scan
mHandler.postDelayed(task, 1000);
}
break;
case 2://get wifi state for 30 times
mCount ++;
if(mCount < WAIT_TIMEOUT_S)//30s内getwifistate,超时就退出
{
try{
wifiState = mWifiManager.getWifiState();
}catch(Exception e){
Log.e(TAG, e.toString());
mMainView.setText(strFaild + ":" + cannotgetwifistate);
mFlag = 0;
mHandler.postDelayed(task, 2000);
break;
}
if(wifiState == WifiManager.WIFI_STATE_ENABLED) //只有wifi_state_enable才可以scan
{
Log.w(TAG, "Turning wifi on Success.");
mWifiEnabled = true;
mFlag = 3;
mHandler.postDelayed(task, 200);
}
else if (wifiState == WifiManager.WIFI_STATE_UNKNOWN)
{
Log.w(TAG, "Turning wifi on failed.");
mMainView.setText(strEnableWifi + " ... " + (WAIT_TIMEOUT_S -mCount) );
mFlag = 2;
mHandler.postDelayed(task, 1000);
}
}
else//30s内,都无法getwifistate直接退出
{
mSb.append(strFaild + "\n");
mMainView.setText(mSb);
mFlag = 0;//exit
mHandler.postDelayed(task, 2000);
}
break;
case 3://start scan
if (mWifiEnabled == true)
{
mSb.append(strSuccess + "\n\n");
mSb.append(strScanningWifi + " ... \n");
mMainView.setText(mSb);
mWifiManager.startScan();
mFlag = 4;
mHandler.postDelayed(task, 30 * 1000); //30秒内还没有结果就跳到case4
}
else
{
mSb.append(strFaild + "\n");
mMainView.setText(mSb);
mFlag = 0;//exit
mHandler.postDelayed(task, 1000);
}
break;
case 4://超时
String strWifiScanTimeout = getString(R.string.WIFI_scan_timeout).toString();
mSb.append(strWifiScanTimeout + "\n\n");
mMainView.setText(mSb);
mFlag = 0;//exit
mHandler.postDelayed(task, 1000);
break;
default:
break;
}
}
};
=====================================================
几个需要说明的地方:
1.
registerReceiver(receiver, filter);意思是在广播receiver中注册一个filter,监听filter事件.
registerReceiver(mReceiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));的意思是在mReceiverWifi这个广播receiver中注册一个filter,
用来监听WifiManager.SCAN_RESULTS_AVAILABLE_ACTION这个事件.
2.
postDelayed(Runnable r, long delayMillis)延时delayMillis毫秒 将Runnable插入消息列队,Runnable将在handle绑定的线程中运行。post 是立即插入消息列队,当消息列队处理到该消息时才运行
3.
mWifiManager.startScan();
mFlag = 4;
mHandler.postDelayed(task, 30 * 1000); //30秒内还没有结果就跳到case4
WifiManager的startscan() 方法是立即返回的,也就是说这个方法会调用一个扫描wifi信号的线程,那么这个扫描什么时候结束呢?
当调用WifiManager的startscan() 方法,扫描结束后,系统会发出WifiManager.SCAN_RESULTS_AVAILABLE_ACTION广播,因此我们只需要定一个BroadcastRecever接受处理这个广播就行。
4.
定义一个处理扫描结果的BroadcastRecever,当扫描结束后,会调用onReceive()方法。
注意:WifiManager.SCAN_RESULTS_AVAILABLE_ACTION这个监听,如果有可用的wifi,并且没有连任何wifi的话,会自动触发onReceive()方法,一旦连接成功则不在执行。
//wifi扫描结束后的结果处理类
private final class WifiReceiver extends BroadcastReceiver{
//当扫描结束后将会触发该方法
public void onReceive(Context context, Intent intent){
List<ScanResult> scanList = wm.getScanResults();
for(ScanResult scanResult : scanList){
//对扫描结果的操作
}
}
}
注册服务,注销服务。建议分别在OnResume()和OnPause()中注册和注销服务。
public void onResume(){
super.onResume();
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); //注册服务
}
protected void onPause(){
super.onPause();
unregisterReceiver(wifiReceiver); //取消注册
}