apn管理
来源:互联网 发布:mac acl 编辑:程序博客网 时间:2024/05/18 03:54
1、简介:
每个运营商都有特定的一些apn,android 系统怎么识别和管理这些apn,本文将对这个问题做一些讨论和研究。
2、分析
2.1 流程简介
神秘的apn到底是怎么一回事,为什么插一张移动卡就会有China Mobile 的3个apn,这些数据怎么获取的?如下图所示:
流程简介:
1)系统启动的时候会将apns.xml 、apns-conf.xml中定义的运营商的apn加载到数据中去;
2)在系统设置里面会根据当前插入的sim卡去查询sim卡运营商相关的apn,并显示出来。
说明:从流程的第一步可以看出运营商的apn都定义在apns.xml 、apns-conf.xml这两个xml中,如果要让系统支持某运营商,我们必须添加相应的apn到xml中,否则系统将不会查询到该卡的apn,会影响用户的上网等功能。
2.2涉及的文件
- com.android.providers.telephony.TelephonyProvider
- etc/apns-conf.xml
- /framework/base/core/res/res/apns.xml
- com.android.settings.ApnSettings
2.3 加载数据到数据库
加载数据到数据库是在TelephonyProvider中完成的,该类是一个ContentProvider,ContentProvider就不用我在这给大家介绍啦yixia ;
1)首先是创建对应的数据库表,以下是其核心代码:
- @Override
- 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," +
- "ipversion TEXT," +
- "current INTEGER);");
- initDatabase(db);
- }
- private void initDatabase(SQLiteDatabase db) {
- // Read internal APNS data
- Resources r = mContext.getResources();
- XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
- int publicversion = -1;
- try {
- XmlUtils.beginDocument(parser, "apns");
- publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
- loadProfiles(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".
- 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");
- // Sanity check. Force internal version and confidential versions to agree
- int confversion = Integer.parseInt(confparser.getAttributeValue(null, "version"));
- if (publicversion != confversion) {
- throw new IllegalStateException("Internal APNS file version doesn't match "
- + confFile.getAbsolutePath());
- }
- loadProfiles(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) { }
- }
- }
2.4 系统设置--查询显示
1)设置中查询显示在上面的操作过后咱们就有了一张叫做carriers的表,该表存放了所有的apn以及其相关的一些属性之类的;
2)设置中的ApnSettings.java就是进入设置apn显示的界面,那该类怎么去加载属于自己的apn列表
调用 fillList()方法填充这个列表,以下是该方法的核心代码:
- private void fillList() {
- String where = "numeric=\""
- + getOperatorNumeric()
- + "\"";
- Cursor cursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] {
- "_id", "name", "apn", "type"}, where,
- Telephony.Carriers.DEFAULT_SORT_ORDER);
- PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");
- apnList.removeAll();
- ArrayList<Preference> mmsApnList = new ArrayList<Preference>();
- mSelectedKey = getSelectedApnKey();
- cursor.moveToFirst();
- while (!cursor.isAfterLast()) {
- String name = cursor.getString(NAME_INDEX);
- String apn = cursor.getString(APN_INDEX);
- String key = cursor.getString(ID_INDEX);
- String type = cursor.getString(TYPES_INDEX);
- ApnPreference pref = new ApnPreference(this);
- if (name.contains("ro.")){
- //for china union
- if (ChinaUnionPLMN.equals(getOperatorNumeric())){
- if (type.equals("default")){
- if (name.contains("wap")){
- name = getString(R.string.china_union_wap_apn_name);
- }else{
- name = getString(R.string.china_union_net_apn_name);
- }
- }
- if (type.equals("mms")) name = getString(R.string.china_union_mms_apn_name);
- if (type.equals("supl")) name = getString(R.string.china_union_supl_apn_name);
- /**
- * changed by zaokun,fix bug 12113,union apn can't edit
- */
- // pref.setIsDefault(true);
- }
- }
- pref.setKey(key);
- pref.setTitle(name);
- pref.setSummary(apn);
- pref.setPersistent(false);
- pref.setOnPreferenceChangeListener(this);
- boolean selectable = ((type == null) || !type.equals("mms"));
- pref.setSelectable(selectable);
- if (selectable) {
- if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
- pref.setChecked();
- }
- apnList.addPreference(pref);
- } else {
- mmsApnList.add(pref);
- }
- cursor.moveToNext();
- }
- cursor.close();
- for (Preference preference : mmsApnList) {
- apnList.addPreference(preference);
- }
- }
一、调用getOperatorNumeric()方法获取sim卡OperatorNumeric;以下是该方法的核心代码:
- private String getOperatorNumeric() {
- String numeric;
- numeric = TelephonyManager.getTelephonyProperty
- (TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, mSubscription, "");
- if (TextUtils.isEmpty(numeric)) {
- numeric = TelephonyManager.getTelephonyProperty
- (TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, mSubscription, "");
- }
- return numeric;
- }
三、ui显示
3、总结
vpn的加载大致过程就是这样,其中可以看到最核心的是从两个xml里面加载apn数据到数据库,设置根据opratorNumber进行查询显示。当然这里的讲解不是很具体,如果大家希望对每个细节进行分析,可能还需要对每段代码仔细阅读。
- apn管理
- apn管理
- apn管理
- Android APN管理 (接入点管理)
- APN
- APN
- apn
- APN
- APN
- APN
- APN
- APN
- GPRS管理与创建APN拨号连接
- Android下代码实现APN管理设置
- Android下代码实现APN管理设置
- GPRS管理与创建APN拨号连接
- GPRS管理与创建APN拨号连接
- GPRS管理与创建APN拨号连接
- xml和json区别总结
- 文件操作
- poj 2481 树状数组
- IOS通过OTA部署App
- Linux Force telnet / ssh to use crtl-H for backspace
- apn管理
- 关于Java的内存模型,使用的是尚学堂的图
- 扩展方法
- xmlrpc Warning: xmlrpc_is_fault() expects parameter 1 to be array的处理
- Mozilla布道师:HTML5在移动端没有未来?
- 七年,Google数据中心从保密向透明的转变
- Android 开发工具:Intellij
- 查询缓存
- 输出10000以内的所有素数