Restore sms from Google Drive

In previous post I described how to backup sms in Google Drive.

In this post I will try to restore sms from a backup saved in Google Drive, and I will also use the new app data folder.
As always, it is just an example.

It is quite simple, but pay attention, you will write your SMS Content Provider.
In order to backup sms, in our app we can do these steps: In our example we will search our backup file in a Google Drive folder or in appdata folder.
.
   Files.List request = mService
                          .files()
                          .list()
                          .setQ("mimeType = '" + MIME_TEXT_PLAIN
                                + "' and '" + folderId
                                + "' in parents ");
If you want to use appdata folder, folderId is "appdata".
As I have described in previous post, to be able to use your Application Data folder, request access to the following scope:
https://www.googleapis.com/auth/drive.appdata

The ideal would be to show the user a list of backups from which he can choose.In our case, I will just use the first file.
With backup file, we retrieve text content:
private String getContentFile(File file) {
  String result;
  
  if (file!=null && file.getDownloadUrl() != null
         && file.getDownloadUrl().length() > 0) {
   
   try {
      GenericUrl downloadUrl = new GenericUrl(file.getDownloadUrl());
      HttpResponse resp = mService.getRequestFactory().buildGetRequest(downloadUrl).execute();
      InputStream inputStream = null;

      try {
         inputStream = resp.getContent();
         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
         StringBuilder content = new StringBuilder();
         char[] buffer = new char[1024];
         int num;

         while ((num = reader.read(buffer)) > 0) {
             content.append(buffer, 0, num);
         }
         result = content.toString();
     
     } finally {
        if (inputStream != null) {
            inputStream.close();
        }
    }
  } catch (IOException e) {
     // An error occurred.
     e.printStackTrace();
     return null;
  }
 } else {
   // The file doesn't have any content stored on Drive.
   return null;
 }
 
 return result;
}
I made ​​a small change to the code of the previous article, to have a text in Json format.You can find it in Github repository.
 {"messages":
      [{"body":"xxxxxxxxxxxxxxxxx.",
        "protocol":"0",
        "_id":"62",
        "service_center":"+39XXXXXXXXX",
        "status":"-1",
        "address":"xxxxxxx",
        "error_code":"0",
        "read":"1",
        "date_sent":"1366725726000",
        "displayName":"xxxxxx",
        "type":"1",
        "date":"1366725710918",
        "thread_id":"3"
       },
      {"body":"xxxxxxxxxxx",
       "protocol":"0",
       .......
       "thread_id":"3"}
     ]
}
Once retrieved text from the file, we have to parse it.
It is quite simple with a Json format.
String content = getContentFile(file);
if (content != null) {
    // Parse Json
    JSONObject json = new JSONObject(content);
    JSONArray msgs = (JSONArray) json.get("messages");
    for (int i = 0; i < msgs.length(); i++) {
        JSONObject json_dataSms = msgs.getJSONObject(i);
        Iterator keys = json_dataSms.keys();
        Map message = new HashMap();
        String idKey = null;
        while (keys.hasNext()) {
           String key = (String) keys.next();
           message.put(key,json_dataSms.getString(key));
           idKey = json_dataSms.getString(TelephonyProviderConstants.Sms._ID);
        }
        
        // Put message in hashMap
	messages.put(idKey, message);
    }
    restore(messages);
    continue;
}
Now we will restore sms.We will use a Content Resolver.

private void restore(Map<String, Map<String, String>> messages) {

   if (messages != null) {
      for (Map.Entry<String, Map<String, String>> entry : messages.entrySet()) {
          String idkey = entry.getKey();
          Map<String, String> msg = entry.getValue();
          String type = msg.get(TelephonyProviderConstants.Sms.TYPE);

          ContentValues values = new ContentValues();
          values.put(TelephonyProviderConstants.Sms.BODY,
                     msg.get(TelephonyProviderConstants.Sms.BODY));
          values.put(TelephonyProviderConstants.Sms.ADDRESS,
                     msg.get(TelephonyProviderConstants.Sms.ADDRESS));
          values.put(TelephonyProviderConstants.Sms.TYPE,
                     msg.get(TelephonyProviderConstants.Sms.TYPE));
          values.put(TelephonyProviderConstants.Sms.PROTOCOL, 
                     msg.get(TelephonyProviderConstants.Sms.PROTOCOL));
          values.put(TelephonyProviderConstants.Sms.SERVICE_CENTER,
                     msg.get(TelephonyProviderConstants.Sms.SERVICE_CENTER));
          values.put(TelephonyProviderConstants.Sms.DATE,
                     msg.get(TelephonyProviderConstants.Sms.DATE));
          values.put(TelephonyProviderConstants.Sms.STATUS,
                     msg.get(TelephonyProviderConstants.Sms.STATUS));
          values.put(TelephonyProviderConstants.Sms.READ,
                     msg.get(TelephonyProviderConstants.Sms.READ));
          values.put(TelephonyProviderConstants.Sms.DATE_SENT,
                     msg.get(TelephonyProviderConstants.Sms.DATE_SENT));

         if (type != null
            && (Integer.parseInt(type) ==
                  TelephonyProviderConstants.Sms.MESSAGE_TYPE_INBOX
                )
   	    && !smsExists(values)) {
              final Uri uri = getContentResolver().insert(
                                 TelephonyProviderConstants.Sms.CONTENT_URI,values);
              if (uri != null) {
                  showToast("Restored message="
                      	+ msg.get(TelephonyProviderConstants.Sms.BODY));
              }
        } else {
           Log.d(TAG, "ignore");
        }
      }
   }
}

private boolean smsExists(ContentValues values) {
	// just assume equality on date+address+type
        Cursor c = getContentResolver()
               .query(TelephonyProviderConstants.Sms.CONTENT_URI,
                          new String[] { "_id" },
                          "date = ? AND address = ? AND type = ?",
                          new String[] {
                              values.getAsString(TelephonyProviderConstants.Sms.DATE),
                              values.getAsString(TelephonyProviderConstants.Sms.ADDRESS),
                              values.getAsString(TelephonyProviderConstants.Sms.TYPE) },
                          null);
   
       boolean exists = false;
       if (c != null) {
            exists = c.getCount() > 0;
            c.close();
       }
       return exists;
}
In our example we make a check if sms already exists.
We assume equality on date,adress and type. If it exists, we will ignore it.
If it doesn't exist, we will insert in sms Content Provider.

This code requires a new permission:
<uses-permission android:name="android.permission.WRITE_SMS" />

You can get code from GitHub:

Popular posts from this blog

Expand and collapse animation

How to centralize the support libraries dependencies in gradle

A Material styled AlertDialog