0

I am trying to get the following tutorial to work: https://developers.google.com/drive/quickstart-android. After following all the steps and running the code, I get the following error: ''
I've tried doing the project twice to see if I had missed any step, but both times led me to the same result. Below are my activity, manifest file and source file.

I added the, "Drive API," via downloading as instructed. I am running on Galaxy SIII which targets Android version 4.1.2. However, my project is set up to run with "Google APIs Android 4.2.2"

Below is the error obtained while connected to the internet and phone service available 4G:

11-18 15:19:51.275: W/AbstractGoogleClient(3450): Application name is not set. Call Builder#setApplicationName.
11-18 15:19:51.946: W/IInputConnectionWrapper(3450): showStatusIcon on inactive InputConnection
11-18 15:20:02.367: E/ActivityThread(3450): Activity com.example.fileupload.MainActivity has leaked ServiceConnection com.google.android.gms.internal.by@41e4e5a8 that was originally bound here
11-18 15:20:02.367: E/ActivityThread(3450): android.app.ServiceConnectionLeaked: Activity com.example.fileupload.MainActivity has leaked ServiceConnection com.google.android.gms.internal.by@41e4e5a8 that was originally bound here
11-18 15:20:02.367: E/ActivityThread(3450):     at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:965)
11-18 15:20:02.367: E/ActivityThread(3450):     at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:859)
11-18 15:20:02.367: E/ActivityThread(3450):     at android.app.ContextImpl.bindService(ContextImpl.java:1308)
11-18 15:20:02.367: E/ActivityThread(3450):     at android.app.ContextImpl.bindService(ContextImpl.java:1300)
11-18 15:20:02.367: E/ActivityThread(3450):     at android.content.ContextWrapper.bindService(ContextWrapper.java:401)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:192)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:217)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:836)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.media.MediaHttpUploader.executeCurrentRequest(MediaHttpUploader.java:456)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.media.MediaHttpUploader.executeCurrentRequestWithBackOffAndGZip(MediaHttpUploader.java:478)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.media.MediaHttpUploader.executeUploadInitiation(MediaHttpUploader.java:428)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:326)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:420)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:345)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:463)
11-18 15:20:02.367: E/ActivityThread(3450):     at com.example.fileupload.MainActivity$1.run(MainActivity.java:98)
11-18 15:20:02.367: E/ActivityThread(3450):     at java.lang.Thread.run(Thread.java:856)
11-18 15:20:02.377: I/Adreno200-EGLSUB(3450): <ConfigWindowMatch:2087>: Format RGBA_8888.
11-18 15:20:06.021: I/Adreno200-EGLSUB(3450): <ConfigWindowMatch:2087>: Format RGBA_8888.
11-18 15:20:16.782: I/Adreno200-EGLSUB(3450): <ConfigWindowMatch:2087>: Format RGBA_8888.
11-18 15:20:27.764: W/AbstractGoogleClient(3450): Application name is not set. Call Builder#setApplicationName.
11-18 15:20:27.844: W/AbstractGoogleClient(3450): Application name is not set. Call Builder#setApplicationName.
11-18 15:20:28.925: W/IInputConnectionWrapper(3450): showStatusIcon on inactive InputConnection

Here is the code copied from tutorial

{

package com.example.fileupload;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.widget.Toast;

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.FileContent;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import android.app.Activity;
import android.view.Menu;

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).execute();
              if (file != null) {
                showToast("Photo uploaded: " + file.getTitle());
                startCameraIntent();
              }
            } catch (UserRecoverableAuthIOException e) {
              startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
            } catch (IOException e) {
              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();
          }
        });
      }
    }

}

manifest file {

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fileupload"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="16" />

    <permission
        android:name="com.google.cloud.backend.android.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.cloud.backend.android.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.fileupload.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="*****" />
            <intent-filter>
            <action android:name="com.google.android.apps.drive.DRIVE_OPEN" />
            <data android:mimeType="application/vnd.google-apps.drive-sdk.id=*****" />
            <data android:mimeType="image/png" />
            <data android:mimeType="image/jpeg" />
            <data android:mimeType="image/jpg" />
            </intent-filter>
        </activity>
    </application>

</manifest>

}

