Обнаружение роуминга в Android
Я пытаюсь определить, когда происходит активация роуминга. До сих пор я использовал следующий фрагмент кода, но, поскольку я не смог его протестировать, я не осознаю его правильность
TelephonyManager telephonyManager = TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener cellLocationListener = new PhoneStateListener() {
public void onCellLocationChanged(CellLocation location) {
if(telephonyManager.isNetworkRoaming()
{
Toast.makeText(getApplicationContext(),"in roaming",Toast.LENGTH_LONG).show();
}
}
};
telephonyManager.listen(cellLocationListener, PhoneStateListener.LISTEN_CELL_LOCATION);
Я написал это, думая, что для того, чтобы роуминг активировался первым, ячейка сигнала должна измениться. Пожалуйста, дайте мне знать, является ли мой вывод правильным или нет, и если нет, то как я могу это сделать.
6 ответов
Вы также можете проверить на isNetworkRoaming()
в TelephonyManager, если вы хотите знать, есть ли голосовой роуминг, даже если приемник запускается android.net.conn.CONNECTIVITY_CHANGE
, Я думаю, что это также позволит избежать ошибки, когда getActiveNetworkInfo()
возвращает ноль.
public class RoamingListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephony =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (telephony.isNetworkRoaming())
Toast.makeText(context, "Is on TelephonyM Roaming", Toast.LENGTH_LONG).show();
}
}
Я думаю, что вы хотите использовать isRoaming() в классе NetworkInfo. Но сначала вы хотите зарегистрировать слушателя изменения трансляции:
<receiver android:name="YourListener">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
Это дает вам имя действия: ConnectivityManager.CONNECTIVITY_ACTION
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
//[edit: check for null]
if(ni != null) {
//...Here check if this is connected and available...
return ni.isRoaming();
}
[править: известная проблема] ПРИМЕЧАНИЕ. Кажется, в некоторых версиях есть ошибка, когда getActiveNetworkInfo() возвращает ноль в роуминге. Смотрите здесь: http://code.google.com/p/android/issues/detail?id=11866
Надеюсь, это поможет!
Эммануэль
Надежный способ получить событие при изменении состояния роуминга
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
super.onServiceStateChanged(serviceState);
if (telephonyManager.isNetworkRoaming()) {
// In Roaming
} else {
// Not in Roaming
}
// You can also check roaming state using this
if (serviceState.getRoaming()) {
// In Roaming
} else {
// Not in Roaming
}
}
};
Всякий раз, когда обнаруживается состояние роуминга, PhoneListener будет уведомлен с использованием метода serviceStateChanged.
Я подтвердил это, посмотрев исходный код AOSP.
CDMA
CDMA LTE
GSM
Проверьте метод pollStateDone(), это где состояние роуминга установлено для TelephonyManager
С обновлением Android 5.1 теперь очень просто обнаружение роуминга: просто используйте SubscriptionManager и получите информацию о роуминге из SubscriptionInfo getDataRoaming (). Если имеется несколько SIM-карт, возвращается только информация с активной, что удобно.
В моем случае я уже прослушиваю изменения состояния сети с помощью TelephonyManager и PhoneStateListener, поэтому, как и в случае с оригинальным опросником, мне интересно, можно ли там обнаружить роуминговые события.
(Это будет альтернативой использованию решения ConnectivityManager/NetworkInfo в принятом ответе.)
Чтобы обнаружить изменения, первоначальный вопрос предполагает прослушивание изменений в расположении ячейки, но мне интересно, не вызовет ли это больше событий, чем необходимо.
Я полагаю, что изменение состояния роуминга может происходить только при изменении состояния сети.
protected PhoneStateListener psl = new PhoneStateListener() {
public void onDataConnectionStateChanged(int state, int networkType) {
if (TelephonyManager.DATA_CONNECTED == state)
isRoaming = teleman.isNetworkRoaming();
// teleman is an instance of TelephonyManager
}
}
public static final int pslEvents = PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
TelephonyManager teleman = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
teleman.listen( psl, pslEvents );
У этого метода есть две оговорки, но я думаю, что решение ConnectivityManager (в принятом ответе) имеет те же проблемы:
Я слушаю изменения в состоянии сети DATA. Если пользователь не устанавливает соединение для передачи данных (например, это просто голосовой роуминг), то оно не будет работать, но я не думаю, что это проблема, потому что большинство из нас стремятся обнаружить роуминг данных (например, чтобы наши приложения не не использовать данные, когда пользователь находится в роуминге).
Я не уверен, что должно произойти изменение состояния подключения к данным, когда пользователь начинает роуминг - это всего лишь моя теория, и мне было бы интересно услышать, если кто-то знает лучше.
Наконец, позвольте мне добавить, что вполне возможно, что прослушивание PhoneStateListener::onServiceStateChanged() может быть лучшим решением из всех: простым и с наименьшим количеством ненужных событий (это должно вызываться редко), но я нахожу документы неоднозначными и не могу сообщить, инициируется ли событие PSL для изменения какого-либо атрибута объекта ServiceState (например, роуминга) или только для атрибута состояния службы ServiceState.
Это прекрасно работает без каких-либо lisstener 1 для роуминга и 0 для не роуминга
try {
int roaming= Settings.Secure.getInt(getContentResolver(), Settings.Secure.DATA_ROAMING);
Log.e("roaming","roaming"+roaming);
}
catch (Exception e)
{
Log.e("Exception","Exception"+e.getLocalizedMessage());