如何从3G和2G / EDGE反之亦然切换? [英] How to switch from 3G and 2G/EDGE vice versa?
问题描述
我想通过code从3G切换网络preference为2G / EDGE,反之亦然。我可以能够打开和关闭的移动数据连接切换。现在我需要知道的3G到2G / EDGE,反之亦然通过code如何切换。有人可以帮助我在这里。提前致谢。
I am trying to switch the network preference from 3G to 2G/EDGE through code and vice versa. I can able to switch on and off the mobile data connection. Now i need know how to switch between 3G to 2G/EDGE and vice versa through code. can somebody help me here. Thanks in advance.
推荐答案
在一个办法来解决这个与反思和系统调用的命令,我迷迷糊糊的,并决定汇报,即使线程是旧的,也有一些注意事项
I've stumbled upon a way to solve this with reflection and system call commands, and decided to report it even though the thread is old and there are some caveats:
- 需要根
- 的hackish,也许ROM特定的(在CM 12.1泰坦测试)
- 在可能不工作在所有的Android版本(5.1.1测试)
大部分的code都借/灵感此答案由ChuongPham 。
Much of the code is borrowed from / inspired by this answer by ChuongPham.
首先,我们需要通过获取ITelephony类声明的字段的值,以获得正确的事务code。因为我怀疑字段的名称可能会略有不同的平台上(为我的字段名称是TRANSACTION_set preferredNetworkType_96),我提供了一个解决方案,那就是尽可能地灵活:
First we need to get the correct transaction code by getting the value of a declared field of the ITelephony class. Since I suspect the name of the field might be slightly different depending on the platform (for mine the field name is "TRANSACTION_setPreferredNetworkType_96"), I provide a solution that is as flexible as possible:
private static String get3gTransactionCode(Context context) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName());
final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony");
mTelephonyMethod.setAccessible(true);
final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager);
final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName());
final Class<?> mClass = mTelephonyStubClass.getDeclaringClass();
for (Field f:mClass.getDeclaredFields()) {
if (f.getName().contains("setPreferredNetworkType")) {
final Field field = mClass.getDeclaredField(f.getName());
field.setAccessible(true);
return String.valueOf(field.getInt(null));
}
}
throw new NoSuchFieldException();
}
接下来我们可以通过苏使用事务code在系统调用:
Next we can use the transaction code in a system call via su:
private static void setPreferredNetworkType(Context context, int preferredType) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException {
String transactionCode = get3gTransactionCode(context);
String command = "service call phone " + transactionCode + " i32 " + preferredType;
executeCommandViaSu(context, "-c", command);
}
在我的情况,我认为这种方法的第二个参数是1对2G,和10对3G preference。针对不同的网络类型的常量可以发现<一href="http://developer.android.com/reference/android/telephony/TelephonyManager.html#NETWORK_TYPE_1xRTT"相对=nofollow>这里。
In my case, I call that method with the 2nd parameter being 1 for 2G, and 10 for 3G preference. The constants for different network types can be found here.
为了方便和完整性我也复制粘贴 ChuongPham的答案executeCommandViaSu方法这里:
For convenience and completeness I also copy-paste the executeCommandViaSu method from ChuongPham's answer here:
private static void executeCommandViaSu(Context context, String option, String command) {
boolean success = false;
String su = "su";
for (int i=0; i < 3; i++) {
// Default "su" command executed successfully, then quit.
if (success) {
break;
}
// Else, execute other "su" commands.
if (i == 1) {
su = "/system/xbin/su";
} else if (i == 2) {
su = "/system/bin/su";
}
try {
// Execute command as "su".
Runtime.getRuntime().exec(new String[]{su, option, command});
} catch (IOException e) {
success = false;
// Oops! Cannot execute `su` for some reason.
// Log error here.
} finally {
success = true;
}
}
}
这篇关于如何从3G和2G / EDGE反之亦然切换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!