Android中的漫游检测

我试图检测漫游激活何时发生。 到目前为止,我已经使用了下面这段代码,但是因为我没有能够testing它,所以我不知道它的正确性

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); 

我写了这个,认为为了漫游首先激活信号单元必须改变。 请让我知道我的扣除是否正确,如果不是我怎么能做到这一点。

Solutions Collecting From Web of "Android中的漫游检测"

我想你想在NetworkInfo类中使用isRoaming()。 但首先你要注册一个更改广播监听器:

 <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()返回null。 请参阅: http : //code.google.com/p/android/issues/detail?id=11866

我希望这有帮助!

灵光

如果您想知道是否存在语音漫游,即使接收方是由android.net.conn.CONNECTIVITY_CHANGE触发的,您也可以在TelephonyManager中testingisNetworkRoaming() 。 我认为这也将避免getActiveNetworkInfo()返回null时的错误。

 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(); } } 

当漫游状态改变时获得事件的可靠方式是

 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设置漫游状态的地方

在我的情况下,我已经在使用TelephonyManager和PhoneStateListener监听networking状态的变化,所以像原来的提问者一样,我想知道是否可以在那里检测到漫游事件。

(这是在接受的答案中使用ConnectivityManager / NetworkInfo解决scheme的替代scheme。)

为了检测变化,原始问题build议听取细胞位置的变化,但是我想知道这是否会导致更多的事件,然后是必要的。

我可以想象,漫游状态的变化只能在networking状态发生变化的时候才会发生。

 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解决scheme(在接受的答案中)具有相同的问题:

  1. 我正在监听DATAnetworking状态的变化。 如果用户没有build立数据连接(例如,他们只是语音漫游),那么它不会工作,但我不认为这是一个问题,因为我们大多数人正在寻找检测数据漫游(例如,所以我们的应用程序当用户漫游时不使用数据)。

  2. 当用户开始漫游时,我不确定数据连接状态必须改变 – 这只是我的理论,我有兴趣知道是否有人知道更好。

最后,让我补充说,监听PhoneStateListener :: onServiceStateChanged()可能是最好的解决scheme:简单并且有最less的不必要的事件(这应该很less被触发),但是我发现这些文档是不明确的,不能告诉PSL事件是否被任何ServiceState对象的属性(例如,包括漫游)的变化触发,或者仅用于ServiceState的服务状态属性。

使用Android 5.1更新,现在有一个非常简单的漫游检测:只需使用SubscriptionManager,并从SubscriptionInfo getDataRoaming()获取漫游信息。 如果有多张SIM卡,则只返回活动的信息,方便。

这完美的没有任何lisstener 1漫游和0 nonroaming

 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());