2010-03-03 64 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());