android中的漫游检测

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2373779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:35:24  来源:igfitidea点击:

roaming detection in android

android

提问by klaus johan

I'm trying to detect when the roaming activation occurs. So far I've used the following piece of code, but because I haven't been able to test it I am unaware of it's correctness

我试图检测漫游激活何时发生。到目前为止,我已经使用了以下代码,但是因为我无法对其进行测试,所以我不知道它的正确性

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

I've written this , thinking that in order for roaming to activate first the signal cell must change. Please let me know whether my deduction is correct or not, and if not how could I accomplish this.

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

回答by Emmanuel

I think you want to use isRoaming() in NetworkInfo class. But first you want to register a change broadcast listener:

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

<receiver android:name="YourListener">
  <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

This gives you an action name: ConnectivityManager.CONNECTIVITY_ACTION

这为您提供了一个操作名称: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();
}

[edit: known issue] NOTE: There seems to be a bug on certain versions, where getActiveNetworkInfo() returns null if roaming. See here: http://code.google.com/p/android/issues/detail?id=11866

[编辑:已知问题] 注意:某些版本似乎存在错误,其中 getActiveNetworkInfo() 在漫游时返回 null。请参阅此处:http: //code.google.com/p/android/issues/detail?id=11866

I hope this helps!

我希望这有帮助!

Emmanuel

伊曼纽尔

回答by Gabriel

You can also test for isNetworkRoaming()in TelephonyManager if you want to know if there is Voice Roaming, even if the receiver is triggered by android.net.conn.CONNECTIVITY_CHANGE. I think this will also avoid the bug when the getActiveNetworkInfo()returns null.

isNetworkRoaming()如果您想知道是否有语音漫游,您也可以在 TelephonyManager 中测试,即使接收器是由 触发的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();
    }
}

回答by AJAY PRAKASH

Reliable way of getting event when Roaming state changes is

漫游状态更改时获取事件的可靠方法是

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

Whenever the Roaming state is detected , PhoneListener will be notified using serviceStateChanged method.

每当检测到漫游状态时,都会使用 serviceStateChanged 方法通知 PhoneListener。

I confirmed this by looking at the AOSP source code.

我通过查看 AOSP 源代码证实了这一点。

CDMA

CDMA

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

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

CDMA LTE

CDMA LTE

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

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

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

Check the method pollStateDone() , this is where the roaming state is set for the TelephonyManager

检查方法 pollStateDone() ,这是为 TelephonyManager 设置漫游状态的地方

回答by lomza

With Android 5.1 update, there is now a very easy roaming detection: just use the SubscriptionManagerand get a roaming info from SubscriptionInfo getDataRoaming(). If there are multiple SIMs, only the info from active one is returned, which is convenient.

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

回答by Tom

In my case I'm already listening for network state changes using the TelephonyManager and PhoneStateListener so, like the original questioner, I'm wondering whether roaming events can be detected there.

就我而言,我已经在使用 TelephonyManager 和 PhoneStateListener 侦听网络状态更改,因此,就像最初的提问者一样,我想知道是否可以在那里检测到漫游事件。

(This would be an alternative to using the ConnectivityManager/NetworkInfo solution in the accepted answer.)

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

To detect changes, the original question suggests listening for changes in cell location but I wonder if this wouldn't cause more events then necessary.

为了检测变化,最初的问题建议监听单元格位置的变化,但我想知道这是否不会导致更多必要的事件。

I would imagine that a change in the roaming state can only occur with a change in the network state.

我想漫游状态的变化只能随着网络状态的变化而发生。

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

There are two caveats to this method, but I think that the ConnectivityManager solution (in the accepted answer) has the same issues:

这种方法有两个警告,但我认为 ConnectivityManager 解决方案(在已接受的答案中)具有相同的问题:

  1. I'm listening for changes in DATA network state. If user doesn't establish a data connection (e.g. they are just voice roaming) then it won't work, but I don't think this is a problem because most of us are looking to detect data roaming (e.g. so our apps don't use data when the user is roaming).

  2. I'm not certain that there must be a change in data connection state when the user starts roaming - it is just my theory and I would be interested in hearing if anyone knows better.

  1. 我正在监听 DATA 网络状态的变化。如果用户没有建立数据连接(例如他们只是语音漫游),那么它将无法工作,但我认为这不是问题,因为我们大多数人都希望检测数据漫游(例如,我们的应用程序不用户漫游时不使用数据)。

  2. 我不确定当用户开始漫游时数据连接状态一定会发生变化 - 这只是我的理论,如果有人知道得更好,我很想听听。

Finally, let me add that it is possible that listening to PhoneStateListener::onServiceStateChanged() could be the best solution of all: simple and with the fewest unnecessary events (this should be triggered rarely) but I find the docs ambiguous and can't tell whether the PSL event gets triggered for a change in any of the ServiceState object's attributes (e.g. including roaming) or just for the ServiceState's service state attribute.

最后,让我补充一点,听 PhoneStateListener::onServiceStateChanged() 可能是最好的解决方案:简单且不必要的事件最少(这应该很少触发)但我发现文档含糊不清,不能判断 PSL 事件是因 ServiceState 对象的任何属性(例如,包括漫游)的更改而触发,还是仅因 ServiceState 的服务状态属性而触发。

回答by Srishti Roy

This works perfectly without any lisstener 1 for roaming and 0 for nonroaming

这可以完美运行,没有任何侦听器 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());