sms提供者分析
android 7.1源码分析(packages/providers/TelephonyProvider)
AndroidManifest.xml
<!-- This is a singleton provider that is used by all users.
A new instance is not created for each user. And the db is shared
as well. -->
<provider android:name="SmsProvider"
android:authorities="sms"
android:multiprocess="false"
android:exported="true"
android:singleUser="true"
android:readPermission="android.permission.READ_SMS" />
由此可知短信主机名:sms
短信的内容提供者:com.android.providers.telephony.SmsProvider
所需读权限:android.permission.READ_SMS
SmsProvider.java
private static final int SMS_ALL = 0;
private static final int SMS_ALL_ID = 1;
private static final int SMS_INBOX = 2;
private static final int SMS_INBOX_ID = 3;
private static final int SMS_SENT = 4;
private static final int SMS_SENT_ID = 5;
private static final int SMS_DRAFT = 6;
private static final int SMS_DRAFT_ID = 7;
private static final int SMS_OUTBOX = 8;
private static final int SMS_OUTBOX_ID = 9;
private static final int SMS_CONVERSATIONS = 10;
private static final int SMS_CONVERSATIONS_ID = 11;
private static final int SMS_RAW_MESSAGE = 15;
private static final int SMS_ATTACHMENT = 16;
private static final int SMS_ATTACHMENT_ID = 17;
private static final int SMS_NEW_THREAD_ID = 18;
private static final int SMS_QUERY_THREAD_ID = 19;
private static final int SMS_STATUS_ID = 20;
private static final int SMS_STATUS_PENDING = 21;
private static final int SMS_ALL_ICC = 22;
private static final int SMS_ICC = 23;
private static final int SMS_FAILED = 24;
private static final int SMS_FAILED_ID = 25;
private static final int SMS_QUEUED = 26;
private static final int SMS_UNDELIVERED = 27;
private static final UriMatcher sURLMatcher =
new UriMatcher(UriMatcher.NO_MATCH);
static {
sURLMatcher.addURI("sms", null, SMS_ALL);
sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
sURLMatcher.addURI("sms", "sent", SMS_SENT);
sURLMatcher.addURI("sms", "sent/#", SMS_SENT_ID);
sURLMatcher.addURI("sms", "draft", SMS_DRAFT);
sURLMatcher.addURI("sms", "draft/#", SMS_DRAFT_ID);
sURLMatcher.addURI("sms", "outbox", SMS_OUTBOX);
sURLMatcher.addURI("sms", "outbox/#", SMS_OUTBOX_ID);
sURLMatcher.addURI("sms", "undelivered", SMS_UNDELIVERED);
sURLMatcher.addURI("sms", "failed", SMS_FAILED);
sURLMatcher.addURI("sms", "failed/#", SMS_FAILED_ID);
sURLMatcher.addURI("sms", "queued", SMS_QUEUED);
sURLMatcher.addURI("sms", "conversations", SMS_CONVERSATIONS);
sURLMatcher.addURI("sms", "conversations/*", SMS_CONVERSATIONS_ID);
sURLMatcher.addURI("sms", "raw", SMS_RAW_MESSAGE);
sURLMatcher.addURI("sms", "attachments", SMS_ATTACHMENT);
sURLMatcher.addURI("sms", "attachments/#", SMS_ATTACHMENT_ID);
sURLMatcher.addURI("sms", "threadID", SMS_NEW_THREAD_ID);
sURLMatcher.addURI("sms", "threadID/*", SMS_QUERY_THREAD_ID);
sURLMatcher.addURI("sms", "status/#", SMS_STATUS_ID);
sURLMatcher.addURI("sms", "sr_pending", SMS_STATUS_PENDING);
sURLMatcher.addURI("sms", "icc", SMS_ALL_ICC);
sURLMatcher.addURI("sms", "icc/#", SMS_ICC);
//we keep these for not breaking old applications
sURLMatcher.addURI("sms", "sim", SMS_ALL_ICC);
sURLMatcher.addURI("sms", "sim/#", SMS_ICC);
}
public boolean onCreate() {
setAppOps(AppOpsManager.OP_READ_SMS, AppOpsManager.OP_WRITE_SMS);
mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
return true;
}
由onCreate函数可知创建数据库的代码在MmsSmsDatabaseHelper类中
MmsSmsDatabaseHelper.java
@Override
public void onCreate(SQLiteDatabase db) {
createMmsTables(db);
createSmsTables(db);
createCommonTables(db);
createCommonTriggers(db);
createMmsTriggers(db);
createWordsTables(db);
createIndices(db);
}
private void createSmsTables(SQLiteDatabase db) {
// N.B.: Whenever the columns here are changed, the columns in
// {@ref MmsSmsProvider} must be changed to match.
db.execSQL("CREATE TABLE sms (" +
"_id INTEGER PRIMARY KEY," +
"thread_id INTEGER," +
"address TEXT," +
"person INTEGER," +
"date INTEGER," +
"date_sent INTEGER DEFAULT 0," +
"protocol INTEGER," +
"read INTEGER DEFAULT 0," +
"status INTEGER DEFAULT -1," + // a TP-Status value
// or -1 if it
// status hasn't
// been received
"type INTEGER," +
"reply_path_present INTEGER," +
"subject TEXT," +
"body TEXT," +
"service_center TEXT," +
"locked INTEGER DEFAULT 0," +
"sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
"error_code INTEGER DEFAULT 0," +
"creator TEXT," +
"seen INTEGER DEFAULT 0" +
");");
/**
* This table is used by the SMS dispatcher to hold
* incomplete partial messages until all the parts arrive.
*/
db.execSQL("CREATE TABLE raw (" +
"_id INTEGER PRIMARY KEY," +
"date INTEGER," +
"reference_number INTEGER," + // one per full message
"count INTEGER," + // the number of parts
"sequence INTEGER," + // the part number of this message
"destination_port INTEGER," +
"address TEXT," +
"sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
"pdu TEXT);"); // the raw PDU for this part
db.execSQL("CREATE TABLE attachments (" +
"sms_id INTEGER," +
"content_url TEXT," +
"offset INTEGER);");
/**
* This table is used by the SMS dispatcher to hold pending
* delivery status report intents.
*/
db.execSQL("CREATE TABLE sr_pending (" +
"reference_number INTEGER," +
"action TEXT," +
"data TEXT);");
// Restricted view of sms table, only sent/received messages
db.execSQL("CREATE VIEW " + SmsProvider.VIEW_SMS_RESTRICTED + " AS " +
"SELECT * FROM " + SmsProvider.TABLE_SMS + " WHERE " +
Sms.TYPE + "=" + Sms.MESSAGE_TYPE_INBOX +
" OR " +
Sms.TYPE + "=" + Sms.MESSAGE_TYPE_SENT + ";");
}
由此可知sms.db数据库包含以下字段:
_id,thread_id,address,person,date,date_sent,protocol,read,status,type,reply_path_present,subject,body,service_center,locked,sub_id,error_code,creator,seen