前提:清单文件根标签添加
android:sharedUserId="android.uid.system"
剩下的都在代码里了
package com.example.myapplication;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
public class SimRoamingUtil {
private static final String TAG = "SimRoamingUtil";
/**
* 方法一:无法根据卡槽索引设置漫游开关
* @param enable
* @return
*/
public static boolean setMobileDataRoamingEnable(boolean enable) {
try {
Class<?> serviceManager = Class.forName("com.android.internal.telephony.PhoneFactory");
Method method = serviceManager.getMethod("getDefaultPhone");
method.setAccessible(true);
//拿到phone的实例化对象
Object phoneObject = method.invoke(serviceManager.newInstance());
Class<?> phoneClass = Class.forName("com.android.internal.telephony.Phone");
//Class phoneClass = phoneObject.getClass();
//调用phone方法
Method setDataRoamingEnabledMethod = phoneClass.getMethod("setDataRoamingEnabled", boolean.class);
setDataRoamingEnabledMethod.setAccessible(true);
setDataRoamingEnabledMethod.invoke(phoneObject, true);
} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException |
IllegalAccessException | InstantiationException e) {
throw new RuntimeException(e);
}
return enable;
}
/**
* 方法二:根据卡槽索引设置漫游开关
* @param context
* @param slotIndex
* @param enable
*/
@SuppressLint("MissingPermission")
public static void setMobileDataRoamingEnableBySlot(Context context, int slotIndex, boolean enable) {
SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
SubscriptionInfo subscriptionInfo = null;
for (SubscriptionInfo info : subscriptionInfoList) {
if (info.getSimSlotIndex() == slotIndex) {
subscriptionInfo = info;
break;
}
}
if (subscriptionInfo != null) {
int subscriptionId = subscriptionInfo.getSubscriptionId();
try {
Method getPhoneIdMethod = SubscriptionManager.class.getMethod("getPhoneId", int.class);
getPhoneIdMethod.setAccessible(true);
int phoneId = (int) getPhoneIdMethod.invoke(subscriptionManager, subscriptionId);
Class<?> serviceManager = Class.forName("com.android.internal.telephony.PhoneFactory");
Method getPhoneMethod = serviceManager.getMethod("getPhone", int.class);
getPhoneMethod.setAccessible(true);
//根据phoneId 获取phone的实例
Object phoneObject = getPhoneMethod.invoke(serviceManager.newInstance(), phoneId);
Class<?> phoneClass = Class.forName("com.android.internal.telephony.Phone");
//调用phone的setDataRoamingEnabled方法
Method setDataRoamingEnabledMethod = phoneClass.getMethod("setDataRoamingEnabled", boolean.class);
setDataRoamingEnabledMethod.setAccessible(true);
setDataRoamingEnabledMethod.invoke(phoneObject, enable);
} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException |
IllegalAccessException | InstantiationException e) {
throw new RuntimeException(e);
}
}
}
/**
* 方法三:可根据卡槽索引设置,但仅支持Android 10 以上
* @param context
* @param slotIndex
* @param enable
*/
@SuppressLint("MissingPermission")
public static void setSimRoamingForAndroidQ(Context context, int slotIndex, boolean enable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
SubscriptionInfo subscriptionInfo = null;
for (SubscriptionInfo info : subscriptionInfoList) {
if (info.getSimSlotIndex() == slotIndex) {
subscriptionInfo = info;
break;
}
}
if (subscriptionInfo != null) {
int subscriptionId = subscriptionInfo.getSubscriptionId();
try {
// Get TelephonyManager by subscription ID
Method getTelephonyManagerMethod = TelephonyManager.class.getDeclaredMethod("createForSubscriptionId",
int.class);
Object telephonyManagerForSlot = getTelephonyManagerMethod.invoke(telephonyManager, subscriptionId);
// Get method to set data roaming
Method setDataRoamingEnabledMethod = telephonyManager.getClass().getDeclaredMethod("setDataRoamingEnabled", boolean.class);
setDataRoamingEnabledMethod.invoke(telephonyManagerForSlot, enable);
} catch (NoSuchMethodException | IllegalAccessException |
InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
Toast.makeText(context, "SIM card not found in slot index", Toast.LENGTH_SHORT).show();
}
}
}
}
但是要注意,使用方法1和方法2时,还需要在清单文件相应的activity 中添加,
android:process="com.android.phone"
例:
<activity android:name=".MainActivity" android:process="com.android.phone"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
因为只有phone进程才能调用phone对象