Android call history Backup implementation code

Source: Internet
Author: User

(1) Preface

By default, Android provides the contact backup function to the SD card (the code is in com. android. in the vcard package), we can export the contact. the vcf file is stored in the SD card. If you change your mobile phone, you can import contacts from the SD card file. So can we make similar functions for call records? The answer is yes!

(2) Export call records

Since it is a backup call record, it must include the Export and Import functions. Here we will first export the call record.

1. According to the call record export specification, the exported file generally ends with a. vcl suffix and the content in the middle isCopy codeThe Code is as follows: BEGIN: VCALL
SLOT: 0 // card SLOT No. 0: Single-card mobile phone 1: Dual-card mobile phone card SLOT 1 2: Dual-card mobile phone card SLOT 2
TYPE: 1 // phone TYPE 1: Access Phone, 2: outgoing call 3: Missed call
Date: 14:11:12 GMT // The GMT time is recorded when you back up the call or time from the deleted point. the time corresponding to the time zone of the mobile phone is displayed when you restore the call.
NUMBER: + 86134 xxxxx // recipient's NUMBER
DURATION: 5 // DURATION, in seconds
END: VCALL

This is the storage format of a call record. It starts with BEGIN: VCALL and ends with END: VCALL. // It indicates the meaning of the field, just to make everyone understand it and will not be imported into the actual file. So let's see how to export it.

2. query the call record list

OK... since the call record is saved, you must first query the call record
In Android, A CallLogProvider is provided to meet your needs. The name configured in the system is "call_log". Therefore, you only need to provide such a Uri for query, for example:

Copy codeThe Code is as follows: Uri uri = Uri. parse ("context: // call_log/CILS ");
Cursor c = mContext. getContentResolver (). query (uri, xxx, xxx );

In this way, all call records can be queried to obtain the cursor ..

3. Extract the fields and data to be saved from the cursor and write the data to the file.

Now that the cursor is found, we will find the field data from the cursor that we want to write to the file. For example, the basic information is as follows:

