Android Q добавил новый тип сети NETWORK_TYPE_NR для 5G, который недоступно для Android Pie. Недавно выпущенный Samsung S10 полностью поддерживает 5G. Он может отображать значок 5G в строке состояния, когда он находится в сети 5G.
Может ли стороннее приложение узнать, находится ли устройство Android Pie в сети 5G или нет?
Любая помощь будет оценена.
Следующая ссылка является определением нового типа сети. Он недоступен в ветке Android Pie.
Исходный код для выпуска Pie https://android.googlesource.com/platform/frameworks/base/+/refs/heads/pie-release-2/telephony/java/android/telephony/TelephonyManager.java
Последний исходный код с NETWORK_TYPE_NR https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/telephony/java/android/telephony/TelephonyManager.java#2375
Я полагаю, что они перенесли код из Q в Pie, поскольку логика для 5G была реализована в конце прошлого года в Q (альфа).
Итак, при использовании
TelephonyManager.getNetworkType()
вы, вероятно, получите
20 (5G)
РЕДАКТИРОВАТЬ
Согласно комментарию ниже: тип сети будет 13, поэтому он не решает проблему.
РЕДАКТИРОВАТЬ
Попробуйте использовать отражение
static boolean isNRConnected(TelephonyManager telephonyManager) {
try {
Object obj = Class.forName(telephonyManager.getClass().getName())
.getDeclaredMethod("getServiceState", new Class[0]).invoke(telephonyManager, new Object[0]);
Method[] methods = Class.forName(obj.getClass().getName()).getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("getNrStatus") || method.getName().equals("getNrState")) {
method.setAccessible(true);
return ((Integer) method.invoke(obj, new Object[0])).intValue() == 3;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
У вас есть этот телефон и покрытие 5G? Вы можете попробовать вызвать метод getNrStatus
из класса ServiceState. Если это вернет 3
, необходимо подключить 5G.
В классе ServiceState нет такого метода getNrStatus
, даже в Android Q. Код не скомпилируется.
Вам нужно использовать отражение.
Удалось получить SM-G977, приведенный выше пример кода работает. Это правильный ответ! Кстати, как вы извлекаете исходный код из прошивки? @Павел Мачала
Не используйте отражение, Android не рекомендует это, они также заставляют это делать через собственные интерфейсы sdk.
Вы правы в том, что использование обратного вызова PhoneStateListener и onDisplayInfo является предпочтительным способом в Android 11. Однако использование отражения было предложено для Android 9 и 10. Похоже, что это работает на устройствах Samsung, но другие производители использовали другую реализацию.
Я извлек ServiceState.java из прошивки SM-G977N, и это подтверждает, что они добавили
ServiceState.getNrStatus()
5G(NR) активен, если NetworkRegistrationState.NR_STATUS_CONNECTED = 3;
Трюк с отражением был мертв со времен Pie, см. developer.android.com/distribute/best-practices/develop/….
Не правда. Вы по-прежнему можете использовать отражение в общедоступных методах. Если вы используете отражение в частных/защищенных методах/полях, у вас проблемы.
Не удалось добавить это как комментарий, но, как сказал @Pavel Machala, просмотр Класс ServiceState в AOSP дает следующее:
/**
* Get the NR 5G status of the mobile data network.
* @return the NR 5G status.
* @hide
*/
public @NRStatus int getNrStatus() {
final NetworkRegistrationState regState = getNetworkRegistrationState(
NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (regState == null) return NetworkRegistrationState.NR_STATUS_NONE;
return regState.getNrStatus();
}
Существует официальная документация по обнаружению 5G на Android 11. https://developer.android.com/about/versions/11/features/5g#detection
Позвоните TelephonyManager.listen()
, передав LISTEN_DISPLAY_INFO_CHANGED
, чтобы определить, есть ли у пользователя подключение к сети 5G.
как предложил @Hunter, вам нужно использовать «прослушивание» из диспетчера телефонии, но если это API 30+, вам необходимо предоставить разрешение READ_PHONE
и прослушивать LISTEN_DISPLAY_INFO_CHANGED
и переопределять onDisplayInfoChanged
из PhoneStateListener
(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).listen(customPhoneStateListener,PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
Слушатель должен быть примерно таким:
private class CustomPhoneStateListener : PhoneStateListener() {
override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
super.onDisplayInfoChanged(telephonyDisplayInfo)
when (telephonyDisplayInfo.overrideNetworkType) {
//5G
OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO,
OVERRIDE_NETWORK_TYPE_NR_NSA,
OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> setNetworkChange(NETWORK_TYPE_NR)
OVERRIDE_NETWORK_TYPE_LTE_CA -> {
setNetworkChange(19) //LTE+
}
else -> setNetworkChange(telephonyDisplayInfo.networkType)
}
} else {
setNetworkChange(telephonyDisplayInfo.networkType)
}
}
}
Ссылка: https://developer.android.com/about/versions/11/features/5g#detection
Нет, он возвращает 13 (LTE), как и любой телефон, работающий в Pie.