在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 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 407 // asu = 0 (-113dB or less) is very weak 408 // signal, its better to show 0 bars to the user in such cases. 409 // asu = 99 is a special case, where the signal strength is unknown. 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;
private void processUnsolicited (Parcel p) { ……. case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break; ….. case RIL_UNSOL_SIGNAL_STRENGTH: // Note this is set to “verbose” because it happens // frequently if (RILJ_LOGV) unsljLogvRet(response, ret); if (mSignalStrengthRegistrant != null) { mSignalStrengthRegistrant.notifyRegistrant( new AsyncResult (null, ret, null)); }
public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
mSignalStrengthRegistrant = new Registrant (h, what, obj);
}
public GsmServiceStateTracker(GSMPhone phone) { super(); …… cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null); ……
case EVENT_SIGNAL_STRENGTH_UPDATE: // This is a notification from // CommandsInterface.setOnSignalStrengthUpdate ar = (AsyncResult) msg.obj; // The radio is telling us about signal strength changes // we don’t have to ask it dontPollSignalStrength = true; onSignalStrengthResult(ar); break;
private void onSignalStrengthResult(AsyncResult ar) { SignalStrength oldSignalStrength = mSignalStrength; int rssi = 99; if (ar.exception != null) { // -1 = unknown // most likely radio is resetting/disconnected setSignalStrengthDefaultValues(); } else { int[] ints = (int[]) ar.result; // bug 658816 seems to be a case where the result is 0-length 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 { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after // POLL_PERIOD_MILLIS) during Radio Technology Change) phone.notifySignalStrength(); } catch (NullPointerException ex) { log(“onSignalStrengthResult()Phone already destroyed:”+ex +“SignalStrength not notified”); } } }
notifySignalStrength() { mNotifier.notifySignalStrength(this); } DefaultPhoneNotifier(DefaultPhoneNotifier.java)通知注册者: public void notifySignalStrength(Phone sender) { try { mRegistry.notifySignalStrength(sender.getSignalStrength()); } catch (RemoteException ex) { // system process is dead } }
DefaultPhoneNotifier() { mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry)); }
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); }
public void listen(PhoneStateListener listener, int events) { String pkgForDebug = mContext != null ? mContext.getPackageName() : “<unknown>”; try { Boolean notifyNow = (getITelephony() != null); mRegistry.listen(pkgForDebug, listener.callback, events, notifyNow); } catch (RemoteException ex) { // system process dead } catch (NullPointerException ex) { // system process dead } }
((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(); } }
GsmServiceStateTracker.java case EVENT_POLL_SIGNAL_STRENGTH: // Just poll signal strength…not part of pollState() cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); break;
public void getSignalStrength(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result); /*if (RILJ_LOGD)*/ riljLog(rr.serialString() + “ >”+requestToString(rr.mRequest)); send(rr); }
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: // This callback is called when signal strength is polled // all by itself if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isCdma())) { // Polling will continue when radio turns back on and not CDMA 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) { // -1 = unknown // most likely radio is resetting/disconnected setSignalStrengthDefaultValues(); } else { int[] ints = (int[])ar.result; // bug 658816 seems to be a case where the result is 0-length 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 { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after // POLL_PERIOD_MILLIS) during Radio Technology Change) phone.notifySignalStrength(); } catch (NullPointerException ex) { log("onSignalStrengthResult() Phone already destroyed: " + ex + "SignalStrength not notified"); } } }
phone.notifySignalStrength();通知上层,走上相同流程
转自 http://blog.csdn.net/pierce0young/article/details/9294119