title: Google drive to back up and restore database and shared preferences of Android application
body: <p>I need to create a backup of my application which would include creating a backup of 2 databases and also the shared preferences using Google drive API. I was able to get the authentication done for the app and also create a new folder in Drive using the following code:</p>
  
  <pre><code>public class MainActivity2 extends BaseDemoActivity {
  
  DriveId folderId;
  
  @Override
  public void onConnected(Bundle connectionHint) {
      super.onConnected(connectionHint);
      MetadataChangeSet changeSet = new MetadataChangeSet.Builder().setTitle("New folder").build();
      Drive.DriveApi.getRootFolder(getGoogleApiClient())
      .createFolder(getGoogleApiClient(), changeSet)
      .setResultCallback(folderCreatedCallback);
  }
  
  ResultCallback&lt;DriveFolderResult&gt; folderCreatedCallback = new ResultCallback&lt;DriveFolderResult&gt;() {
      @Override
      public void onResult(DriveFolderResult result) {
          if (!result.getStatus().isSuccess()) {
              showMessage("Error while trying to create the folder");
              return;
          }
          folderId = result.getDriveFolder().getDriveId();
          showMessage("Created a folder: " + result.getDriveFolder().getDriveId());
      }
  };
  }
  </code></pre>
  
  <p>I insert the file using</p>
  
  <pre><code>fileUri = Uri.fromFile(new java.io.File(Environment.getDataDirectory().getPath()
                          + "/data/com.example.myapp/databases/mydb.db"));
  
                  java.io.File fileContent = new java.io.File(fileUri.getPath());
  
                  FileContent mediaContent = new FileContent(getMimeType("db"), fileContent);
                  File body = new com.google.api.services.drive.model.File();
                  body.setTitle(fileContent.getName());
                  body.setMimeType(getMimeType("db"));
  
                  File file = service.files().insert(body, mediaContent).execute();
  </code></pre>
  
  <p>This works fine. </p>
  
  <p>I restore using </p>
  
  <pre><code>AsyncTask&lt;Void, Void, String&gt; task = new AsyncTask&lt;Void, Void, String&gt;() {
          @Override
          protected String doInBackground(Void... params) {
              try {
  
                  fileId="0B7Gol85MIbTJLTRxX1hZdDJjaEE";
                  credential.setSelectedAccountName("the same drive account");
                  service = getDriveService(credential);
                  if (fileId != null) {
                      File file = service.files().get(fileId).execute();
                      downloadFile(service, file);
                  }
                  else return null;
              } catch (Throwable tr) {
  
              }
              return fileId;
          }
  
  private void downloadFile(Drive service, File file) {
      InputStream mInput=null;
      FileOutputStream mOutput=null;
      if (file.getDownloadUrl() != null &amp;&amp; file.getDownloadUrl().length() &gt; 0) {
          try {
              HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
  
              mInput = resp.getContent();
              String outFileName = "file://"+Environment.getDataDirectory().getPath() + "/data/com.example.myapp/databases/InvoiceDataBase.db";
              Log.e("com.example.myapp", "getDatabasePath="+ getDatabasePath("")); 
              Log.e("com.example.myapp", "outFileName="+outFileName);
  //              String outFileName = "../databases/" + "Quickpay.db";
              mOutput = new FileOutputStream(outFileName);
              byte[] mBuffer = new byte[1024];
              int mLength;
              while ((mLength = mInput.read(mBuffer)) &gt; 0) {
                  mOutput.write(mBuffer, 0, mLength);
              }
              mOutput.flush();
          } catch (IOException e) {
              // An error occurred.
              e.printStackTrace();
              // return null;
          }
          finally {
              try {
                      //Close the streams
                      if(mOutput != null){
                          mOutput.close();
                      }
                      if(mInput != null){
                          mInput.close();
                      }
              } catch (IOException e) {
                      Log.e("com.example.myapp", "failed to close databases");
              }
      }
      } else {
          // The file doesn't have any content stored on Drive.
          // return null;
          Log.e("com.example.myapp", "No content on Drive");
      }
  }
  </code></pre>
  
  <p>When I backup again after a restore, I get</p>
  
  <p><strong>" /data/data/com.example.myapp/databases/mydb: open failed: ENOENT (No such file or directory)"</strong></p>
  
  <p>Now I need to upload my ".db" file in this folder and also upload shared preferences as an XML file. So my questions are:</p>
  
  <ol>
  <li>How do I upload my application database to this folder? <strong>solved.</strong></li>
  <li>How do i RESTORE the database file back to the application?</li>
  <li>Can the user have full access to the files when he logs into his Google Drive account? Is there any other way to backup and restore ? I cannot use "Android Backup services" as that cannot be a forced backup. </li>
  </ol>
  
  <p>TIA.</p>