我是Android的新手。
如何以百分比(1 - 100%)获得GSM信号强度?
答案 0 :(得分:4)
提出要求的用户应提供更多信息或反馈。那说......
问题根本不是微不足道的:因为它是以分贝为单位的标度,它不是线性的,因此当信号较低时较小的变化会产生较大的影响,而当值较高时较大的变化则不那么重要。这就是为什么我很遗憾地说所有其他答案都会得到与手机上显示的值不匹配的不准确值。
假设你已经拥有一个SignalStrength
对象(如果没有,还有另一个很好的答案显示了如何做到这一点),在Marshmallow中它用方法getGsmLevel()
解决了(还有其他所有方法)信号,甚至组合)返回线性化的标度0-4。您可以查看课程SignalStrength
中的源代码。
/**
* Get gsm as level 0..4
*
* @hide
*/
public int getGsmLevel() {
int level;
// ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
// asu = 0 (-113dB or less) is very weak
// signal, its better to show 0 bars to the user in such cases.
// asu = 99 is a special case, where the signal strength is unknown.
int asu = getGsmSignalStrength();
if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
else level = SIGNAL_STRENGTH_POOR;
if (DBG) log("getGsmLevel=" + level);
return level;
}
具有0-100%的比例它没有意义,因为它对于这个问题来说是一个小粒度,这就是为什么它更常用于0-4范围,并且在这种方法中它已经线性化了。如果不在Marshmallow中,只需调整此方法即可将对象作为值接收。如果由于某种原因你真的需要0-100范围,你应该使用dB到线性转换功能,但我不知道GSM信号中的增益因子。
答案 1 :(得分:3)
public class MyActivity extends Activity {
public static final int UNKNOW_CODE = 99;
int MAX_SIGNAL_DBM_VALUE = 31;
TelephonyManager tel;
MyPhoneStateListener myPhoneStateListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = getLayoutInflater().inflate(R.layout.activity_about, null);
setContentView(view);
myPhoneStateListener = new MyPhoneStateListener();
tel = (TelephonyManager) PpsApplication.getAppContext().getSystemService(Context.TELEPHONY_SERVICE);
tel.listen(myPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
private class MyPhoneStateListener extends PhoneStateListener {
/* Get the Signal strength from the provider, each tiome there is an update */
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
if (null != signalStrength && signalStrength.getGsmSignalStrength() != UNKNOW_CODE) {
int signalStrengthPercent = calculateSignalStrengthInPercent(signalStrength.getGsmSignalStrength());
viewModel.setSignalStrengthString(IntegerHelper.getString(signalStrengthPercent));
}
}
}
private int calculateSignalStrengthInPercent(int signalStrength) {
return (int) ((float) signalStrength / MAX_SIGNAL_DBM_VALUE * 100);
}
}
答案 2 :(得分:1)
请注意.getGsmSignalStrength();现在只返回栏:0-5,99
现在隐藏了实际值。你仍然可以使用反射来找到它们:
int strength=signalStrength.getGsmSignalStrength();//number of bars not ASU
Log.v("Mobile","BARS: "+strength);
try{//Actual signal strength is hidden
Class classFromName = Class.forName(SignalStrength.class.getName());
java.lang.reflect.Method method = classFromName.getDeclaredMethod("getAsuLevel");//getDbm
strength = (int) method.invoke(signalStrength);
}catch (Exception ex){Log.v("Mobile","cant retreive");}
if (strength == 99 ) { Log.v("Mobile", "ERROR! GSM signal strength not available!");return;}//99 = Unknown
if (strength == 255) { Log.v("Mobile", "ERROR! UMTS signal strength not available!");return;}//255 = Unknown
以上示例仅针对ASU,似乎比Dbm更好。获得ASU值后,您可以将其转储为百分比:
Log.v("Mobile","ASU: "+strength);
//Data.mobile_signal=strength*20;//Number of bars 0-5
//Data.mobile_signal = 100-((strength-113)/62);//GSM DBM
Data.mobile_signal =(int)((double)strength*100/31);//GSM ASU
Data.mobile_signal =(int)((double)strength*100/91);//UMTS ASU
Log.v("Mobile","Set GSM signal from "+strength+" to "+Data.mobile_signal);
提醒一下,这是因为当你有GSM信号而不是CDMA信号时。使用TelephonyManager.getPhoneType();确定哪个: 1 = GSM,2 = CDMA,3 = SIP
但等等!这说我只有50%的信号强度,但我有5个棒!这是错的!
嗯,不完全是。除非您的手机正好在发射器前面,否则它可能不会是100%。但50%的信号质量约为100%。所以从这里你必须要有创意。
答案 3 :(得分:0)
答案 4 :(得分:0)
更好的解决方案是使用:
signalStrength.level
这将返回一个 0 到 4 的值,您应该从您的 android 设备中熟悉该值。将其视为信号条的数量。这与 GSM 和 CDMA 兼容。