Обнаружение роуминга в 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

https://android.googlesource.com/platform/frameworks/opt/telephony/+/master/src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java

CDMA LTE

https://android.googlesource.com/platform/frameworks/opt/telephony/+/master/src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java

GSM

https://android.googlesource.com/platform/frameworks/opt/telephony/+/master/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java

Проверьте метод 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 (в принятом ответе) имеет те же проблемы:

  1. Я слушаю изменения в состоянии сети DATA. Если пользователь не устанавливает соединение для передачи данных (например, это просто голосовой роуминг), то оно не будет работать, но я не думаю, что это проблема, потому что большинство из нас стремятся обнаружить роуминг данных (например, чтобы наши приложения не не использовать данные, когда пользователь находится в роуминге).

  2. Я не уверен, что должно произойти изменение состояния подключения к данным, когда пользователь начинает роуминг - это всего лишь моя теория, и мне было бы интересно услышать, если кто-то знает лучше.

Наконец, позвольте мне добавить, что вполне возможно, что прослушивание 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());
Другие вопросы по тегам