14

I have just setup the quickstart google drive sdk application for Android available on this link

I am trying to upload images and then do OCR on them. The sample application on the Android quickstart works fine, but when I try to set the boolean for OCR as true I get the following IOException:

07-29 03:33:01.172: D/OCR_SERVICE(22602): Error 2: 400 Bad Request
07-29 03:33:01.172: D/OCR_SERVICE(22602): {
07-29 03:33:01.172: D/OCR_SERVICE(22602):   "code": 400,
07-29 03:33:01.172: D/OCR_SERVICE(22602):   "errors": [
07-29 03:33:01.172: D/OCR_SERVICE(22602):     {
07-29 03:33:01.172: D/OCR_SERVICE(22602):       "domain": "global",
07-29 03:33:01.172: D/OCR_SERVICE(22602):       "message": "Bad Request",
07-29 03:33:01.172: D/OCR_SERVICE(22602):       "reason": "badRequest"
07-29 03:33:01.172: D/OCR_SERVICE(22602):     }
07-29 03:33:01.172: D/OCR_SERVICE(22602):   ],
07-29 03:33:01.172: D/OCR_SERVICE(22602):   "message": "Bad Request"
07-29 03:33:01.172: D/OCR_SERVICE(22602): }

The interesting thing is I was able to do the OCR about 2 times and then after that I might have modified the source or something and now it isnt working. But I remember the only change I had to make from the quickstart app was changing this line: File file = service.files().insert(body, mediaContent).execute(); to the following:

File file = service.files().insert(body, mediaContent).setOcr(true).execute();

Here is my code:

public class MainActivity extends Activity {
  static final int REQUEST_ACCOUNT_PICKER = 1;
  static final int REQUEST_AUTHORIZATION = 2;
  static final int CAPTURE_IMAGE = 3;

  private static Uri fileUri;
  private static Drive service;
  private GoogleAccountCredential credential;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
    startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
  }

  @Override
  protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    switch (requestCode) {
    case REQUEST_ACCOUNT_PICKER:
      if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
        String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
        if (accountName != null) {
          credential.setSelectedAccountName(accountName);
          service = getDriveService(credential);
          startCameraIntent();
        }
      }
      break;
    case REQUEST_AUTHORIZATION:
      if (resultCode == Activity.RESULT_OK) {
        saveFileToDrive();
      } else {
        startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
      }
      break;
    case CAPTURE_IMAGE:
      if (resultCode == Activity.RESULT_OK) {
        saveFileToDrive();
      }
    }
  }

  private void startCameraIntent() {
    String mediaStorageDir = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES).getPath();
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
    fileUri = Uri.fromFile(new java.io.File(mediaStorageDir + java.io.File.separator + "IMG_"
        + timeStamp + ".jpg"));

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(cameraIntent, CAPTURE_IMAGE);
  }

  private void saveFileToDrive() {
    Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          // File's binary content
          java.io.File fileContent = new java.io.File(fileUri.getPath());
          FileContent mediaContent = new FileContent("image/jpeg", fileContent);

          // File's metadata.
          File body = new File();
          body.setTitle(fileContent.getName());
          body.setMimeType("image/jpeg");

          File file = service.files().insert(body, mediaContent).setOcr(true).execute();
          if (file != null) {
            showToast("Photo uploaded: " + file.getTitle());
            startCameraIntent();
          }
        } catch (UserRecoverableAuthIOException e) {
            Log.d("OCR_SERVICE", "Error 1: " + e.getMessage());
          startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
        } catch (IOException e) {
            Log.d("OCR_SERVICE", "Error 2: " + e.getMessage());
          e.printStackTrace();
        }
      }
    });
    t.start();
  }

  private Drive getDriveService(GoogleAccountCredential credential) {
    return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
        .build();
  }

  public void showToast(final String toast) {
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
      }
    });
  }
}
JunYoung Gwak
  • 2,967
  • 3
  • 21
  • 35
Nick Richards
  • 249
  • 2
  • 6
  • It could be a corrupted image blob to receive an http 400 error. – Burcu Dogan Jul 29 '13 at 13:44
  • I'm having the exact same issue. Could it be because of the mime type? Since the drive document would have both image and text? – RagHaven Jul 29 '13 at 17:56
  • you can try with application/vnd.google-apps.photo, as said in https://developers.google.com/drive/mime-types – nsL Oct 12 '13 at 21:52

1 Answers1

2

I just finished making this Google Drive Quickstart example from the documentation work. The code is outdated and didn't even compile at first. Once that succeeded I had some other issues when running the app on a device.

I have listed the changes required to get this working and committed to the following github project. It's an Eclipse ADT project so feel free to check out and compare with your code. I've tested with the OCR option enabled and verified the result.

https://github.com/hanscappelle/more-android-examples/tree/master/DriveQuickstart

The readme file has an overview of all the required changes.

hcpl
  • 17,382
  • 7
  • 72
  • 73