Andoird 添加系统默认配置APN

一、概述

        近段时间有个项目需求,在欧洲的时候SIM卡无法识别,但是在国内可以。很明显这是APN设置的问题。于是想在android系统中添加默认的APN配置

二、APN默认配置文件位置

        Android系统的APN配置存储在telephony.db这个数据库中,数据库生成后路径在/data/data/com.android.providers.Telephony。注意手机第一次开机如果没有插卡的话是不会生成这个数据库的,一定要识别到一次插卡以后这个数据库才存在。

    分析源码数据库生成源码packages/providers/TelephonyProvider/src/com/android/providers/telephony/TelephonyProvider.java

private static int getVersion(Context context) {
            // Get the database version, combining a static schema version and the XML version
            Resources r = context.getResources();
            XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
            try {
                XmlUtils.beginDocument(parser, "apns");
                int publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
                return DATABASE_VERSION | publicversion;
            } catch (Exception e) {
                Log.e(TAG, "Can't get version of APN database", e);
                return DATABASE_VERSION;
            } finally {
                parser.close();
            }
}
    这是数据库创建的helper类中获取数据库版本的方法,可以看到这里取的文件是com.android.internal.R.xml.apns,这个文件在frameworks/base/core/res/apns.xml下。可是打开发现里面是空的,就一个版本号,这是google Android默认的数据库配置文件,我们一般不在这里改。
    继续往下,是数据库onCreate()回调方法,创建了表和各个字段,最后调用initDatabase()方法。

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"));
                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".
            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());
                }

                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) { }
            }
        }
       可以看出系统APN默认的配置其实是来自于system/etc/apns-conf.xml这个文件,这个目录是out目录下的,生成它的地方在device/目录下的apns-conf.xml中,找不到的用find命令找一下,根据项目的不同路径不同。然后在apns-conf.xml中可以看到许多已经存在的apn信息,在末尾添加上你需要配置的新的APN即可。

三、默认选中配置好的APN

      任务还没有结束,我们配置好以后,重烧系统开机,插入欧洲卡Vodaphone卡,发现APN列表中的确是有我们新添加的APN了,可是它没有被默认选中,依旧得我们手动选中它才行,这显然不人性化。  而其他的例如移动和联通卡却有默认选上的功能,这应该是Vodaphone卡在大陆本身的问题吧。不过没有关系,我们在代码中加两句话即可

  packages/apps/Settings/src/com/android/settings/ApnSettings.java中,找到fillList()方法,该方法中定位到

if (selectable) {
   if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
     pref.setChecked();
   }
     apnList.addPreference(pref);
    } else {
     mmsApnList.add(pref);
}  
      可以在这儿添加判断,如果name和apn和numeric满足自己配置的条件,就直接给它setChceked。
if ((mSelectedKey != null) && mSelectedKey.equals(key)) 
     例如我的是这样添加
//add by zhiming.su start
                if("Vodaphone".equals(name) && "internetd.gdsp".equals(apn) && where.contains("20404")){
                     pref.setChecked();
                     apnList.addPreference(pref);
                     Log.v("szm","Vodaphone");
                }else{//add by zhiming.su end
                if (selectable) {
                    if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
                        pref.setChecked();
                    }
                    apnList.addPreference(pref);
                } else {
                    mmsApnList.add(pref);
                }
                }

--------------------- 
作者:Smoyan_ 
来源:CSDN 
原文:https://blog.csdn.net/u012761076/article/details/79062118 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值