layout file {

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

}

jpCoder411
  • 207
  • 3
  • 11

1 Answers1

0

In the log, the first line tells about adding the application name as supplied when you registered your app for a simple api access key at google console. I have constructed my Drive object when supplied by a credential object as following :

public static Drive getDriveService(GoogleAccountCredential credential) 
{
    return 
            new Drive
                    .Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
                    .setApplicationName("YourProjectName")
                    .build();
}

This i hope will solve your problem !

Sri Krishna
  • 302
  • 1
  • 2
  • 14
  • Thanks that helped. I guess I am still missing other pieces of the puzzle. Now I am getting the following error: (common_google_play_services_install_title) in Lcom/google/android/gms/R$string;.... and W/System.err(16349): "message": "Access Not Configured"... – jpCoder411 Nov 20 '13 at 06:22
  • You need to activate both Drive SDK and API in the console, and also when u create a project in the console, u must run the application from the same computer, because it is IP Locked (or i am assuming MAC Locked). – Sri Krishna Nov 20 '13 at 07:23
  • The Drive SDK and API are both turned one, the SHA key generated, I am wondering if I am missing something in the code. I am not sure what, "com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden" requests me to do to fix this error. I am compiling from the same windows machine. – jpCoder411 Nov 20 '13 at 07:51
  • how did u get the SHA1 Key? Did u generate it from keytool or did u get it from Eclipse's -> Window tab -> Preferences -> Android -> Build. If you follow the second method u will get the correct SHA1 Key. Also did u correctly put the OAuth 2.0 Client ID in the Android Projects's Manifest as : – Sri Krishna Nov 20 '13 at 09:04
  • U must perform these two steps correctly, then clean your project and run the Project in either Android Phone(API 8+)/Android Emulator (4.2.2 or API 17). I think this will solve your problem of 401 Access not configured problem, which i also faced many times in my early google drive development phases. – Sri Krishna Nov 20 '13 at 09:07
  • I created another project this time using the SHA1 key from Eclipse and I get the same error. I am thinking that I am putting the wrong value for the key. Do I use, "Client ID," under OAUTH 2.0 or the API key under "Android"? Above is a copy of my manifest file, which I updated to match your comments above. Thanks a lot for your help. – jpCoder411 Nov 20 '13 at 15:37
  • You need to use the OAuth 2.0 Client ID, as it is the doorway for accessing user's data as explained in the Google console. And an Api key is used to use google services for accessing data not associated with an account from Android. – Sri Krishna Nov 23 '13 at 01:43
  • I still have not resolved this issue. I walked away from trying to get it to work with the conclusion that Google Drive API only works with Jelly Bean version 4.2.2 or higher. If anyone can confirm that this is true, it'll be very helpful. Instead of Google Drive, I am going to try to use Twitter! – jpCoder411 Nov 28 '13 at 19:45
  • Generally the '403 Access not configured' is explained in [google drive}(https://developers.google.com/drive/handle-errors), also many others have experienced the same problem [google drive api error 403 Access Not configured](http://stackoverflow.com/questions/16731196/google-drive-api-error-403-access-not-configured). I myself got stuck in that quagmire, but after consistent effort and following google API Docs and StackOverflow solutions found that the problem is due to wrongful data entry in the google cloud condole. – Sri Krishna Nov 30 '13 at 12:56
  • So just try to recreate your project and follow the steps to get the Google Drive working. The GA is not limited to 4.2.2, as GA requires Google Services, which is a feature in Android starting from version 2.2 and made available after a prolonged request to google on the emulator versions from 4.2.2. I hope you can solve your problem by doing a fresh install of everything related to GA in Eclipse. – Sri Krishna Nov 30 '13 at 12:57