• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【Android】控制移动数据网络选择 4G/5G

前言

在 Android 应用中控制移动数据网络类型(如 4G/5G)需要与设备的蜂窝网络功能交互。

使用 TelephonyManager

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

获取当前网络类型:

int networkType = telephonyManager.getDataNetworkType();
switch (networkType) {
    case TelephonyManager.NETWORK_TYPE_GSM:
        // 2G网络
        break;
    case TelephonyManager.NETWORK_TYPE_UMTS:
        // 3G网络
        break;
    case TelephonyManager.NETWORK_TYPE_LTE:
        // 4G网络
        break;
    case TelephonyManager.NETWORK_TYPE_NR:
        // 5G网络
        break;
    // 其他网络类型...
}

管理 SIM 卡和网络订阅(API 22+):

SubscriptionManager subManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);

可能需要以下权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <!-- 系统权限 -->

如果无法直接控制网络相关的内容,可能需要手动打开网络设置:

Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
startActivity(intent);

正文

在设备中读取 SIM 卡信息,需在 AndroidMenifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

核心代码如下:

private static final int INF = 0x3f3f3f3f;// 定义一个常量,代表未定义 
private static final int PREFER_5G = 916479;
private static final int PREFER_4G = 392191;
private int subscriptionId = INF;// 卡槽

// 获取全部 SIM 卡信息:
public void getAllSIMInfo() {
    subscriptionId = INF;
    SubscriptionManager subManager = getSystemService(SubscriptionManager.class);
    if (subManager != null) {
        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, 2);
            Log.e(TAG, "没有获取SIM卡信息的权限");
            return;
        }
        for (SubscriptionInfo subInfo : subManager.getActiveSubscriptionInfoList()) {
            int subId = subInfo.getSubscriptionId();
            subscriptionId = subId;
            String carrierName = (String) subInfo.getCarrierName(); // 运营商名称
            Log.d(TAG, "subId=" + subId + ", carrier=" + carrierName);
        }
    }
}

// 设置对应的卡槽和网络制式(即切换 4G/5G)
public void setSubscriptionIDAndAllowedNetworkTypesForReason(int subscriptionId, int reason, long allowedNetworkTypes) {
    // 1. 设置对应的卡槽
    TelephonyManager tm = (TelephonyManager) mContext.getSystemService(TelephonyManager.class).createForSubscriptionId(subscriptionId);
    // 2. 设置网络制式
    Class<?> cls = tm.getClass();
    Method setAllowedNetworkTypesForReason = null;
    try {
        setAllowedNetworkTypesForReason = cls.getMethod("setAllowedNetworkTypesForReason", int.class, long.class);
        setAllowedNetworkTypesForReason.invoke(tm, reason, allowedNetworkTypes);
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        throw new RuntimeException(e);
    }
}

切换 4G/5G 的示例代码:

// 切换 5G 网络
setSubscriptionIDAndAllowedNetworkTypesForReason(subscriptionId, TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, PREFER_5G);

// 切换 4G 网络
setSubscriptionIDAndAllowedNetworkTypesForReason(subscriptionId, TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, PREFER_4G);

posted on 2025-07-17 12:08  RomanLin  阅读(56)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3