APN必读
发布时间:2018-07-19 16:31:28
发布时间:2018-07-19 16:31:28
一、基础知识
1、APN定义:
APN(Access Point Name)指一种网络接入技术,是通过手机上网时必须配置的一个参数,它决定了手机通过哪种接入方式来访问网络。
2、配置的APN xml文件,最终生成到以下目录:/system/etc/apns-conf.xml
3、APN数据会加载到 carriers 数据表中:
L及之前版本:/data/data/com.android.providers.telephony/databases/telephony.db
L之后的版本:/data/user_de/0/com.android.providers.telephony/databases/telephony.db
4、一般情况下,每个运营商有一组APN,这一组APN 中,有type="default"
类型和type="mms"类型,default类型用于上网,mms类型用于发送和接收彩信。例如:
二:配置APN
1、 需要注意的字段值
Excel 文件中的authentication对应apns-conf.xml 中authtype
Excel 文件中的Protocol对应apns-conf.xml 中protocol
Excel 文件中的Roaming protocol对应apns-conf.xml 中roaming_protocol
Excel 文件中的mvno_type对应apns-conf.xml 中mvno_type
Excel 文件中的mvno_match_data对应apns-conf.xml 中mvno_match_data
例如:
authtype的取值如下:
对应的UI界面显示如下:
注意:如果Excel表中authentication的值为none,则XML中记得配置
authtype="0",如果APN没有配置authtype ,则显示:“未设置”,数据库中存储的值为“-1”,而不是none的值“0”
如果是虚拟运营商,记得配置mvno_type 和 mvno_match_data
如果不是,则无需配置这两个字段。
备注:配置:mvno_type=”none”和mvno_match_data=”none”是错误的
mvno_type 和 mvno_match_data 的配置请参考:
[FAQ09811] 如何区分MNO和MVNO
注意:配置完毕MVNO的APN后(apns-conf.xml),一定要记得配置相应的Virtual-spn-conf-by-ef*.xml 文件
虚拟运营商的名称显示,会用到Virtual-spn-conf-by-ef*.xml文件,如果没有配置,会导致运营商名称显示有误!
protocol 和 roaming_protocol 的取值如下:
对应的UI界面显示如下:
数据库中存储的值:
注意:以下配置是错误的:
我通过中国移动的卡做过实验,如果按照以上配置,界面上显示是不对的:
是否对网络连接有影响还有待确认!
正确配置为:
备注:如果XML中没有配置protocol 和 roaming_protocol,则默认为 IPv4,数据库中存储的值为:IP
注意:目前查看E183L/E188F 项目上关于protocol 和 roaming_protocol 的配置存在问题,请相应的同事修改。
三、加载APN
1、Settings 模块的加载( 设置—更多—移动网络—接入点名称(APN) )
/packages/apps/Settings/src/com/android/settings/ApnSettings.java
关键代码如下:
private void fillList() {
……
Log.d(TAG, "mccmnc = " + mccmnc);
String where = "numeric=\"" + mccmnc
+ "\" AND NOT (type='ia' AND (apn=\"\" OR apn IS NULL))";
/// M: for plug-in
where = mApnExt.getFillListQuery(where, mccmnc);
Log.d(TAG, "fillList where: " + where);
String order = mApnExt.getApnSortOrder(Telephony.Carriers.DEFAULT_SORT_ORDER);
/Log.d(TAG, "fillList sort: " + order);
Cursor cursor = getContentResolver().query(
Telephony.Carriers.CONTENT_URI,
new String[] { "_id", "name", "apn", "type", "mvno_type", "mvno_match_data", "sourcetype" }, where, null, order);
/// @}
if (cursor != null) {
Log.d(TAG, "fillList, cursor count: " + cursor.getCount());
List
List
List
List
}
while (!cursor.isAfterLast()) {
if (selectable) {
addApnToList(pref, mnoApnList, mvnoApnList, r, mvnoType, mvnoMatchData);
} else {
addApnToList(pref, mnoMmsApnList, mvnoMmsApnList, r, mvnoType, mvnoMatchData);
}
cursor.moveToNext();
}
cursor.close();
if (!mvnoApnList.isEmpty()) {
mnoApnList = mvnoApnList;
mnoMmsApnList = mvnoMmsApnList;
// Also save the mvno info
}
……
}
根据addAPNToList可知,如果配置了虚拟运营商的参数,就会加载到mvnoList列表中,但是否可以加载进来,还有一层判断,ApnSeting.mvnoMatches, 即虚拟运营商的参数必须跟SIM卡中参数保持一致;如果是实体运营商,会加载到mnoList列表中。
例如:最近西班牙项目前方报,
关键Log信息:
经查看发现Movistar是实体卡,但配置了虚拟运营商参数,导致ApnSeting.mvnoMatches条件不满足,无法加载到mvnoList列表中,而mnoList也为空,最终APN界面没有显示!
解决方案:删除Movistar APN的虚拟运营商参数即可。
补充说明如下:
public static final class Carriers implements BaseColumns {
/**
* The default sort order for this table.
*/
publicstaticfinal String DEFAULT_SORT_ORDER = "name ASC";
}
M 平台上是根据 Carriers 数据表中 name 的升序来加载APN的(name 字段对应 XML 中的 carrier)
M平台上设置默认APN可根据以下FAQ去修改
[FAQ17853] M上默认接入点apn显示
L 平台上加载数据时,没有去设置order的值,默认是根据XML中APN的先后顺序加载的。因此L平台上,设置默认APN时,只要把默认APN放在一组APN的最前面即可
2、 DcTracker文件中APN的加载
caseDctConstants.EVENT_RECORDS_LOADED:
onRecordsLoaded();
break;
private void onRecordsLoaded() {
if (DBG) log("onRecordsLoaded: createAllApnList");
createAllApnList();
}
/**
* Based on the sim operator numeric, create a list for all possible
* Data Connections and setup the preferredApn.
*/
PrivatevoidcreateAllApnList() {
…………
if (operator != null) {
String selection = "numeric = '" + operator + "'"; String orderBy = "_id";
if (DBG) log("createAllApnList: selection=" + selection);
Cursor cursor = mPhone.getContext().getContentResolver().query(Telephony.Carriers.CONTENT_URI, null, selection, null, orderBy);
if (cursor != null) {
if (cursor.getCount() > 0) {
mAllApnSettings = createApnList(cursor);
hasResult = true;
}
cursor.close();
}
}
…………
if(DBG)log("createAllApnList:XmAllApnSettings=" + mAllApnSettings);
}
privateList
List
List
IccRecords r = mIccRecords.get();
if (cursor.moveToFirst()) {
do {
ApnSettingapn = makeApnSetting(cursor);
if (apn == null) {
continue;
}
if (apn.hasMvnoParams()) {
if (r != null&&ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
mvnoApns.add(apn);//加载虚拟运营商的APN
}
} else {
mnoApns.add(apn);//加载实体运营商的APN
}
} while (cursor.moveToNext());
}
List
if (DBG) log("createApnList: X result=" + result);
return result;
}
根据createApnList可知,如果配置了虚拟运营商的参数,就会加载到mvnoApns列表中,但是否可以加载进来,还有一层判断,ApnSetting.mvnoMatches, 即虚拟运营商的参数必须跟SIM卡中参数保持一致;如果是实体运营商,会加载到mnoApns列表中。因此,如果虚拟运营商参数设置不正确,会导致:mvnoApns和mnoApns都为空。
备注:数据连接这一块,会用到APN的信息。因此,务必确保APN配置正确,否则会引起无法建立数据连接,无法发送/接收彩信等Bug。
四、疑问
没有找到把apns-conf.xml导入到carriers 数据表的代码,有知道的可以添加到此文件中。