数据业务建立流程之常规APN参数的创建(原)
来源:互联网 发布:java scanner用法 编辑:程序博客网 时间:2024/05/16 01:06
区别于前面的紧急APN,这里的APN参数主要指常规的SIM卡APN参数,手机在上网时必须传递正确的APN参数给运营商才可以接入移动网络,而常规APN参数的创建是由监听器触发的。
前面在DcTracker初始化过程中注册了大量监听器,其中有两个监听器可以触发APN的创建过程:1、SIM载入完毕;2、APN改变。这两个事件所导致的APN创建流程也都是类似的,分别是:
【当SIM载入完毕时】,将会触发onRecordsLoaded():
1、创建一个APN的列表,其中包含:当前SIM对应的APN、紧急APN;
2、合并相同的APN;
3、寻找一个当前Prefer的APN参数;
前面介绍过,在TelephonyProvider初始化过程中从"etc/apns-conf.xml"配置文件中载入了预置的APN参数存入数据库,而现在需要根据当前SIM信息把匹配的APN读取出来。
而读取过程就是先获取当前SIM的PLMN,然后创建数据库查询条件"numeric = 当前SIM PLMN",然后通过createApnList()方法将数据库查到的信息创建为APN参数。
接下来又经历了一次添加紧急APN的过程,这个过程和前面初始化DcTracker时添加紧急APN过程完全一致。
然后就需要通过dedupeApnSettings()方法去掉APN列表中重复的APN参数:
再然后就需要从当前众多的APN参数中寻找一个当前合适的(prefer)APN参数,该APN要求其对应的PLMN属于当前的SIM。他的来源是跟随其他预置的APN一起被添加到数据库中的,其特别之处就在于多了“preferapn_no_update”的属性。他的作用就是作为备用APN来发起数据连接。
至此,所有APN准备工作就绪,接下来就是等待需要上网时,将当前APN激活,然后发起数据连接过程。
前面在DcTracker初始化过程中注册了大量监听器,其中有两个监听器可以触发APN的创建过程:1、SIM载入完毕;2、APN改变。这两个事件所导致的APN创建流程也都是类似的,分别是:
【当SIM载入完毕时】,将会触发onRecordsLoaded():
private void onRecordsLoaded() { mAutoAttachOnCreationConfig = mPhone.getContext().getResources().getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation); //创建APN参数 createAllApnList(); setInitialAttachApn(); if (mPhone.mCi.getRadioState().isOn()) { notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED); } //尝试发起数据业务 setupDataOnConnectableApns(Phone.REASON_SIM_LOADED); }【当APN改变时】,将会触发onApnChanged():
private void onApnChanged() { DctConstants.State overallState = getOverallState(); boolean isDisconnected = (overallState == DctConstants.State.IDLE || overallState == DctConstants.State.FAILED); if (mPhone instanceof GSMPhone) { ((GSMPhone)mPhone).updateCurrentCarrierInProvider(); } //创建APN参数 createAllApnList(); setInitialAttachApn(); //清除旧的连接 cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED); //尝试发起数据业务 setupDataOnConnectableApns(Phone.REASON_APN_CHANGED); }从上面两个过程对比我们发现,他们都通过两个步骤进行APN的创建,分别是createAllApnList()和setInitialAttachApn(),他们的作用分别是创建APN和设置默认APN。
下面分别来介绍这个过程。
一、创建APN过程
private void createAllApnList() { mAllApnSettings = new ArrayList<ApnSetting>(); IccRecords r = mIccRecords.get(); //获取该SIM的PLMN String operator = (r != null) ? r.getOperatorNumeric() : ""; if (operator != null) { String selection = "numeric = '" + operator + "'"; //查询当前SIM的APN数据库 Cursor cursor = mPhone.getContext().getContentResolver().query(Telephony.Carriers.CONTENT_URI, null, selection, null, null); if (cursor != null) { if (cursor.getCount() > 0) { //根据APN参数创建APN列表 mAllApnSettings = createApnList(cursor); } cursor.close(); } } //添加紧急APN addEmergencyApnSetting(); //合并类似的APN dedupeApnSettings(); if (mAllApnSettings.isEmpty()) { mPreferredApn = null; } else { //寻找prefer APN mPreferredApn = getPreferredApn(); if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) { mPreferredApn = null; setPreferredApn(-1); } } setDataProfilesAsNeeded(); }这个方法主要经历了三个步骤:
1、创建一个APN的列表,其中包含:当前SIM对应的APN、紧急APN;
2、合并相同的APN;
3、寻找一个当前Prefer的APN参数;
前面介绍过,在TelephonyProvider初始化过程中从"etc/apns-conf.xml"配置文件中载入了预置的APN参数存入数据库,而现在需要根据当前SIM信息把匹配的APN读取出来。
而读取过程就是先获取当前SIM的PLMN,然后创建数据库查询条件"numeric = 当前SIM PLMN",然后通过createApnList()方法将数据库查到的信息创建为APN参数。
接下来又经历了一次添加紧急APN的过程,这个过程和前面初始化DcTracker时添加紧急APN过程完全一致。
然后就需要通过dedupeApnSettings()方法去掉APN列表中重复的APN参数:
private void dedupeApnSettings() { ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>(); int i = 0; while (i < mAllApnSettings.size() - 1) { ApnSetting first = mAllApnSettings.get(i); ApnSetting second = null; int j = i + 1; while (j < mAllApnSettings.size()) { second = mAllApnSettings.get(j); if (apnsSimilar(first, second)) { ApnSetting newApn = mergeApns(first, second); mAllApnSettings.set(i, newApn); first = newApn; mAllApnSettings.remove(j); } else { j++; } } i++; } }这里就一个去重的算法问题,这个算法的原理就是,经过一个循环,可以找到某个参数所有相同的组合。
再然后就需要从当前众多的APN参数中寻找一个当前合适的(prefer)APN参数,该APN要求其对应的PLMN属于当前的SIM。他的来源是跟随其他预置的APN一起被添加到数据库中的,其特别之处就在于多了“preferapn_no_update”的属性。他的作用就是作为备用APN来发起数据连接。
private ApnSetting getPreferredApn() { if (mAllApnSettings.isEmpty()) { return null; } Cursor cursor = mPhone.getContext().getContentResolver().query( PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" }, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER); if (cursor != null) { mCanSetPreferApn = true; } else { mCanSetPreferApn = false; } if (mCanSetPreferApn && cursor.getCount() > 0) { int pos; cursor.moveToFirst(); pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)); for(ApnSetting p : mAllApnSettings) { log("getPreferredApn: apnSetting=" + p); if (p.id == pos && p.canHandleType(mRequestedApnType)) { log("getPreferredApn: X found apnSetting" + p); cursor.close(); return p; } } } if (cursor != null) { cursor.close(); } return null; }
从其获取途径可以看到,他的URI("content://telephony/carriers/preferapn_no_update")中多了"preferapn_no_update"的参数,这也是该APN的特殊之处。
二、设置默认APN过程
protected void setInitialAttachApn() { ApnSetting iaApnSetting = null; ApnSetting defaultApnSetting = null; ApnSetting firstApnSetting = null; if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) { firstApnSetting = mAllApnSettings.get(0); for (ApnSetting apn : mAllApnSettings) { if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_IA) && apn.carrierEnabled) { iaApnSetting = apn; break; } else if ((defaultApnSetting == null) && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) { //找到类型是APN_TYPE_DEFAULT的APN参数作为默认attach用 log("setInitialApn: defaultApnSetting=" + apn); defaultApnSetting = apn; } } } ApnSetting initialAttachApnSetting = null; if (iaApnSetting != null) { initialAttachApnSetting = iaApnSetting; } else if (mPreferredApn != null) { initialAttachApnSetting = mPreferredApn; } else if (defaultApnSetting != null) { initialAttachApnSetting = defaultApnSetting; } else if (firstApnSetting != null) { initialAttachApnSetting = firstApnSetting; } if (initialAttachApnSetting == null) { } else { //设置Attach用的APN参数 mPhone.mCi.setInitialAttachApn(initialAttachApnSetting.apn, initialAttachApnSetting.protocol, initialAttachApnSetting.authType, initialAttachApnSetting.user, initialAttachApnSetting.password, null); } }在上面这个过程中,遍历当前所有的APN列表,寻找类型是APN_TYPE_DEFAULT的APN,然后将该APN参数传递给Modem用于初始的Attach。
至此,所有APN准备工作就绪,接下来就是等待需要上网时,将当前APN激活,然后发起数据连接过程。
3 0
- 数据业务建立流程之常规APN参数的创建(原)
- 数据业务建立流程之常规APN参数的创建
- 数据业务建立流程之常规APN参数的创建
- 数据业务建立流程之常规APN参数的创建
- 数据业务建立流程之APN参数的激活(原)
- 数据业务建立流程之APN参数的激活
- 数据业务建立流程之APN参数的激活
- 数据业务建立流程之APN参数的激活
- 数据业务建立流程之DcTracker创建过程(原)
- 四、 Android 数据业务APN参数的创建
- 数据业务建立流程之发起网络连接过程(原)
- 数据业务建立流程之DcTracker创建过程
- 数据业务建立流程之DcTracker创建过程
- 数据业务建立流程之DcTracker创建过程
- 【Android 数据业务解析】APN参数创建
- Android数据业务发起流程(原)
- 五、 数据业务APN参数的开机默认使能
- 数据业务建立流程之发起网络连接过程
- 二叉树算术库
- Java基础之集合函数-Collection接口
- 第九周项目2-对称矩阵压缩存储的实现与应用(1)
- PendingIntent用法注意
- 摄像机矩阵详解
- 数据业务建立流程之常规APN参数的创建(原)
- 8.11.1 Internal Locking Methods
- Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 16169 (Thread-1035)
- 第七周 负数把正数赶出队
- 欢迎使用CSDN-markdown编辑器
- 走马灯相册
- 页签示例
- T-SQL 学习之路之数据库完整性之域完整性(一)
- strtok独到深刻的讲解