Java tutorial
/******************************************************************************* * Copyright 2013 Gabriele Mariotti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package it.gmariotti.android.examples.googleaccount; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.accounts.AccountManager; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.support.v4.app.NavUtils; import android.util.Log; import android.widget.CheckBox; import android.widget.Toast; import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; import com.google.android.gms.auth.GoogleAuthUtil; import com.google.android.gms.common.AccountPicker; import com.google.api.client.extensions.android.http.AndroidHttp; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; import com.google.api.client.http.ByteArrayContent; import com.google.api.client.json.gson.GsonFactory; import com.google.api.services.drive.Drive; import com.google.api.services.drive.Drive.Files; import com.google.api.services.drive.DriveScopes; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.FileList; import com.google.api.services.drive.model.ParentReference; import com.google.gson.JsonObject; public class SmsBackupGDriveActivity extends SherlockActivity { private static String TAG = "SmsBackupGDriveActivity"; static final int REQUEST_ACCOUNT_PICKER = 1; static final int REQUEST_AUTHORIZATION_FOLDER = 2; private final static String PREF_ACCOUNT_NAME = "ACCOUNT_NAME"; private GoogleAccountCredential mCredential; private static Drive mService; private String mAccountName; private static final String MIME_TEXT_PLAIN = "text/plain"; private static final String MIME_FOLDER = "application/vnd.google-apps.folder"; private static final String FOLDER_NAME = "backup"; private boolean useDataFolder = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sms_backup_gdrive); // Show the Up button in the action bar. getSupportActionBar().setDisplayHomeAsUpEnabled(true); } /* * */ private JSONObject readSmsInbox() throws JSONException { Cursor cursor = getSmsInboxCursor(); // StringBuilder messages = new StringBuilder(); JSONArray messages = new JSONArray(); String and = ""; if (cursor != null) { final String[] columns = cursor.getColumnNames(); while (cursor.moveToNext()) { // messages.append(and); JSONObject msg = new JSONObject(); // long id = cursor.getLong(SmsQuery._ID); long contactId = cursor.getLong(SmsQuery.PERSON); String address = cursor.getString(SmsQuery.ADDRESS); // long threadId = cursor.getLong(SmsQuery.THREAD_ID); // final long date = cursor.getLong(SmsQuery.DATE); final Map<String, String> msgMap = new HashMap<String, String>(columns.length); for (int i = 0; i < columns.length; i++) { String value = cursor.getString(i); msgMap.put(columns[i], cursor.getString(i)); /* * messages.append(columns[i]); messages.append("="); * messages.append(value); messages.append(";;"); */ msg.put(columns[i], value); } // and = "\n"; /** * Retrieve display name * */ String displayName = address; if (contactId > 0) { // Retrieve from Contacts with contact id Cursor contactCursor = tryOpenContactsCursorById(contactId); if (contactCursor != null) { if (contactCursor.moveToFirst()) { displayName = contactCursor.getString(RawContactsQuery.DISPLAY_NAME); } else { contactId = 0; } contactCursor.close(); } } else { if (contactId <= 0) { // Retrieve with address Cursor contactCursor = tryOpenContactsCursorByAddress(address); if (contactCursor != null) { if (contactCursor.moveToFirst()) { displayName = contactCursor.getString(ContactsQuery.DISPLAY_NAME); } contactCursor.close(); } } } /* * messages.append("displayName"); messages.append("="); * messages.append(displayName); messages.append(";;"); * messages.append("||"); */ msg.put("displayName", displayName); messages.put(msg); } } JSONObject fileBackupTest = new JSONObject(); fileBackupTest.put("messages", messages); return fileBackupTest; } /** * Retrieve sms * * @return */ private Cursor getSmsInboxCursor() { try { return getContentResolver().query(TelephonyProviderConstants.Sms.CONTENT_URI, SmsQuery.PROJECTION, SmsQuery.WHERE_INBOX, null, TelephonyProviderConstants.Sms.DEFAULT_SORT_ORDER); } catch (Exception e) { Log.e(TAG, "Error accessing conversations cursor in SMS/MMS provider", e); return null; } } private Cursor tryOpenContactsCursorById(long contactId) { try { return getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI.buildUpon() .appendPath(Long.toString(contactId)).build(), RawContactsQuery.PROJECTION, null, null, null); } catch (Exception e) { Log.e(TAG, "Error accessing contacts provider", e); return null; } } private Cursor tryOpenContactsCursorByAddress(String phoneNumber) { try { return getContentResolver().query(ContactsContract.PhoneLookup.CONTENT_FILTER_URI.buildUpon() .appendPath(Uri.encode(phoneNumber)).build(), ContactsQuery.PROJECTION, null, null, null); } catch (Exception e) { // Can be called by the content provider // java.lang.IllegalArgumentException: URI: // content://com.android.contacts/phone_lookup/ Log.w(TAG, "Error looking up contact name", e); return null; } } private interface SmsQuery { String[] PROJECTION = { TelephonyProviderConstants.Sms._ID, TelephonyProviderConstants.Sms.ADDRESS, TelephonyProviderConstants.Sms.PERSON, TelephonyProviderConstants.Sms.THREAD_ID, TelephonyProviderConstants.Sms.BODY, TelephonyProviderConstants.Sms.DATE, TelephonyProviderConstants.Sms.TYPE, TelephonyProviderConstants.Sms.READ, TelephonyProviderConstants.Sms.DATE_SENT, TelephonyProviderConstants.Sms.ERROR_CODE, TelephonyProviderConstants.Sms.STATUS, TelephonyProviderConstants.Sms.SUBJECT, TelephonyProviderConstants.Sms.PROTOCOL, TelephonyProviderConstants.Sms.SERVICE_CENTER }; int _ID = 0; int ADDRESS = 1; int PERSON = 2; int THREAD_ID = 3; int BODY = 4; int DATE = 5; int TYPE = 6; int READ = 7; int DATE_SENT = 8; int ERROR_CODE = 9; int STATUS = 10; int SUBJECT = 11; int PROTOCOL = 12; int SERVICE_CENTER = 13; String WHERE_INBOX = TelephonyProviderConstants.Sms.TYPE + " = " + TelephonyProviderConstants.Sms.MESSAGE_TYPE_INBOX; } private interface RawContactsQuery { String[] PROJECTION = { ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY, }; int DISPLAY_NAME = 0; } private interface ContactsQuery { String[] PROJECTION = { ContactsContract.Contacts.DISPLAY_NAME, }; int DISPLAY_NAME = 0; } /** * Google Picker Account */ private void launchGooglePicker() { Intent googlePicker = AccountPicker.newChooseAccountIntent(null, null, new String[] { GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE }, true, null, null, null, null); startActivityForResult(googlePicker, REQUEST_ACCOUNT_PICKER); } /** * Create a folder */ /* * private void createFolder() { Thread t = new Thread(new Runnable() { * * @Override public void run() { * * if (mService == null) initService(); * * try { File folder = _createFolder(); } catch * (UserRecoverableAuthIOException e) { Intent intent = e.getIntent(); * startActivityForResult(intent, REQUEST_AUTHORIZATION_FOLDER); } catch * (IOException e) { Log.e(TAG, "Error in create folder", e); } * * } }); t.start(); * * } */ /** * internal create Folder * * @return * @throws UserRecoverableAuthIOException * @throws IOException */ private File _createFolder() throws UserRecoverableAuthIOException, IOException { if (useDataFolder) return null; File folder = _isFolderExists(); if (folder != null) return folder; File body = new File(); body.setTitle(FOLDER_NAME); body.setMimeType(MIME_FOLDER); File file = mService.files().insert(body).execute(); return file; } /** * Verify if folder exists * * @return * @throws UserRecoverableAuthIOException * @throws IOException */ private File _isFolderExists() throws UserRecoverableAuthIOException, IOException { Files.List request = mService.files().list() .setQ("mimeType = '" + MIME_FOLDER + "' and title = '" + FOLDER_NAME + "' "); FileList files = request.execute(); if (files != null) { for (File file : files.getItems()) { return file; } } return null; } /** * Init service */ private void initService() { mCredential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE, "https://www.googleapis.com/auth/drive.appdata"); if (mAccountName == null) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); mAccountName = prefs.getString(PREF_ACCOUNT_NAME, null); } if (mAccountName != null) { mCredential.setSelectedAccountName(mAccountName); mService = getDriveService(mCredential); } } private Drive getDriveService(GoogleAccountCredential credential) { return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build(); } /** * Backup SMSs to GDrive */ private void backupSmsToGDrive() { // Check for use data folder CheckBox checkbox = (CheckBox) findViewById(R.id.appdatafolder); if (checkbox != null && checkbox.isChecked()) useDataFolder = true; else useDataFolder = false; Thread t = new Thread(new Runnable() { @Override public void run() { try { showToast("Start process"); // Retrieve sms JSONObject messages = readSmsInbox(); Log.i(TAG, messages.toString()); // Create sms backup Folder File folder = null; if (mService == null) initService(); if (!useDataFolder) folder = createBackupFolder(); // File's metadata. String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ITALIAN).format(new Date()); File body = new File(); body.setTitle("Sms Backup " + timeStamp); body.setMimeType("text/plain"); body.setDescription("Backup sms"); // Set the parent folder. if (useDataFolder) body.setParents(Arrays.asList(new ParentReference().setId("appdata"))); else body.setParents(Arrays.asList(new ParentReference().setId(folder.getId()))); ByteArrayContent content = ByteArrayContent.fromString("text/plain", messages.toString()); File file = mService.files().insert(body, content).execute(); if (file != null) { showToast("Sms backup uploaded: " + file.getTitle()); } } catch (UserRecoverableAuthIOException e) { Intent intent = e.getIntent(); startActivityForResult(intent, REQUEST_AUTHORIZATION_FOLDER); } catch (IOException e) { Log.e("TAG", "Error in backup", e); } catch (JSONException e) { Log.e("TAG", "Error in backup", e); } } private File createBackupFolder() { File folder = null; try { folder = _createFolder(); } catch (UserRecoverableAuthIOException e) { Intent intent = e.getIntent(); startActivityForResult(intent, REQUEST_AUTHORIZATION_FOLDER); } catch (IOException e) { Log.e(TAG, "Error in create folder", e); } return folder; } }); t.start(); } public void showToast(final String toast) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show(); } }); } @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { switch (requestCode) { case REQUEST_ACCOUNT_PICKER: if (resultCode == RESULT_OK) { mAccountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); prefs.edit().putString(PREF_ACCOUNT_NAME, mAccountName).commit(); if (mAccountName != null) { backupSmsToGDrive(); } } break; case REQUEST_AUTHORIZATION_FOLDER: if (resultCode == RESULT_OK) { backupSmsToGDrive(); } else { startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER); } break; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getSupportMenuInflater().inflate(R.menu.activity_sms_backup_gdrive, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: // This ID represents the Home or Up button. In the case of this // activity, the Up button is shown. Use NavUtils to allow users // to navigate up one level in the application structure. For // more details, see the Navigation pattern on Android Design: // // http://developer.android.com/design/patterns/navigation.html#up-vs-back // NavUtils.navigateUpFromSameTask(this); return true; case R.id.menu_backup: launchGooglePicker(); return true; } return super.onOptionsItemSelected(item); } }