简介
Mms 数据库代码的位置在/packages/providers/TelephonyProvider,这里还包括APN的部分。从AndroidManifest中可以看到,其注明sharedUserId为android.uid.phone,运行在com.android.phone进程中。TelephonyProvider是APN的数据库,SmsProvider、MmsProvider、MmsSmsProvider为Mms的数据库。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.providers.telephony"
coreApp="true"
android:sharedUserId="android.uid.phone">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:process="com.android.phone"
android:allowClearUserData="false"
android:allowBackup="false"
android:label="@string/app_label"
android:icon="@drawable/ic_launcher_phone">
<provider android:name="TelephonyProvider"
android:authorities="telephony"
android:multiprocess="true" />
<provider android:name="SmsProvider"
android:authorities="sms"
android:multiprocess="true"
android:readPermission="android.permission.READ_SMS"
android:writePermission="android.permission.WRITE_SMS" />
<provider android:name="MmsProvider"
android:authorities="mms"
android:multiprocess="true"
android:readPermission="android.permission.READ_SMS"
android:writePermission="android.permission.WRITE_SMS">
<grant-uri-permission android:pathPrefix="/part/" />
<grant-uri-permission android:pathPrefix="/drm/" />
</provider>
<provider android:name="MmsSmsProvider"
android:authorities="mms-sms"
android:multiprocess="true"
android:readPermission="android.permission.READ_SMS"
android:writePermission="android.permission.WRITE_SMS" />
</application>
</manifest>
关于APN数据
APN数据项参考其数据库的建立:
@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);");
initDatabase(db);
}
APN数据的载入流程:
1. 读取internal APNS data,位于$ANDROID_SRC_HOME/frameworks/base/core/res/res/xml/apns.xml
这个文件实际上是提供了一个version的值publicversion,这个值在载入实际的APN配置时会起作用(也就是external APNS时)
2. 读取external APNS data,位于$ANDROID_SRC_HOME/out/target/product/generic/system/etc/apns-conf.xml
3. CARRIERS_TABLE中的"current INTEGER"项指定目前使用的APN设置
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) { }
}
}