如果要支持多个运营商的支持就要在apns-conf.xml中加入。
APN概念
1)用户发出GPRS登录请求,请求中包括由移动公司为GPRS专网系统专门分配的专网APN;
2)根据请求中的APN,SGSN向DNS服务器发出查询请求,找到与企业服务器平台连接的GGSN,并将用户请求通过GTP隧道封装送给GGSN;
3)GGSN将用户认证信息(包括手机号码、用户账号、密码等)通过专线送至Radius进行认证;
4)Radius认证服务器看到手机号等认证信息,确认是合法用户发来的请求,向DHCP服务器请求分配用户地址;
5)Radius认证通过后,由Radius向GGSN发送携带用户地址的确认信息;
6)用户得到了IP地址,就可以携带数据包,对GPRS专网系统信息查询和业务处理平台进行访问。
Android自带的内部APN配置文件
frameworks/base/core/res/res/xml/apns.xml文件内容:
- <!-- If you edit this version, also edit the version in the partner-supplied
- apns-conf.xml configuration file -->
- <apns version="7">
- </apns>
该文件被编译到res.apk中,通过android的资源管理器进行访问。
第三方提供的APN配置文件
在Android源码build目录下,通过搜索apns-conf.xml可以找到在各个board中分别有配置:
在编译该product时会将device/generic/goldfish/data/etc/apns-conf.xml文件拷贝到system/etc/目录下,最后打包到system.img中。
APN配置加载
android通过telephony.db数据库中的 carriers表来保存所有的APN配置信息
packages/providers/TelephonyProvider/src/com/android/providers/telephony/TelephonyProvider.java文件中的内部类DatabaseHelper用于创建telephony.db数据库
- public void onCreate(SQLiteDatabase db) {
- // Set up the database schema
- db.execSQL("CREATE TABLE " + CARRIERS_TABLE +
- "(_id INTEGER PRIMARY KEY," +
- "name TEXT," +
- "numeric TEXT," +
- "mcc TEXT," +
- "mnc TEXT," +
- "apn TEXT," +
- "user TEXT," +
- "server TEXT," +
- "password TEXT," +
- "proxy TEXT," +
- "port TEXT," +
- "mmsproxy TEXT," +
- "mmsport TEXT," +
- "mmsc TEXT," +
- "authtype INTEGER," +
- "type TEXT," +
- "current INTEGER," +
- "protocol TEXT," +
- "roaming_protocol TEXT," +
- "carrier_enabled BOOLEAN," +
- "preset BOOLEAN default false," +
- "bearer INTEGER);");
- //从APN配置xml文件中读取APN配置,并存储到数据表carriers中
- initDatabase(db);
- }
- private void initDatabase(SQLiteDatabase db) {
- // Read internal APNS data
- Resources r = mContext.getResources();
- //读取frameworks/base/core/res/res/xml/apns.xml文件
- XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
- int publicversion = -1;
- try {
- XmlUtils.beginDocument(parser, "apns");
- //读取APN配置版本信息
- publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
- //加载APN配置信息,并保存到数据表中
- loadApns(db, parser);
- } catch (Exception e) {
- Log.e(TAG, "Got exception while loading APN database.", e);
- } finally {
- parser.close();
- }
- // Read external APNS data (partner-provided)
- XmlPullParser confparser = null;
- // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
- //读取system/etc/apns-conf.xml文件
- File confFile = new File(Environment.getRootDirectory(), PARTNER_APNS_PATH);
- FileReader confreader = null;
- try {
- confreader = new FileReader(confFile);
- confparser = Xml.newPullParser();
- confparser.setInput(confreader);
- XmlUtils.beginDocument(confparser, "apns");
- // 读取第三方提供的APN配置版本号
- int confversion = Integer.parseInt(confparser.getAttributeValue(null, "version"));
- //判断第三方提供的APN配置版本号是否与Android自带的APN配置版本号相同
- if (publicversion != confversion) {
- throw new IllegalStateException("Internal APNS file version doesn't match "
- + confFile.getAbsolutePath());
- }
- //如果版本号相同,读取APN配置信息
- loadApns(db, confparser);
- } catch (FileNotFoundException e) {
- // It's ok if the file isn't found. It means there isn't a confidential file
- // Log.e(TAG, "File not found: '" + confFile.getAbsolutePath() + "'");
- } catch (Exception e) {
- Log.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
- } finally {
- try { if (confreader != null) confreader.close(); } catch (IOException e) { }
- }
- }