title: Create / Edit / Retrieve DB file with GDAA (Google Drive Api for Android)
body: <p>skilled friends.</p>
  
  <p>Could you someone help me with my problem, please? I'm trying to use GDAA (Google Drive API for Android = <a href="https://developers.google.com/drive/android/appfolder" rel="nofollow">https://developers.google.com/drive/android/appfolder</a>) for backup and restore my DB file. Not REST API.
  I tried use their demo classes from here: <a href="https://github.com/googledrive/android-demos/" rel="nofollow">https://github.com/googledrive/android-demos/</a>, but no positive result. </p>
  
  <p>I suceed with authentication and with save my DB file into App Folder in Google Drive, but I can not edit or retrieve this file. I only still create new and new files. Could you help me, please?</p>
  
  <p>I call this Edit activity:</p>
  
  <pre><code>public class EditContentsActivity extends BaseDemoActivity {
  
  private static final String TAG = "EditContentsActivity";
  
  @Override
  public void onConnected(Bundle connectionHint) {
      super.onConnected(connectionHint);
  
      final ResultCallback&lt;DriveIdResult&gt; idCallback = new ResultCallback&lt;DriveIdResult&gt;() {
          @Override
          public void onResult(DriveIdResult result) {
              if (!result.getStatus().isSuccess()) {
                  Intent intent = new Intent(getBaseContext(), CreateFileInAppFolderActivity.class);
                  startActivity(intent);
                  return;
              }
  
              DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), result.getDriveId());
              new EditContentsAsyncTask(EditContentsActivity.this).execute(file);
          }
      };
      Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
              .setResultCallback(idCallback);
  }
  
  public class EditContentsAsyncTask extends ApiClientAsyncTask&lt;DriveFile, Void, Boolean&gt; {
  
      public EditContentsAsyncTask(Context context) {
          super(context);
      }
  
      @Override
      protected Boolean doInBackgroundConnected(DriveFile... args) {
          DriveFile file = args[0];
          try {
              DriveContentsResult driveContentsResult = file.open(
                      getGoogleApiClient(), DriveFile.MODE_WRITE_ONLY, null).await();
              if (!driveContentsResult.getStatus().isSuccess()) {
                  return false;
              }
              DriveContents driveContents = driveContentsResult.getDriveContents();
              OutputStream outputStream = driveContents.getOutputStream();
  
              String dbpath = "/data/" + "com.myapp" + "/databases/" + DatabaseHelper.DB_NAME;
              FileInputStream fis = new FileInputStream(Environment.getDataDirectory() + dbpath);
              byte[] buffer = new byte[1024];
              int length;
              while ((length = fis.read(buffer)) &gt; 0) {
                  outputStream.write(buffer, 0, length);
              }
  
              com.google.android.gms.common.api.Status status =
                      driveContents.commit(getGoogleApiClient(), null).await();
  
              outputStream.flush();
              outputStream.close();
              fis.close();
  
              return status.getStatus().isSuccess();
          } catch (IOException e) {
              Log.e(TAG, "IOException while appending to the output stream", e);
          }
          return false;
      }
  
      @Override
      protected void onPostExecute(Boolean result) {
          if (!result) {
              showMessage("Error while editing contents");
              return;
          }
          showMessage("Successfully edited contents");
      }
  }
  </code></pre>
  
  <p>If I get "!result.getStatus().isSuccess()" I want to call Create Activity:</p>
  
  <pre><code>public class CreateFileInAppFolderActivity extends BaseDemoActivity {
  
  @Override
  public void onConnected(Bundle connectionHint) {
      super.onConnected(connectionHint);
      // create new contents resource
      Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(driveContentsCallback);
  }
  
  final private ResultCallback&lt;DriveContentsResult&gt; driveContentsCallback =
          new ResultCallback&lt;DriveContentsResult&gt;() {
              @Override
              public void onResult(DriveContentsResult result) {
                  if (!result.getStatus().isSuccess()) {
                      showMessage("Error while trying to create new file contents");
                      return;
                  }
  
                  String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db");
                  MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                          .setTitle(EXISTING_FILE_ID)
                          .setMimeType(mimeType)
                          .build();
                  OutputStream os  = result.getDriveContents().getOutputStream();
                 try {
                      String dbpath = "/data/" + "com.myapp" + "/databases/" + DatabaseHelper.DB_NAME;
                      FileInputStream fis = new FileInputStream(Environment.getDataDirectory() + dbpath);
                      byte[] buffer = new byte[1024];
                      int length;
                      while ((length = fis.read(buffer)) &gt; 0) {
                          os.write(buffer, 0, length);
                      }
                     Drive.DriveApi.getAppFolder(getGoogleApiClient())
                             .createFile(getGoogleApiClient(), changeSet, result.getDriveContents())
                             .setResultCallback(fileCallback);
  
                     os.flush();
                     os.close();
                     fis.close();
  
                     throw new IOException("");
                  } catch (IOException e) {
                      Log.e("IOExceptions=", e.toString());
                     Drive.DriveApi.getAppFolder(getGoogleApiClient()).delete(getGoogleApiClient());
                  }
  
              }
          };
  
  final private ResultCallback&lt;DriveFileResult&gt; fileCallback = new
          ResultCallback&lt;DriveFileResult&gt;() {
              @Override
              public void onResult(DriveFileResult result) {
                  if (!result.getStatus().isSuccess()) {
                      showMessage("Error while trying to create the file");
                      return;
                  }
                  showMessage("Created a file in App Folder: "
                          + result.getDriveFile().getDriveId());
              }
          };
  </code></pre>
  
  <p>All extend this Base Demo Activity:</p>
  
  <pre><code>public abstract class BaseDemoActivity extends Activity implements
      GoogleApiClient.ConnectionCallbacks,
      GoogleApiClient.OnConnectionFailedListener {
  
  private static final String TAG = "BaseDriveActivity";
  
  /**
   * DriveId of an existing folder to be used as a parent folder in
   * folder operations samples.
   */
  public static final String EXISTING_FOLDER_ID = "0B2EEtIjPUdX6MERsWlYxN3J6RU0";
  
  /**
   * DriveId of an existing file to be used in file operation samples..
   */
  public static final String EXISTING_FILE_ID = "0ByfSjdPVs9MZTHBmMVdSeWxaNTg";
  
  /**
   * Extra for account name.
   */
  protected static final String EXTRA_ACCOUNT_NAME = "account_name";
  
  /**
   * Request code for auto Google Play Services error resolution.
   */
  protected static final int REQUEST_CODE_RESOLUTION = 1;
  
  /**
   * Next available request code.
   */
  protected static final int NEXT_AVAILABLE_REQUEST_CODE = 2;
  
  /**
   * Google API client.
   */
  private GoogleApiClient mGoogleApiClient;
  
  /**
   * Called when activity gets visible. A connection to Drive services need to
   * be initiated as soon as the activity is visible. Registers
   * {@code ConnectionCallbacks} and {@code OnConnectionFailedListener} on the
   * activities itself.
   */
  @Override
  protected void onResume() {
      super.onResume();
      if (mGoogleApiClient == null) {
          mGoogleApiClient = new GoogleApiClient.Builder(this)
                  .addApi(Drive.API)
                  .addScope(Drive.SCOPE_FILE)
                  .addScope(Drive.SCOPE_APPFOLDER) // required for App Folder sample
                  .addConnectionCallbacks(this)
                  .addOnConnectionFailedListener(this)
                  .build();
      }
      mGoogleApiClient.connect();
  }
  
  /**
   * Handles resolution callbacks.
   */
  @Override
  protected void onActivityResult(int requestCode, int resultCode,
          Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (requestCode == REQUEST_CODE_RESOLUTION &amp;&amp; resultCode == RESULT_OK) {
          mGoogleApiClient.connect();
      }
  }
  
  /**
   * Called when activity gets invisible. Connection to Drive service needs to
   * be disconnected as soon as an activity is invisible.
   */
  @Override
  protected void onPause() {
      if (mGoogleApiClient != null) {
          mGoogleApiClient.disconnect();
      }
      super.onPause();
  }
  
  /**
   * Called when {@code mGoogleApiClient} is connected.
   */
  @Override
  public void onConnected(Bundle connectionHint) {
      Log.i(TAG, "GoogleApiClient connected");
  }
  
  /**
   * Called when {@code mGoogleApiClient} is disconnected.
   */
  @Override
  public void onConnectionSuspended(int cause) {
      Log.i(TAG, "GoogleApiClient connection suspended");
  }
  
  /**
   * Called when {@code mGoogleApiClient} is trying to connect but failed.
   * Handle {@code result.getResolution()} if there is a resolution is
   * available.
   */
  @Override
  public void onConnectionFailed(ConnectionResult result) {
      Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
      if (!result.hasResolution()) {
          // show the localized error dialog.
          GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
          return;
      }
      try {
          result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
      } catch (SendIntentException e) {
          Log.e(TAG, "Exception while starting resolution activity", e);
      }
  }
  
  /**
   * Shows a toast message.
   */
  public void showMessage(String message) {
      Toast.makeText(this, message, Toast.LENGTH_LONG).show();
  }
  
  /**
   * Getter for the {@code GoogleApiClient}.
   */
  public GoogleApiClient getGoogleApiClient() {
    return mGoogleApiClient;
  }
  </code></pre>
  
  <p>Retrieve Activity:</p>
  
  <pre><code>public class RetrieveContentsActivity extends BaseDemoActivity {
  
  private static final String TAG = "RetrieveContentsActivity";
  
  @Override
  public void onConnected(Bundle connectionHint) {
      super.onConnected(connectionHint);
      Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
              .setResultCallback(idCallback);
  }
  
  final private ResultCallback&lt;DriveIdResult&gt; idCallback = new ResultCallback&lt;DriveIdResult&gt;() {
      @Override
      public void onResult(DriveIdResult result) {
          new RetrieveDriveFileContentsAsyncTask(
                  RetrieveContentsActivity.this).execute(result.getDriveId());
      }
  };
  
  final private class RetrieveDriveFileContentsAsyncTask
          extends ApiClientAsyncTask&lt;DriveId, Boolean, String&gt; {
  
      public RetrieveDriveFileContentsAsyncTask(Context context) {
          super(context);
      }
  
      @Override
      protected String doInBackgroundConnected(DriveId... params) {
          String contents = null;
          DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), params[0]);
          DriveContentsResult driveContentsResult =
                  file.open(getGoogleApiClient(), DriveFile.MODE_READ_ONLY, null).await();
          if (!driveContentsResult.getStatus().isSuccess()) {
              return null;
          }
          DriveContents driveContents = driveContentsResult.getDriveContents();
          BufferedReader reader = new BufferedReader(
                  new InputStreamReader(driveContents.getInputStream()));
          StringBuilder builder = new StringBuilder();
          String line;
          try {
              while ((line = reader.readLine()) != null) {
                  builder.append(line);
              }
              contents = builder.toString();
          } catch (IOException e) {
              Log.e(TAG, "IOException while reading from the stream", e);
          }
  
          driveContents.discard(getGoogleApiClient());
          return contents;
      }
  
      @Override
      protected void onPostExecute(String result) {
          super.onPostExecute(result);
          if (result == null) {
              showMessage("Error while reading from the file");
              return;
          }
          showMessage("File contents: " + result);
      }
  }
  </code></pre>
  
  <p>And there is Authentication code:</p>
  
  <pre><code>public abstract class ApiClientAsyncTask&lt;Params, Progress, Result&gt;
      extends AsyncTask&lt;Params, Progress, Result&gt; {
  
  private GoogleApiClient mClient;
  
  public ApiClientAsyncTask(Context context) {
      GoogleApiClient.Builder builder = new GoogleApiClient.Builder(context)
              .addApi(Drive.API)
              .addScope(Drive.SCOPE_FILE);
      mClient = builder.build();
  }
  
  @Override
  protected final Result doInBackground(Params... params) {
      Log.d("TAG", "in background");
      final CountDownLatch latch = new CountDownLatch(1);
      mClient.registerConnectionCallbacks(new ConnectionCallbacks() {
          @Override
          public void onConnectionSuspended(int cause) {
          }
  
          @Override
          public void onConnected(Bundle arg0) {
              latch.countDown();
          }
      });
      mClient.registerConnectionFailedListener(new OnConnectionFailedListener() {
          @Override
          public void onConnectionFailed(ConnectionResult arg0) {
              latch.countDown();
          }
      });
      mClient.connect();
      try {
          latch.await();
      } catch (InterruptedException e) {
          return null;
      }
      if (!mClient.isConnected()) {
          return null;
      }
      try {
          return doInBackgroundConnected(params);
      } finally {
          mClient.disconnect();
      }
  }
  
  /**
   * Override this method to perform a computation on a background thread, while the client is
   * connected.
   */
  protected abstract Result doInBackgroundConnected(Params... params);
  
  /**
   * Gets the GoogleApliClient owned by this async task.
   */
  protected GoogleApiClient getGoogleApiClient() {
      return mClient;
  }
  </code></pre>
  
  <p>Do you know the right approach with this demo, please? </p>