android手机状态栏上wifi图标的显示流程

本文详细解析了Android系统中Wi-Fi图标更新的工作流程,从广播接收器到图标更新的具体实现,包括RSSI值的获取与处理,以及Wi-Fi信息的获取方法。

状态栏上的图标显示是属于SYSTEM-UI的内容范畴;显示图标是在:SignalClusterView.Java文件中

public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,

boolean activityIn, boolean activityOut, String description) {

mWifiVisible = statusIcon.visible && !mBlockWifi;

mWifiStrengthId = statusIcon.icon;

mWifiActivityId = getWifiActivityId(activityIn, activityOut);

mWifiDescription = statusIcon.contentDescription;

apply();//这里将会显示更新后的图片

}

代码是怎么一步一步调用到setWifiIndicators
这个函数来显示图标的呢?

1. 系统定义了一个广播接收器:NetworkControllerImpl extends BroadcastReceiver

在它的onReceive()函数里会处理所有的状态栏上的图标更新:

NetworkControllerImpl.java会定义mWifiSignalController

if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||

action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {}

else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {}

else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {}

else {

// No sub id, must be for the wifi.

mWifiSignalController.handleBroadcast(intent); //这里处理WifiSignal的变化

}

{{{handler.post这个函数的作用是把Runnable里面的run方法里面的这段代码发送到消息队列中,等待运行。

如果handler是以UI线程消息队列为参数构造的,那么是把run里面的代码发送到UI线程中,等待UI线程运行这段代码。

如果handler是以子线程线程消息队列为参数构造的,那么是把run里面的代码发送到子线程中,等待子线程运行这段代码。

具体可以查看handle的理解}}}

2.在WifiSignalController.java会定义mWifiTracker WifiStatusTracker里有对WifiManager.RSSI_CHANGED_ACTION 这个消息的处理:

else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {

// Default to -200 as its below WifiManager.MIN_RSSI.

rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);

level = WifiManager.calculateSignalLevel(rssi, 5);

}

3.在WifiSignalController.java 中的函数:notifyListeners 会调用最上面的setWifiIndicators这个CALLBACK函数,来实现更新WIFI图标:

public void notifyListeners(SignalCallback callback) {

callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,

ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,

wifiDesc);

}

同时,在WifiSignalController.java中还引用了WifiIcons.java中定义的各种WIFI图标

 

那么WIFI的常规信息如何获取呢?

WifiManager wifi_service = (WifiManager)getSystemService(WIFI_SERVICE);

WifiInfo wifiInfo = wifi_service.getConnectionInfo();

其中wifiInfo有以下的方法:

wifiinfo.getBSSID();

wifiinfo.getSSID();

wifiinfo.getIpAddress();获取IP地址。

wifiinfo.getMacAddress();获取MAC地址。

wifiinfo.getNetworkId();获取网络ID。

wifiinfo.getLinkSpeed();获取连接速度,可以让用户获知这一信息。

wifiinfo.getRssi();获取RSSI,RSSI就是接受信号强度指示。

这里得到信号强度就靠wifiinfo.getRssi()这个方法。得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好,-50到-70表示信号偏差,小于-70表示最差,有可能连接不上或者掉线,一般Wifi已断则值为-200。当RSSI=0时,表示信号强度为0

获取wifi信号强度:

privateintobtainWifiInfo() {// Wifi的连接速度及信号强度:intstrength =0;        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);// WifiInfo wifiInfo = wifiManager.getConnectionInfo();WifiInfo info = wifiManager.getConnectionInfo();if(info.getBSSID() !=null) {// 链接信号强度,5为获取的信号强度值在5以内strength = WifiManager.calculateSignalLevel(info.getRssi(),5);// 链接速度intspeed = info.getLinkSpeed();// 链接速度单位String units = WifiInfo.LINK_SPEED_UNITS;// Wifi源名称String ssid = info.getSSID();        }//        return info.toString();returnstrength;    }

广播接收信号强度变化的处理:

publicBroadcastReceiver rssiReceiver =newBroadcastReceiver() {@OverridepublicvoidonReceive(Context context, Intent intent) {ints = obtainWifiInfo();            tv.setText(s+"");        }    };

注册广播:

registerReceiver(rssiReceiver,newIntentFilter(WifiManager.RSSI_CHANGED_ACTION));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值