ANDROID_ Monitor SMS data changes via Contentobserver

Source: Internet
Author: User
Tags dateformat

1. Introduction

In some models such as millet, can not receive the system sent SMS broadcast. Only through the observer contentobserver, to listen to the changes in SMS data

2.SMS Data Introduction

Content://sms/inbox Inbox
Content://sms/sent has been sent
Content://sms/draft Draft
Content://sms/outbox Outbox
content://sms/failed Send failed
content://sms/queued to send list

In the simulator Outbox no query to the data, in the simulator found long time also did not find the Outbox, very depressed.
The SMS related fields in the database are as follows:
_id a self-increment field, starting from 1
thread_id serial number, same Sender ID
Address Sender's mobile number
Ordinal of person contact list, stranger null
Date Sent from
Protocol protocol, divided into: 0 sms_rpoto, 1 mms_proto
Read whether reading 0 unread, 1 read
Status state-1 receive, 0 complete, pending, failed
Type
all = 0;
INBOX = 1;
SENT = 2;
DRAFT = 3;
OUTBOX = 4;
FAILED = 5;
QUEUED = 6;
Body SMS Content
Service_center SMS Service Center number
The subject of subject SMS
Reply_path_present Tp-reply-path
Locked

Retrieving the data method is simple:
Uri uri = uri.parse ("Content://sms/inbox");
Cursor cur = this.managedquery (URI, NULL, NULL, NULL, or NULL);
if (Cur.movetofirst ()) {
do{
for (int j = 0; J < Cur.getcolumncount (); j + +) {
info = "Name:" + cur.getcolumnname (j) + "=" + cur.getstring (j);
LOG.I ("====>", info);
}
}while (Cur.movetonext ());
}

Managedquery will eventually convert the arguments to SQL statements to send messages to SQLite, so the parameters are similar to SQL statements, so you can add SQL functions to the query fields.
such as new string[] projection = new string[]{"Count (*) as Count"} and so on.
The arguments in the managedquery are in turn URI,
Query fields query the field array, or you can put all fields that need to be queried into a single word characters
For example new projection[]{"_id", "thread_id"} and New projection[]{"_id,thread_id"} are consistent.
As with SQL, field names are case insensitive
The condition does not have a where SQL conditional character, and if there are parameters then use? Alternative, such as "_id=?" and thread_id =? Or type = ' 1 ' "
An array of parameter parameters in the condition corresponding to the above conditions
Sort without order by sort string, such as _id desc, type
If the query field in Parameter Null,sql is "*", the related condition is blank

You can also use Getcontentresolver () to get a contentresolver,
Getcontentresolver (). Query () also returns a cursor object, with parameters that are consistent with managedquery.
But use Contentresolver object to update, delete and insert a data times SecurityException. There appears to be no permission to add permissions in Manifest.xml:
<uses-permission android:name= "Android.permission.WRITE_SMS" ></uses-permission>
Then delete the SMS:
This.getcontentresolver (). Delete (Uri.parse ("content://sms"), "_id=?", New string[]{"3"});
Delete succeeded.
The URL content://sms replaced with content://sms/also succeeded, but the other URL when the program error, such as Content://sms/inbox

Looking at the source code of Android, SMS supports the following protocols:
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", "Sim", Sms_all_sim);
Surlmatcher.adduri ("SMS", "sim/#", Sms_sim);

Among these, the protocols supported in the Delete method are:
Sms_all Delete SMS table data based on conditions in parameters
SMS_ALL_ID Deleting SMS table data based on _id
SMS_CONVERSATIONS_ID Delete SMS table data according to THREAD_ID, can bring other conditions
Sms_raw_message Delete RAW tables based on conditions in parameters
sms_status_pending Delete the Sr_pending table based on the conditions in the parameter
Sms_sim deleting data from SIM card

Try sms_conversations_id: "Content://sms/conversations/3", delete thread_id= "3", _id= "5" Data
In emulator control in Eclipse, send three data to the simulator with 13800, and then send a message with 13900
This.getcontentresolver (). Delete (Uri.parse ("CONTENT://SMS/CONVERSATIONS/3"), "_id=?", New string[]{"5"});
A piece of data was successfully deleted.
In the database each sender's thread_id is the same, but not fixed, if the entire data of a sender is deleted,
And then change to a new number when sending a text message, thread_id is assigned with the largest id+1 in the database.

The update supports a number of protocols:
Sms_raw_message
Sms_status_pending
Sms_all
Sms_failed
sms_queued
Sms_inbox
Sms_sent
Sms_draft
Sms_outbox
Sms_conversations
sms_all_id
sms_inbox_id
sms_failed_id
sms_sent_id
sms_draft_id
sms_outbox_id
sms_conversations_id
sms_status_id

