四、 Android 數據業務APN參數的創建

前面在DcTracker初始化過程中註冊了大量監聽器,其中有兩個監聽器可以觸發APN的創建過程:1、SIM載入完畢;2、APN改變。其中SIM載入完畢的註冊是EVENT_RECORDS_LOADED事件,APN改變是註冊了一個ApnChangeObserver類來監聽。
當SIM載入完畢時,將會觸發onRecordsLoaded()

private void onRecordsLoaded() {
    logi("onRecordsLoaded: createAllApnList");
    mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
            .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);

    createAllApnList();
    setInitialAttachApn();
    if (mPhone.mCi.getRadioState().isOn()) {
        if (DBG) log("onRecordsLoaded: notifying data availability");
        notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
    }
    setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
}

當APN改變時,用戶指定APN,將會觸發onApnChanged()

/**
 * Handles changes to the APN database.
 */
private void onApnChanged() {
    DctConstants.State overallState = getOverallState();
    boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
            overallState == DctConstants.State.FAILED);

    createAllApnList();
    setInitialAttachApn();
    cleanUpConnectionsOnUpdatedApns(!isDisconnected);

    // FIXME: See bug 17426028 maybe no conditional is needed.
    if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubId()) {
        setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
    }
}

兩個事件都會調用createAllApnList()和setInitialAttachApn(),分別是初始化當前卡可用的所有APN和設置默認聯網用的APN,首先看createAllApnList()

private void createAllApnList() {
    mAllApnSettings = new ArrayList<ApnSetting>();
    IccRecords r = mIccRecords.get();
    String operator = (r != null) ? r.getOperatorNumeric() : "";
    if (operator != null) {
        String selection = "numeric = '" + operator + "'";
        Cursor cursor = mPhone.getContext().getContentResolver().query(
                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
        if (cursor != null) {
            if (cursor.getCount() > 0) {
                mAllApnSettings = createApnList(cursor);
            }
            cursor.close();
        }
    }

    addEmergencyApnSetting(); // 添加emergencyApnSettings
    dedupeApnSettings();      // 去除重複的APN
    if (mAllApnSettings.isEmpty()) {
        mPreferredApn = null;
    } else {
        mPreferredApn = getPreferredApn();
        if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
            mPreferredApn = null;
            setPreferredApn(-1);
        }
    }
    setDataProfilesAsNeeded();
}

這裏面主要做了三件事
1、創建一個APN的列表,其中包含:當前SIM對應的APN、緊急APN;
APN的來源是telephony.db數據庫中表carries,數據庫的的參數是更新於apns-conf.xml文件
2、合併相同的APN;
在apns-conf.xml中的APN有可能又重複的
3、尋找一個當前Prefer的APN參數;
用戶使用一張卡時,可能手動選擇過使用的APN,因此,當用戶再次插拔卡後,getPreferredApn用於找出用戶之前選擇的APN
這個mPreferredApn會在buildWaitingApns中被檢查
如果mPreferredApn滿足用戶數據鏈接的需求,那麼buildWaitingApns就直接會返回mPreferredApn用於聯網使用的APN
如果mPreferredApn已經不能滿足用戶數據鏈接的需求時,纔會從mAllApnSettings(createAllApnList)中去找合適的APN用於聯網

這就是爲什麼setupData中getNextWaitingApn要去拿list的第0個APN聯網,因爲當mPreferredApn有效時,只會有一個APN存在apnContext中
以上就是APN的初始化和設置默認值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章