Copy codeThe Code is as follows: protected Object doInBackground (Object... params) {// background asynchronous Task, which queries data in the background and writes files. Each time a record is exported, a progress bar is updated.
Super. doInBackground (params );
String path = (String) params [0];

Uri queryUri = Uri. parse ("content: // call_log/CILS ");
Cursor queryedCursor = mContext. getContentResolver (). query (queryUri,
Null,
Null,
Null,
Null );
If (queryedCursor = null | queryedCursor. getCount () = 0 ){
Return-1;
}

Object [] message = new Object [1];
Message [0] = queryedCursor. getCount ();
PublishProgress (message );

StringBuilder sb = new StringBuilder ();
OutputStream outputStream = null;
Writer writer = null;
Try {
OutputStream = new FileOutputStream (path );
Writer = new BufferedWriter (new OutputStreamWriter (outputStream ));

For (queryedCursor. moveToFirst ();! QueryedCursor. isAfterLast ();
QueryedCursor. moveToNext ()){
If (mCancel ){
Break;
}
Sb. setLength (0 );
Sb. append ("BEGIN: VCALL"). append ("\ n ");
Int subId = queryedCursor. getInt (queryedCursor. getColumnIndex ("sub_id "));
Int callType = queryedCursor. getInt (
QueryedCursor. getColumnIndex ("type"); // incall/outcall/missed call
Long date = queryedCursor. getLong (queryedCursor. getColumnIndex ("date "));
String gmtData = getGTMDatetimeString (date );
String number = queryedCursor. getString (queryedCursor. getColumnIndex ("formatted_number "));
String duration = queryedCursor. getString (queryedCursor. getColumnIndex ("duration "));

Sb. append ("SLOT:"). append (subId). append ("\ n ");
Sb. append ("TYPE:"). append (callType). append ("\ n ");
Sb. append ("DATE:"). append (gmtData). append ("\ n ");
Sb. append ("NUMBER:"). append (number). append ("\ n ");
Sb. append ("DURATION:"). append (duration). append ("\ n ");
Sb. append ("END: VCALL"). append ("\ n ");
Writer. write (sb. toString (); // write a record to the file.
Message [0] =-1;
PublishProgress (message); // publish a message so that the main thread updates the progress bar
}

} Catch (Exception e ){
Log. d (TAG, "", e );
Return 0;
} Finally {
Try {
If (writer! = Null ){
Writer. close ();
}
If (outputStream! = Null ){
OutputStream. close ();
}
} Catch (Exception e2 ){
Log. d (TAG, "", e2 );
Return 0;
}
}
Return 1;
}

This is just the general code. If you have any requirements in the future, you can modify the code without having to know the author .. No copyright required ~~~

(3) Import call records to the database

1. Well, if you import data, you must first search for the files ending with the. vcl Suffix in the SD card! Start a thread and perform iterative search. As follows:Copy codeThe Code is as follows: private class VCLScanThread extends Thread implements OnCancelListener, OnClickListener {// start Thread to search, and a progress bar is displayed to the user.
Private boolean mCanceled; // variable indicates whether the user has cancel.
Private boolean mGotIOException;
Private File mRootDirectory;
Private static final String LOG_TAG = "VCLScanThread ";

// To avoid recursive link.
Private Set <String> mCheckedPaths;

Private class CanceledException extends Exception {
}

Public VCLScanThread (File sdcardDirectory, String scanType ){
MCanceled = false;
MGotIOException = false;
MRootDirectory = sdcardDirectory;
MCheckedPaths = new HashSet <String> ();
MProgressDialogForScanVCard = new ProgressDialog (Main. this );
MProgressDialogForScanVCard. setTitle (R. string. dialog_scan_calllist_progress_title );
MProgressDialogForScanVCard. show (); // The search progress bar is displayed.
}

@ Override
Public void run (){
If (mAllVclFileList = null ){
MAllVclFileList = new Vector <VCLFile> (); // start searching. First, clear the list. This list is used to save the found. vcl file (including file name, file path, and so on)
} Else {
MAllVclFileList. clear ();
}

Try {
GetVCardFileRecursively (mRootDirectory); // iteratively searches all. vcl files on the SD card
} Catch (CanceledException e ){
MCanceled = true;
} Catch (IOException e ){
MGotIOException = true;
}

If (mCanceled ){
MAllVclFileList = null;
}

MProgressDialogForScanVCard. dismiss ();
MProgressDialogForScanVCard = null;

If (mGotIOException ){
// RunOnUiThread (new DialogDisplayer (R. id. dialog_io_exception ));
} Else if (mCanceled ){
// Finish ();
} Else {
Int size = mAllVclFileList. size ();
If (size = 0 ){
Toast. makeText (Main. this, R. string. error_scan_vcl_not_found,
Toast. LENGTH_SHORT). show ();
} Else {
RunOnUiThread (new Runnable (){
@ Override
Public void run (){
StartVCardSelectAndImport (); // after the search is completed, a dialog box is displayed asking users to select the files to import.
}
});

}
}
}

Private void getVCardFileRecursively (File directory)
Throws CanceledException, IOException {
If (mCanceled ){
Throw new CanceledException ();
}

// E.g. secured directory may return null toward listFiles ().
Final File [] files = directory. listFiles ();
If (files = null ){
Final String currentDirectoryPath = directory. getCanonicalPath ();
Final String secureDirectoryPath =
MRootDirectory. getCanonicalPath (). concat (SECURE_DIRECTORY_NAME );
If (! TextUtils. equals (currentDirectoryPath, secureDirectoryPath )){
Log. w (LOG_TAG, "listFiles () returned null (directory:" + directory + ")");
}
Return;
}
For (File file: directory. listFiles ()){
If (mCanceled ){
Throw new CanceledException ();
}
String canonicalPath = file. getCanonicalPath ();
If (mCheckedPaths. contains (canonicalPath )){
Continue;
}

MCheckedPaths. add (canonicalPath );

String endFix = ". vcl ";
If (file. isDirectory ()){
GetVCardFileRecursively (file); // if it is a directory, continue iterative search
} Else if (canonicalPath. toLowerCase (). endsWith (endFix. end of vcl. If yes and readable, put it in the list to be searched.
File. canRead ()){
String fileName = file. getName ();
VCLFile vclFile = new VCLFile (
FileName, canonicalPath, file. lastModified ());
MAllVclFileList. add (vclFile );

}
}
}

Public void onCancel (DialogInterface dialog ){
MCanceled = true;
}

Public void onClick (DialogInterface dialog, int which ){
If (which = DialogInterface. BUTTON_NEGATIVE ){
MCanceled = true;
}
}
}

2. after selecting the file to be imported, it will parse the file and save it to the database after parsing a BEGIN: VCALL and END: VCALL (you can also Parse Multiple files and save them to the database at one time)

Copy codeThe Code is as follows: private void parseItemInter (String name, String value) throws Exception {
If ("SLOT". inclusignorecase (name )){
MValues. put ("sub_id", value );
} Else if ("TYPE". inclusignorecase (name )){
MValues. put ("type", value );
} Else if ("DATE". inclusignorecase (name )){
MValues. put ("date", getGTMDatetime (value ));
} Else if ("NUMBER". inclusignorecase (name )){
MValues. put ("formatted_number", value );
MValues. put ("number", value );
} Else if ("DURATION". inclusignorecase (name )){
MValues. put ("duration", value );
} Else {
Throw new Exception ("Unknown type, name:" + name + "value:" + value );
}
}

// Submit a call record to the database
Uri uri = Uri. parse ("content: // call_log ");
MContext. getContentResolver (). insert (uri, mValues );

This is basically what it means, but the details must be controlled. For example, the file is invalid, not starting with BEGIN: VCALL. You also need to control it.

This is basically the case. I hope to provide some reference for you in the future...

Related Article

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.