Manage SMS in Android

Source: Internet
Author: User

In order to see the code convenient, while on the internet Google data, while looking at the Android Java source code.

Accidentally found a class, originally Android will all the text messages are stored in the mmssms.db.

This class is not available in the public SDK and cannot be used directly. So I wrote a sqliteopenhelper, but a SQL exception occurred while querying.

I can't seem to do anything, but according to the information on the Internet can copy the DB file to achieve SMS data backup.

Now that each DB is related to the package name, build a project for to try and see if it can be successful.

Result output please execute ' adb uninstall ' in a shell,android security is very strong.

Cannot access the database directly, only through the protocol to access the database,
First put out the relevant agreement:
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:
_idOne self-increment field, starting from 1
thread_idSerial number, same sender's ID
AddressSender's mobile number
PersonOrdinal of the contact list, null for strangers
DateDate of shipment
ProtocolAgreement, divided into: 0 sms_rpoto, 1 mms_proto
ReadRead 0 unread, 1 read
StatusStatus-1 Receive, 0 complete, pending, failed
all = 0;
INBOX = 1;
SENT = 2;
DRAFT = 3;

BodySMS Content
Service_centerSMS Service Center Number
subjectThe subject of SMS

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 ()) {
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 FieldsQuery the field array, or you can put all the fields you want to query into one 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
conditionsThe SQL conditional character without where, and if there are parameters? Alternative, such as "_id=?" and thread_id =? Or type = ' 1 ' "
parameters in the conditionAn array of parameter numbers corresponding to the above conditions
Sortstring without order by sort, 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   According to the conditions in the parameters;
sms_all_id          by _ ID Delete SMS table data  
sms_conversations_id      Delete SMS table data based on thread_id, with additional criteria  
sms_raw_message                Delete Raw table   according to the conditions in the parameter;
sms_status_pending           Delete sr_pending table   According to the conditions in the parameter;
sms_sim                                    remove data from the 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_ inbox    
SMS_ outbox    
SMS_ conversations_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:


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:

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

The system even the minimum data check did not do Ah, Google is too kind to the programmer.

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:


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 ' --< /c0> "}, NULL, NULL, and NULL);

Then the output of the sql=select * from sqlite_master WHERE type = ' table ' -- from the SMS ORDER by date DESC

Incredibly 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, NULL, NULL);

Unfortunately, only the first SQL statement was run, and Android seems to have some control over the key issues.

But support--also very good, so you can query all the tables in the database, but also can be multi-table

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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: and provide relevant evidence. A staff member will contact you within 5 working days.