By:GentlemanTsao
背景:
3UK 希望在漫游的时候,APN 能够从 local 切换到 common,也就是从自己的 APN 切换到 一个通用的 APN。这项被称为 LBO 的 feature ,即欧洲的运营商都要支持该通用 APN。
要求
行为:
- 在本地网络,要使用 3UK 本地 APN;
- 处于漫游时,使用 EUInternet APN,不再从 3UK 接入.
菜单设定:
有两个选项:3UK 和 EU Roaming.
- 设为本地,APN 一直是 3UK;
- 设为 EU roaming,APN 随网络的漫游而切换。
实现方案:
根据网络漫游状态,动态更新 APN database。
分为:
静态切换:
当菜单设定变动时;
动态切换:
当网络漫游状态变化时;
关键源代码
静态切换APN,当菜单设定变动时
对应场景是,网络没有改变,APN roaming 设定有更改。若当前网络处于本地,APN 将不会变化;若网络 处于漫游,APN 将切换到 EU Internet。
实现方法是直接修改 APN DB 参数,使对应的 APN 类 型改变、enable 属性改变,从而控制显示或隐藏。
private void doApnSwitch(int value){
boolean roaming = "true".equals(
SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
String CARRIERS_URI_STRING = "content://telephony/carriers";
Uri APN_URI = Uri.parse(CARRIERS_URI_STRING);
ContentResolver resolver = getActivity().getContentResolver();
Xlog.d(TAG, "doApnSwitch value =" + value);
// if value == 0, then no EUinternet, switch to 3UK APN anyway;
//if value == 1, should use EUinternet when roaming,use 3UK APN when in Home
if( value == 0 || value == 1 && !roaming){
Xlog.d(TAG, "enable home APN" );
/*disable Roaming APN*/
ContentValues value3 = new ContentValues(1);
value3.put(Telephony.Carriers.CARRIER_ENABLED, 0);
resolver.update(APN_URI, value3, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","EUInternet"});
/*enable home APN*/
ContentValues value1 = new ContentValues(1);
value1.put(Telephony.Carriers.TYPE, "default,mms,supl");
resolver.update(APN_URI, value1, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3"});
ContentValues value2 = new ContentValues(1);
value2.put(Telephony.Carriers.CARRIER_ENABLED, 1);
resolver.update(APN_URI, value2, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3hotspot"});
}else if (value == 1 && roaming){
Xlog.d(TAG, "disable home APN" );
/*disable home APN*/
ContentValues value1 = new ContentValues(1);
value1.put(Telephony.Carriers.TYPE, "mms");
resolver.update(APN_URI, value1, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3"});
ContentValues value2 = new ContentValues(1);
value2.put(Telephony.Carriers.CARRIER_ENABLED, 0);
resolver.update(APN_URI, value2, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3hotspot"});
/*enable Roaming APN*/
ContentValues value3 = new ContentValues(1);
value3.put(Telephony.Carriers.CARRIER_ENABLED, 1);
resolver.update(APN_URI, value3, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","EUInternet"});
}
// for test,should be removed
/*if(value == 0){
ContentValues value1 = new ContentValues(1);
value1.put(Telephony.Carriers.TYPE, "default");
resolver.update(APN_URI, value1, "numeric"+"=?"+ " AND "+"apn"+"=?", new String[]{"46000","cmnet"});
}else if(value == 1){
ContentValues value1 = new ContentValues(1);
value1.put(Telephony.Carriers.TYPE, "mms");
resolver.update(APN_URI, value1, "numeric"+"=?"+ " AND "+"apn"+"=?", new String[]{"46000","cmnet"});
}
*/
}
备注:注释的一段代码,用于本地模拟。旨在没有3UK USIM的情况下,验证逻辑的有效性。
动态切换APN,当网络漫游状态变化时
对应场景是,在 APN 设定为 EU roaming 时,若此时网络在本地,APN 要切到 3UK;若网络处于漫游,APN 要切到 EU。
具体的做法,在 GSMserviceStateTracker 的 handlePollStateResult 方法中侦测漫游状态改变,执行动态切换:
private void dynamicSwitchApn(){
String mccmnc = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
log( "dynamicSwitchApn mccmnc is " + mccmnc);
if(mccmnc != null && mccmnc.equals("23420")){
String CARRIERS_URI_STRING = "content://telephony/carriers";
Uri APN_URI = Uri.parse(CARRIERS_URI_STRING);
ContentResolver resolver = phone.getContext().getContentResolver();
int ApnModeValue = Settings.System.getInt(resolver,Settings.System.APN_MODE_SETTING, 0);
log( "ApnModeValue is " + ApnModeValue + " old roaming state = " + ss.getRoaming() + " new roaming state = " + newSS.getRoaming());
if((ApnModeValue == 1) && (newSS.getRoaming() != ss.getRoaming())){
if(!newSS.getRoaming()){
log( "dynamicSwitchApn enable home APN ");
/*disable Roaming APN*/
ContentValues value3 = new ContentValues(1);
value3.put(Telephony.Carriers.CARRIER_ENABLED, 0);
resolver.update(APN_URI, value3, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","EUInternet"});
/*enable home APN*/
ContentValues value1 = new ContentValues(1);
value1.put(Telephony.Carriers.TYPE, "default,mms,supl");
resolver.update(APN_URI, value1, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3"});
ContentValues value2 = new ContentValues(1);
value2.put(Telephony.Carriers.CARRIER_ENABLED, 1);
resolver.update(APN_URI, value2, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3hotspot"});
}else{
log( "dynamicSwitchApn disable home APN ");
/*disable home APN*/
ContentValues value1 = new ContentValues(1);
value1.put(Telephony.Carriers.TYPE, "mms");
resolver.update(APN_URI, value1, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3"});
ContentValues value2 = new ContentValues(1);
value2.put(Telephony.Carriers.CARRIER_ENABLED, 0);
resolver.update(APN_URI, value2, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","3hotspot"});
/*enable Roaming APN*/
ContentValues value3 = new ContentValues(1);
value3.put(Telephony.Carriers.CARRIER_ENABLED, 1);
resolver.update(APN_URI, value3, "numeric"+"=?"+ " AND "+"name"+"=?", new String[]{"23420","EUInternet"});
}
}
}
}
Q&A:
Q:在哪里调用dynamicSwitchApn()?
A:pollStateDone();之前