Test with sms_inbox_id:
Contentvalues CV = new Contentvalues ();
Cv.put ("thread_id", "2");
Cv.put ("Address", "00000");
Cv.put ("Person", "11");
Cv.put ("date", "11111111");
This.getcontentresolver (). Update (Uri.parse ("CONTENT://SMS/INBOX/4"), CV, NULL, NULL);
Too strong, even thread_id can be modified.

Insert-supported protocols:
Sms_all
Sms_inbox
Sms_failed
sms_queued
Sms_sent
Sms_draft
Sms_outbox
Sms_raw_message
Sms_status_pending
Sms_attachment
sms_new_thread_id

When inserting data into an SMS table, the type is automatically set according to the protocol.
If date is not set in the incoming data, it is automatically set to the current system time; The read flag is set to 1 when the Sms_inbox protocol is not
Sms_inbox protocol, the system automatically queries and sets the person
ThreadID is null or 0 o'clock, the system is automatically set

has been worrying about making "send failed" messages, now to do one:
Content://sms/failed
Contentvalues CV = new Contentvalues ();
Cv.put ("_id", "99");
Cv.put ("thread_id", "0");
Cv.put ("Address", "9999");
Cv.put ("Person", "888");
Cv.put ("date", "9999");
Cv.put ("protocol", "0");
Cv.put ("read", "1");
Cv.put ("Status", "1");
Cv.put ("type", "0");
Cv.put ("Body", "");
This.getcontentresolver (). Insert (Uri.parse ("content://sms/failed"), CV);
The type is set to 5,thread_id set to 1

See if you can dig up the SMS functionality again. Let's make a bad query first:
Getcontentresolver (). Query (Uri.parse ("content://sms/"), New string[]{"A"}, "B", NULL, NULL);
Log output of the wrong SQL statement:
SELECT A from SMS WHERE (b) ORDER by date DESC
There is no group by in the Query method, and if you want to do statistics on text messages, it is too slow to traverse the cursor.
In the SQL language, group by is behind the where, so try to find a way in the condition parameter:
Android organization SQL statement when the conditions are added (), then spell a group by come out:
Getcontentresolver (). Query (Uri.parse ("content://sms/"), New string[]{"count (*) as Count, thread_id"}, "1=1") Group by (t HREAD_ID ", NULL, NULL);
Then the output of sql= SELECT count (*) as Count, thread_id from SMS WHERE (1=1) group BY (thread_id) ORDER by date DESC
What if you want to query the URI without a corresponding table, for example, to know which tables are in the MMSSMS.DB database,
The query table is URI-bound, and it is not possible to cobble together in the condition parameters.
So let's move forward and see if we can get out of the field parameters.
To query other tables, the key is to remove the system-fixed added from SMS,
Use the comments in SQL,
Getcontentresolver (). Query (Uri.parse ("content://sms/"), New string[]{"* from sqlite_master WHERE type = ' table '--"}, Nu ll, NULL, NULL);
Then the output of the sql=select * from sqlite_master WHERE type = ' table '--The From SMS ORDER by date DESC is actually able to run.
And then further, if you join the ";" can also run, haha, then build the table, delete the table, update the table can do whatever it is.
Getcontentresolver (). Query (Uri.parse ("content://sms/"), New string[]{"* from Sms;select * from thrreads;--"}, NULL, NUL L, NULL);

3. Example

public class Smscontentobserver extends Contentobserver {private Context mcontext; string[] projection = new string[] {"Address", "body", "date", "type", "read"};p ublic Smscontentobserver (Context context , Handler Handler) {super (Handler); mcontext = context;} @Overridepublic void OnChange (Boolean selfchange) {uri uri = uri.parse ("Content://sms/inbox"); Cursor C = mcontext.getcontentresolver (). Query (URI, NULL, NULL, NULL, "Date desc"), if (c! = null) {while (C.movetonext ()) {SimpleDateFormat DateFormat = new SimpleDateFormat ("Yyyy-mm-dd hh:mm:ss");D ate d = new Date (C.getlong (c.getcolumnindex ("date")); String date = Dateformat.format (d); StringBuilder sb = new StringBuilder (), Sb.append ("sender's mobile number:" + c.getstring (C.getcolumnindex ("Address")). Append ("Message content : "+ c.getstring (C.getcolumnindex (" Body ")). Append (" Whether to view: "+ c.getint (C.getcolumnindex (" read ")). Append (" type: "+ c.ge TInt (C.getcolumnindex ("type"))). append (date); LOG.I ("xxx", sb.tostring ());} C.close ();}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.