Android APN加载流程

时间:2021-03-25 15:56:32

Version: Android 4.4.4

一、关于APN

1、Android的APN(Access Point Name)数据预置在/system/etc/apns-conf.xml中:

2、源码:apns-conf.xml来自apns-full-conf.xml,编译系统的时候Copy到/system/etc/目录下:

PRODUCT_COPY_FILES += 
     device/sample/etc/apns-full-conf.xml:system/etc/apns-conf.xml

Android APN加载流程


二、APN加载过程

1、系统检查到SIM卡正常后从/system/etc/apns-conf.xml解析数据,存放到数据库:telephony.db

/data/data/com.android.providers.telephony/databases/telephony.db

sqlite> select * from carriers where numeric='46001';
1113|China Unicom 3G|46001|460|01|3gnet|||||80||||-1|default,supl|1|IP|IP|1|0||
1114|中国联通 3g 彩信 (China Unicom)|46001|460|01|3gwap||||||10.0.0.172|80|http://mmsc.myuni.com.cn|-1|mms|1|IP|IP|1|0||
1115|China Unicom MMS|46001|460|01|uniwap||||||10.0.0.172|80|

telephony.db数据库的建立对应TelephonyProvider.java文件:

packages\providers\telephonyprovider\src\com\android\providers\telephony\TelephonyProvider.java
public class TelephonyProvider extends ContentProvider{
    private static final String DATABASE_NAME = "telephony.db";
    private static class DatabaseHelper extends SQLiteOpenHelper {
        public DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, getVersion(context));
            mContext = context;
        }

        @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," +
                    "current INTEGER," +
                    "protocol TEXT," +
                    "roaming_protocol TEXT," +
                    "carrier_enabled BOOLEAN," +
                    "bearer INTEGER," +
                    "mvno_type TEXT," +
                    "mvno_match_data TEXT);");

            initDatabase(db);
        }

        private void initDatabase(SQLiteDatabase db) {
            // Read internal APNS data
            // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
            File confFile = new File(Environment.getRootDirectory(), PARTNER_APNS_PATH);
            loadApns(db, confparser);
		}
	}
}

2、检索APN,根据MCC、MNC的值组合(46001)来查询telephony.db数据库:

http://www.gpsspg.com/bs/mnc.htm

Android APN加载流程

frameworks\opt\telephony\src\java\com\android\internal\telephony\dataconnection\DcTracker.java
/**
 * Based on the sim operator numeric, create a list for all possible
 * Data Connections and setup the preferredApn.
 */
private void createAllApnList() {
	mAllApnSettings = new ArrayList<ApnSetting>();
	IccRecords r = mIccRecords.get();
	// getOperatorNumeric()返回MCC+MNC的组合值
	String operator = (r != null) ? r.getOperatorNumeric() : "";
	if (operator != null) {
		String selection = "numeric = '" + operator + "'";
		// query only enabled apn.
		// carrier_enabled : 1 means enabled apn, 0 disabled apn.
		selection += " and carrier_enabled = 1";
		if (DBG) log("createAllApnList: selection=" + selection);

		Cursor cursor = mPhone.getContext().getContentResolver().query(
				Telephony.Carriers.CONTENT_URI, null, selection, null, null);

		if (cursor != null) {
			Rlog.e(LOG_TAG, "cursor != null");
			Rlog.e(LOG_TAG, "cursor.getCount(): " + cursor.getCount());
			if (cursor.getCount() > 0) {
				mAllApnSettings = createApnList(cursor);
			}
			cursor.close();
		}
	}
}
这样,在Setting界面就可以看到设备的APN信息;若APN缺少,4G、3G等移动网络异常!