7

有没有办法返回“仅使用2G网络”的Android移动网络设置的值?

正在开发的应用程序会测量某个位置的互联网速度,但为了使其具有相关性,它必须知道用户是否故意将移动互联网限制为 2G。

我查看了 ConnectivityManager,但它仅提供有关背景数据设置或所有网络的信息。遍历它们表明,尽管启用了设置,但 HSPA 和 UMTStrue返回isAvailable()

for (NetworkInfo netInfo : cm.getAllNetworkInfo()) {
    Log.i(TAG, netInfo.getSubtypeName() + ": " + netInfo.isAvailable());
}

在这一切中我发现的唯一提示netInfo.getReason()是启用设置时在 HSPA 和 UMTS 上返回“connectionDisabled”。问题是,当设置被禁用时,这些网络类型根本不一定会出现在列表中。对我来说,专门在 HSPA 和 UMTS 上对“connectionDisabled”使用字符串比较似乎不合适。

解决这个问题的正确方法是什么?

4

2 回答 2

5

对于一小部分设备(特别是 LG Optimus 2X Speed,LG-P990),答案似乎是:

int enabled = Settings.Secure.getInt(getContentResolver(),
        "preferred_network_mode", -1);
Log.d("MYAPP", "2G only enabled: " + enabled);

其中“仅使用 2G 网络”设置指定为:

  • 0表示该设置已禁用
  • 1表示该设置已启用
  • -1表示设置未设置(某些设备?)

我是怎么发现的?我使用以下内容收集了所有键/值对Settings.Secure

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(Settings.Secure.CONTENT_URI, null, null, null, null);
if (cursor.moveToFirst()) {
    while (!cursor.isAfterLast()) {
        Log.d("MYAPP", "cursor: "
                + cursor.getString(0) + ", "
                + cursor.getString(1) + ", "
                + cursor.getString(2));
        cursor.moveToNext();
    }
}

我比较了启用和禁用设置的结果,果然我得到了:

07-08 00:15:20.991:调试/MYAPP(13813):光标:5154,preferred_network_mode,1

不要使用索引列(上面示例中的 5154),因为我注意到它在切换设置之间发生了变化。

尽管这与我在网上找到的 Settings.Secure 的一些文档相关,但并非所有手机都尊重此值。

如果您的设备返回-1,也许列出键值对将显示您需要的设置。遇到请留言!

于 2011-07-07T22:23:46.407 回答
0

据我所知,没有记录为该设置获得价值的方法。但是有一个Use2GOnlyCheckBoxPreference类可以作为例子。它使用内部PhonePhoneFactory类来获取设置的当前值prefer_2g

您可以通过反射使用Phone和类。PhoneFactory但当然,这是无证的,风险自负。以下是来自的相关代码Use2GOnlyCheckBoxPreference

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;

public class Use2GOnlyCheckBoxPreference extends CheckBoxPreference {

    private Phone mPhone;
    private MyHandler mHandler;

    public Use2GOnlyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mPhone = PhoneFactory.getDefaultPhone();
        mHandler = new MyHandler();
        mPhone.getPreferredNetworkType(
                mHandler.obtainMessage(MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
    }

    private class MyHandler extends Handler {

        private static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_GET_PREFERRED_NETWORK_TYPE:
                    handleGetPreferredNetworkTypeResponse(msg);
                    break;
            }
        }

        private void handleGetPreferredNetworkTypeResponse(Message msg) {
            AsyncResult ar = (AsyncResult) msg.obj;

            if (ar.exception == null) {
                int type = ((int[])ar.result)[0];
                Log.i(LOG_TAG, "get preferred network type="+type);
                setChecked(type == Phone.NT_MODE_GSM_ONLY);
            } else {
                // Weird state, disable the setting
                Log.i(LOG_TAG, "get preferred network type, exception="+ar.exception);
                setEnabled(false);
            }
        }
    }   
}
于 2011-06-28T10:08:12.563 回答