2010-03-03 77 views
8

我试图检测漫游激活何时发生。到目前为止,我已经使用了下面的一段代码,而是因为我一直无法对其进行测试,我不知道它的正确性在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); 

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

+1

你可以在模拟器上我觉得很容易进行测试。 如果您在Eclipse中切换到DDMS调试透视图,则可以选择仿真器,然后从数据选择器中选择仿真器控件中的漫游。 这应该引发漫游和非漫游之间的变化。问题在于,它可能会使用不同的方式在模拟器中从一个状态转换到另一个状态,然后实际的设备就会转移。 它在模拟器中工作吗? – Janusz 2010-03-03 18:18:46

+0

我正在使用除Eclipse之外的其他IDE,其中一个没有此选项 – 2010-03-03 18:49:40

+0

您可以通过模拟器控制台上的telnet执行相同的操作。 查看http://developer.android.com/intl/fr/guide/developing/tools/emulator.html#telephony您可以使用gsm命令启用漫游。 – Janusz 2010-03-04 09:02:43

回答

15

我想你想在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(); 
} 

[编辑:已知问题] 注:似乎是一个某些版本的bug,其中getActiveNetworkInfo()在漫游时返回null。看到这里:http://code.google.com/p/android/issues/detail?id=11866

我希望这可以帮助!

灵光

+0

如果我将模拟器切换到漫游,ni将返回null。 Hrm ...在最后一行btw时要小心NullPointerException。 – 2011-09-28 22:33:25

+0

好点。我会在答案中纠正这一点。而且,某些版本似乎存在一个错误。 – Emmanuel 2011-09-29 14:02:58

12

您还可以在TelephonyManager测试isNetworkRoaming()如果你想知道是否有话音漫游,即使接收由android.net.conn.CONNECTIVITY_CHANGE触发。 我认为这也将避免当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(); 
    } 
} 
+0

我不确定为什么你建议你的方法只是为了监测'语音漫游'? isNetworkRoaming()的文档不做任何这样的区分。 – Tom 2012-07-08 16:00:14

+0

想到同样的解决方案,我不明白他们为什么不只是在上面的答案中这样做。 – 2012-08-24 09:58:24

+4

它不可能进行语音漫游,但不能进行数据漫游。 http://stackoverflow.com/questions/2783120/data-roaming-in-android – 2012-09-11 04:50:52

0

对我来说,我已经听使用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. ,我听在数据网络状态的变化。如果用户没有建立数据连接(例如,他们只是语音漫游),那么它不会工作,但我不认为这是一个问题,因为我们大多数人都在寻找检测数据漫游(例如,所以我们的应用程序当用户漫游时不使用数据)。

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

最后,让我补充一点,有可能是听PhoneStateListener :: onServiceStateChanged()可能是所有的最佳解决方案:简单,用最少的不必要的事件(这应该是很少触发),但我觉得该文档含糊不清,并且无法分辨PSL事件是否因任何ServiceState对象的属性(例如,包括漫游)或仅用于ServiceState的服务状态属性而被触发。漫游状态变化时得到事件的

+0

和你会在哪里使用这???里面的主要活动..但笏如果我的活动是在后台,因为它不包括清单将它的工作?我有一个服务在后台运行,并在处理器的低内存中再次崩溃。 – sheetal 2012-08-01 06:45:07

+0

如果您希望它在您的活动不是前台时仍能正常运行,那么您应该将其放入服务中,但即使在您的服务中,也无法保证它将继续运行(如您注意的)。我想你需要找到一个你可以在清单中列出的意图,当漫游状态改变时它会被解雇 - 所以我基于PSL的soln不适合你。 – Tom 2012-08-01 13:49:00

2

可靠的方法是

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

-2

这工作完全没有任何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());