android手机信号强度
2013-11-28 15:25
507 查看
在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值转换为几格信号的方法:
-----------------------------------------------------------------------------------------
以下是从网上找到的相关资料。
在RILConstants.java中找到:
在RIL.java中找到与其相关的代码:
在RIL的父类BaseCommands.java中找到:
再找其调用者(GsmServiceStateTracker.java):
GsmServiceStateTracker自己处理上报上来的信号强度信息:
函数onSignalStrengthResult负责处理:
若没发生异常,且值产生变化,则调用 phone.notifySignalStrength通知(见GSMPhone.java):
这个注册者来自:
TelephonyRegistry.java,TelephonyRegistry是ITelephonyRegistry.Stub的子类,作为service运行在system_server进程中,它会通知注册者。上面的DefaultPhoneNotifier运行在com.android.phone进程中,当信号强度值变化时,通过Service进行通知(service被感兴趣的注册者调用了listen,添加了回调函数。
在TelephonyManager.java中提供了API,应用程序可以监听各种事件,实际上它将感兴趣的监听者作为一条记录添加到service一侧的列表(跨进程)中,当有变化时,调用它们提供的回调函数,通知(跨进程)这些注册者。
TelephonyManager.java中的listen函数如下:
其中回调对象实例listener.callback来自于PhoneStateListener.java嵌套定义及其实例,这样,当TelephonyRegistry.java调用回调函数时,就调用到listener.callback,进而发送消息给PhoneStateListener.java中的mHandler,由其处理,进而由其子类去处理。
在StatusBarPolicy.java中,注册了下面要监听处理的事件。第二个为信号强度:
处理者为:
在StatusBarPolicy的updateSignalStrength函数中,将根据得到的信息,设置适当的图标id,显示合适的图标。
主动请求:
在RIL.java中,发送请求:
请求号在RIL.java中,定义了请求号:
RIL_REQUEST_SIGNAL_STRENGTH
返回结果: processSolicited中得到结果后sendToTarget
phone.notifySignalStrength();通知上层,走上相同流程
转自 http://blog.csdn.net/pierce0young/article/details/9294119
在你手机屏幕上方显示的信号条永远不会是最好的方法来确定你手机的信号,无论你用什么手机都一样。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;
在RIL.java中找到与其相关的代码:
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)); }
在RIL的父类BaseCommands.java中找到:
public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) { 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: // 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;
函数onSignalStrengthResult负责处理:
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”); } } }
若没发生异常,且值产生变化,则调用 phone.notifySignalStrength通知(见GSMPhone.java):
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)); }
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() : “<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 } }
其中回调对象实例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: // Just poll signal strength…not part of pollState() cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); break;
在RIL.java中,发送请求:
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); }
请求号在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: // 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
相关文章推荐
- Android手机得到信号强度信息
- 【小功能2】android获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)
- android手机信号强度
- 【小功能2】android获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)
- Android 【信号格的客制化】Part 3:手机上显示的信号强度dbm值不正确
- Android手机信号强度介绍
- Android手机信号强度详解
- Android系统移植与调试之------->如何修改Android手机显示的4G信号强度的格子数
- android双卡手机怎样分别获得两个卡的信号强度
- Android 获取 Wifi 信号强度,检测是 Wifi 或者流量,获取手机电池电量及充电状态
- 【小功能2】android获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)
- android-获取手机信号强度
- Android:TelephonyManager,MyPhoneStateListener监听手机信号强度
- android-获取手机信号强度(2)
- Android小功能获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)
- android手机 - 关于信号强度的问题
- Android手机信号强度检测详细介绍
- 【小功能2】android获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)
- 如何测量Android手机的信号强度
- Android 手机信号强度上报机制1