在Android手机上,通过“设置”-“关于手机”-“状态”-“信号强度”可以查看到手机的信号强度,显示出如“-87 dBm 13 asu”这样的数据。ASU与dBm之间的关系是:dBm=-113+(2*ASU)。
在你手机屏幕上方显示的信号条永远不会是最好的方法来确定你手机的信号,无论你用什么手机都一样。Android也是,用很粗的条来展示很强的信号,但这些条仅仅表示最高的信号。或许你并不熟悉,信号通常是以dBm度量的。dBm是每毫瓦特的电磁波产生的功率。-60dBm的信号接近完美,-112dBm就很容易掉线,如果你在 -87dBm以上,Android会显示一个4格的满信号。
android界面UI信号显示是通过RIL对通讯模块发送AT命令来实现的,如AT+CSQ,我们查看一般可以通过 logcat -b radio来获取一些RIL的实时信息,可以通过关键字“CSQ”查找radio.log,查看手机信号强度。log如:AT< +CSQ: 14,99 这里的14就是ASU值,在4.0源码中有SignalStrength.Java类,其中有ASU值转换为几格信号的方法:
- 403
- public int getGsmLevel() {
- 404
- int level;
- 405
-
- 406
-
- 407
-
- 408
-
- 409
-
- 410
- int asu = getGsmSignalStrength();
- 411
- if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- 412
- else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
- 413
- else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
- 414
- else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
- 415
- else level = SIGNAL_STRENGTH_POOR;
- 416
- if (DBG) log("getGsmLevel=" + level);
- 417
- return level;
- 418
- }
-----------------------------------------------------------------------------------------
以下是从网上找到的相关资料。
在RILConstants.java中找到:
- int RIL_UNSOL_SIGNAL_STRENGTH = 1009;
在RIL.java中找到与其相关的代码:
- private void processUnsolicited (Parcel p) {
- …….
- case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
- …..
- case RIL_UNSOL_SIGNAL_STRENGTH:
-
-
- if (RILJ_LOGV) unsljLogvRet(response, ret);
-
- if (mSignalStrengthRegistrant != null) {
- mSignalStrengthRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
在RIL的父类BaseCommands.java中找到:
- public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
- "white-space:pre"> mSignalStrengthRegistrant = new Registrant (h, what, obj);
- }
再找其调用者(GsmServiceStateTracker.java):
- public GsmServiceStateTracker(GSMPhone phone) {
- super();
-
- ……
- cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
- ……
GsmServiceStateTracker自己处理上报上来的信号强度信息:
- case EVENT_SIGNAL_STRENGTH_UPDATE:
-
-
-
- ar = (AsyncResult) msg.obj;
-
-
-
- dontPollSignalStrength = true;
-
- onSignalStrengthResult(ar);
- break;
函数onSignalStrengthResult负责处理:
- private void onSignalStrengthResult(AsyncResult ar) {
- SignalStrength oldSignalStrength = mSignalStrength;
- int rssi = 99;
-
-
- if (ar.exception != null) {
-
-
- setSignalStrengthDefaultValues();
- } else {
- int[] ints = (int[]) ar.result;
-
-
-
- if (ints.length != 0) {
- rssi = ints[0];
- } else {
- Log.e(LOG_TAG, “Bogus signal strength response”);
- rssi = 99;
- }
- }
-
-
- mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
- -1, -1, -1, true);
-
-
- if (!mSignalStrength.equals(oldSignalStrength)) {
- try {
-
- phone.notifySignalStrength();
- } catch (NullPointerException ex) {
- log(“onSignalStrengthResult()Phone already destroyed:”+ex
- +“SignalStrength not notified”);
- }
- }
- }
若没发生异常,且值产生变化,则调用 phone.notifySignalStrength通知(见GSMPhone.java):
- notifySignalStrength() {
- mNotifier.notifySignalStrength(this);
- }
-
-
- DefaultPhoneNotifier(DefaultPhoneNotifier.java)通知注册者:
-
-
- public void notifySignalStrength(Phone sender) {
- try {
- mRegistry.notifySignalStrength(sender.getSignalStrength());
- } catch (RemoteException ex) {
-
- }
- }
这个注册者来自:
- DefaultPhoneNotifier() {
- mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry));
- }
TelephonyRegistry.java,TelephonyRegistry是ITelephonyRegistry.Stub的子类,作为service运行在system_server进程中,它会通知注册者。上面的DefaultPhoneNotifier运行在com.android.phone进程中,当信号强度值变化时,通过Service进行通知(service被感兴趣的注册者调用了listen,添加了回调函数。
- public void notifySignalStrength(SignalStrength signalStrength) {
- if (!checkNotifyPermission(“notifySignalStrength()”)) {
- return;
- }
- synchronized (mRecords) {
- mSignalStrength = signalStrength;
- for (int i = mRecords.size()–1;
- i >= 0;
- i–){
- Record r = mRecords.get(i);
- if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
- sendSignalStrength(r, signalStrength);
- }
- if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
- try {
- int gsmSignalStrength = signalStrength.getGsmSignalStrength();
- r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
- : gsmSignalStrength));
- } catch (RemoteException ex) {
- remove(r.binder);
- }
- }
- }
- }
- broadcastSignalStrengthChanged(signalStrength);
- }
在TelephonyManager.java中提供了API,应用程序可以监听各种事件,实际上它将感兴趣的监听者作为一条记录添加到service一侧的列表(跨进程)中,当有变化时,调用它们提供的回调函数,通知(跨进程)这些注册者。
TelephonyManager.java中的listen函数如下:
- public void listen(PhoneStateListener listener, int events) {
- String pkgForDebug = mContext != null ? mContext.getPackageName() : “”;
- try {
- Boolean notifyNow = (getITelephony() != null);
- mRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
- } catch (RemoteException ex) {
-
- } catch (NullPointerException ex) {
-
- }
- }
其中回调对象实例listener.callback来自于PhoneStateListener.java嵌套定义及其实例,这样,当TelephonyRegistry.java调用回调函数时,就调用到listener.callback,进而发送消息给PhoneStateListener.java中的mHandler,由其处理,进而由其子类去处理。
在StatusBarPolicy.java中,注册了下面要监听处理的事件。第二个为信号强度:
- ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE)). listen(mPhoneStateListener,
- PhoneStateListener.LISTEN_SERVICE_STATE
- |PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
- |PhoneStateListener.LISTEN_CALL_STATE
- |PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
- |PhoneStateListener.LISTEN_DATA_ACTIVITY);
处理者为:
- private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
- @Override
- public void onSignalStrengthsChanged(SignalStrength signalStrength) {
- mSignalStrength = signalStrength;
- updateSignalStrength();
- }
- }
在StatusBarPolicy的updateSignalStrength函数中,将根据得到的信息,设置适当的图标id,显示合适的图标。
主动请求:
- GsmServiceStateTracker.java
- case EVENT_POLL_SIGNAL_STRENGTH:
-
-
- cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
- break;
在RIL.java中,发送请求:
- public void
- getSignalStrength(Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);
-
-
- riljLog(rr.serialString() + “ >”+requestToString(rr.mRequest));
-
- send(rr);
- }
请求号在RIL.java中,定义了请求号:
RIL_REQUEST_SIGNAL_STRENGTH
返回结果: processSolicited中得到结果后sendToTarget
- private void processSolicited (Parcel p) {
- ...
-
- case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
-
- 在GsmServiceStateTracker.java中,msg的handler指定为this,所以GsmServiceStateTracker负责回送的消息的处理:
- case EVENT_GET_SIGNAL_STRENGTH:
-
-
-
- if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isCdma())) {
-
- return;
- }
- ar = (AsyncResult) msg.obj;
- onSignalStrengthResult(ar);
- queueNextSignalStrengthPoll();
-
- break;
-
- private void onSignalStrengthResult(AsyncResult ar) {
- SignalStrength oldSignalStrength = mSignalStrength;
- int rssi = 99;
- Log.d("YCG", "query done! onSignalStrengthResult");
- if (ar.exception != null) {
-
-
- setSignalStrengthDefaultValues();
- } else {
- int[] ints = (int[])ar.result;
-
-
- if (ints.length != 0) {
- rssi = ints[0];
- Log.d("YCG", "query done! rssi="+rssi);
- } else {
- Log.e(LOG_TAG, "Bogus signal strength response");
- rssi = 99;
- }
- }
-
- mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
- -1, -1, -1, true);
-
- if (!mSignalStrength.equals(oldSignalStrength)) {
- try {
-
- phone.notifySignalStrength();
- } catch (NullPointerException ex) {
- log("onSignalStrengthResult() Phone already destroyed: " + ex
- + "SignalStrength not notified");
- }
- }
- }
phone.notifySignalStrength();通知上层,走上相同流程
转自 http://blog.csdn .NET/pierce0young/article/details/9294119