ContentProvider of the Call System for Android development-SMS acquisition and backup
Patience and persistence are painful, but gradually bring you benefits.
After sticking to one thing for a while, we may have a lot of abandonment thoughts in our mind. Maybe after several years of giving up, we will wonder what will happen if we stick to it ..., but unfortunately, we didn't stick to it. Recently, I am too lazy to remind myself not to lose myself and keep learning. In the previous article, we talked about how to create your own ContentProvider. If you have mastered the content of the previous article, you can easily master this article today. The main content of this article is to call Google engineers to provide us with a good ContentProvider. That is to say, after Google defines a ContentProvider, it will give us a Uri. With this Uri, we can get the corresponding data. It doesn't matter if you haven't called the system Uri. Today we will use a case to explain how to call it in detail. Not much nonsense. If you have any mistakes, please criticize and correct them. If you have any questions, please leave a message. Through this blog, you will learn the following knowledge points ① how to call the system's ContentProvider ② How To Get text message data through Google's Uri ③ a case study back up and restore text messages on mobile phones1. How to call the system's ContentProviderIn fact, after reading the previous article, this question will be well understood. After Google engineers write the ContentProvider, they will certainly give us a Uri, as long as they know this Uri, we can get the data we need. For example, if you want to get the text message information, you must have the Uri corresponding to it. You want to get the image library and contact information, there must also be a corresponding Uri. After knowing the corresponding Uri, you can access the ContentResolver object based on the Uri. For more information, see: content provider of Android development-create your own ContentProvider (detailed description). Today's main task is to complete a case study to obtain the system's text message data.2. Cases (acquisition, backup, and recovery of text message data)Next, let's take a look at the case. The main function of this case is to obtain the text message information based on Uri, and back up and restore it as follows:
This image demonstrates this function. First, send a few text messages to the simulator in DDMS, then run our program, click back up, and then delete all the messages after the backup is successful, then, click Restore in our program to open the text message interface and find that the deleted text message has been restored. This is the function we want to implement.
First, let's analyze how to achieve the above results. If you want to back up text messages, you must first obtain the SMS list. This step is simple because Google has encapsulated it, all we need to do is to use Uri to query the text message library. Then, we need to save the data to the SD card in XML format after obtaining the data, of course you can use other methods, as long as you can restore it. At last, the system parses the XML file in the specified path and inserts the parsed text message data into the system's text message list based on the Uri. This is an idea. It doesn't matter if you don't understand it. The source code and their analysis will be shown below. After learning about the general idea, another important task is to look at the text message table structure in the simulator. Its path is data-> com. android. providers. in telephony-> databases, if you export it and open it with Sqlite data, you can see that the data structure is as follows, here, we only care about the threads table and the sms table. The structure of the threads table is as follows: _ id: used to distinguish different phone numbers. The system will assign different _ IDs to different phone numbers. Date: the time when the message is received (if multiple messages from the same phone number are received and one message is not read, date indicates the time when the last message is received) message_count: number of received messages read: 0. indicates not read. 1. It indicates that read is rarely used for other fields. Here we will not introduce it more. The structure of the sms table is as follows: _ id: used to distinguish different text messages.
Date: the time when the SMS is received.
Read: Table 0 is not read, table 1 is read
Body: indicates that the preparation of the specific text message content is still one step away from code writing. Which step? Is the Uri used to access this database. The Uri used to access text messages mainly includes the following content: // sms/all text messages
Content: // sms/inbox
Content: // sms/sent
Content: // sms/draft
Content: // sms/outbox sender
Content: // sms/failed to send
Content: // sms/queued list to be sent in this case, we use content: // sms/, because it is a backup, it must be a backup of all text messages, let's take a look at the code. The first thing to do is to retrieve the SMS list based on the Uri. Here we create an SmsManage class and put the backup and recovery methods in this class. The code for obtaining the SMS list is as follows:
/*** Get the SMS List ** @ return */public List
GetSmsList () {// retrieve the Uri of all text messages uri = Uri. parse ("content: // sms/"); // obtain the ContentResolver object ContentResolver contentResolver = mContext. getContentResolver (); // query the text message data Cursor cursor = contentResolver Based on the Uri. query (uri, null, null); if (null! = Cursor) {Log. I (TAG, "cursor. getCount (): "+ cursor. getCount (); // Add it to the smsList (SMS list) while (Cursor. moveToNext () {int _ id = cursor. getInt (cursor. getColumnIndex ("_ id"); int type = cursor. getInt (cursor. getColumnIndex ("type"); String address = cursor. getString (cursor. getColumnIndex ("address"); String body = cursor. getString (cursor. getColumnIndex ("body"); String date = cursor. getString (cursor. getColumnIndex ("date"); SmsData smsData = new SmsData (_ id, type, address, body, date); smsList. add (smsData);} cursor. close ();} return smsList ;}
You can see that the above Code is to query the text message database in the Mobile Phone Based on the content: // sms/Uri, and get a Cursor that contains a text message. Then, traverse the Cursor and add the required data to the smsList. In this way, the text message data will be obtained, because our function is to back up the text message, so we need to save the data in the smsList collection to the local device, in order to facilitate the text message recovery to read the saved file, the problem arises. How can we save the smsList set as a file to the local device? Of course, there are many methods. Here we use XmlSerializer to serialize it. When we need to restore it, we can use XmlPullParser to deserialize it to obtain the backup data, it sounds very big. In fact, it is very simple to operate on xml. Next let's take a look at the serialized code, which will generate an xml file for the data in the above collection smsList and save it locally. The Code is as follows:
/*** Save the text message data to the SD card */public void saveSmsToSdCard () {smsList = getSmsList (); // obtain a serialized object XmlSerializer xmlSerializer = Xml. newSerializer (); // Save the generated xml file to the sd card named "sms. xml "File file = new File (Environment. getExternalStorageDirectory (), "sms. xml "); FileOutputStream fos; try {fos = new FileOutputStream (file); xmlSerializer. setOutput (fos, "UTF-8"); xmlSerializer. startDocument ("UTF-8", true); xmlSerializer. startTag (null, "smss"); xmlSerializer. startTag (null, "count"); xmlSerializer. text (smsList. size () + ""); xmlSerializer. endTag (null, "count"); for (SmsData smsData: smsList) {xmlSerializer. startTag (null, "sms"); xmlSerializer. startTag (null, "_ id"); xmlSerializer. text (smsData. get_id () + ""); System. out. println ("smsData. get_id () = "+ smsData. get_id (); xmlSerializer. endTag (null, "_ id"); xmlSerializer. startTag (null, "type"); xmlSerializer. text (smsData. getType () + ""); System. out. println ("smsData. getType = "+ smsData. getType (); xmlSerializer. endTag (null, "type"); xmlSerializer. startTag (null, "address"); xmlSerializer. text (smsData. getAddress () + ""); System. out. println ("smsData. getAddress () = "+ smsData. getAddress (); xmlSerializer. endTag (null, "address"); xmlSerializer. startTag (null, "body"); xmlSerializer. text (smsData. getBody () + ""); System. out. println ("smsData. getBody () = "+ smsData. getBody (); xmlSerializer. endTag (null, "body"); xmlSerializer. startTag (null, "date"); xmlSerializer. text (smsData. getDate () + ""); System. out. println ("smsData. getDate () = "+ smsData. getDate (); xmlSerializer. endTag (null, "date"); xmlSerializer. endTag (null, "sms");} xmlSerializer. endTag (null, "smss"); xmlSerializer. endDocument (); fos. flush (); fos. close (); Toast. makeText (mContext, "backup completed", Toast. LENGTH_SHORT ). show ();} catch (FileNotFoundException e) {e. printStackTrace ();} catch (IllegalArgumentException e) {e. printStackTrace ();} catch (IllegalStateException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace ();}}
By calling the preceding method, the text message is saved to the local device in xml format. After running this method, you can see the sms. xml file in the SD card and export it to see the following format:
Note: in fact, the xml file contains a line. Here, I manually changed it to the above format to make it clearer. After saving it locally, the last step is to deserialize the xml file and insert one piece of data into the text message database. The corresponding code is as follows:
/*** Insert the data in the xml File in the specified path to the SMS database * @ param path */public void restoreSms (String path) {file File = new File (path ); // get an xml-parsed object XmlPullParser parser = Xml. newPullParser (); try {FD = new FileInputStream (file); parser. setInput (FCM, "UTF-8"); ContentValues values = null; int type = parser. getEventType (); while (type! = XmlPullParser. END_DOCUMENT) {switch (type) {case XmlPullParser. START_TAG: if ("count ". equals (parser. getName () {} else if ("sms ". equals (parser. getName () {values = new ContentValues ();} else if ("type ". equals (parser. getName () {values. put ("type", parser. nextText ();} else if ("address ". equals (parser. getName () {values. put ("address", parser. nextText ();} else if ("body ". equals (parser. getName () {values. put ("body", parser. nextText ();} else if ("date ". equals (parser. getName () {values. put ("date", parser. nextText ();} break; case XmlPullParser. END_TAG: if ("sms ". equals (parser. getName () {// If the node is sms Uri uri = Uri. parse ("content: // sms/"); ContentResolver resolver = mContext. getContentResolver (); resolver. insert (uri, values); // insert data into the database System. out. println ("inserted successfully"); values = null; //} break;} type = parser. next () ;}} catch (FileNotFoundException e) {e. printStackTrace ();} catch (XmlPullParserException e) {e. printStackTrace ();} catch (NumberFormatException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace ();}}
In the above method, we can see whether the xml END_TAG is "sms". If yes, it indicates that the message "type", "address", "body", and "date" have been obtained., then insert the data into the database according to the Uri, and then restore the text message to be read.
END_DOCUMENTIt indicates that the xml file has been read, and all the messages backed up are restored. Now, this article is here. If you find any errors in this article, please leave a message if you have any questions. Thank you. If you think this article is helpful to you, just like it. Thank you for your support.