1

我在developers.google.com 中关注有关Drive v2 的所有信息,以便在Android API 15 中构建一个简单的应用程序,只是为了上传一个txt 文件。在围绕它花费了很多时间之后,比如库的正确 java 构建路径(在我的例子中是 1.11.0),启用和设置 Drive SDK、客户端 ID 的 API 访问等。我在这篇文章中找到了一个很好的例子Google Drive 将错误 400 或 403 返回到我的 Android 应用程序?在那里我发现了与现在我的应用程序相同的错误描述。这是我的完整代码(希望对其他人有用):

public class DrivexampleActivity extends Activity { 

Context activity = null;
boolean alreadyTriedAgain;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AccountManager am = AccountManager.get(this);
    activity = this.getApplicationContext();
    Bundle options = new Bundle();
    Account[] acc = am.getAccounts();
    am.getAuthToken(
        (am.getAccounts())[8], // #8 just in my phone case. you can debugg the acc variable to find your @gmail account index.
        "oauth2:" + DriveScopes.DRIVE,
        options,
        true, 
        new OnTokenAcquired(),
        null); 
}

private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
    @Override
    public void run(AccountManagerFuture<Bundle> result) {

        try {
            final String token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN);

            HttpTransport httpTransport = new NetHttpTransport();
            JacksonFactory jsonFactory = new JacksonFactory();  

            Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
            b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
            @Override
            public void initialize(JsonHttpRequest request) throws IOException {
            // TODO Auto-generated method stub
                DriveRequest driveRequest = (DriveRequest) request;
                driveRequest.setPrettyPrint(true);                              
                driveRequest.setKey("xxxxxxxxxxxx.apps.googleusercontent.com"); // I replaced the number with x's. for your Client ID from Google API Console
                driveRequest.setOauthToken(token);                      
                }
            }); 

                final Drive drive = b.build();

                final com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
                body.setTitle("My Test File");
                body.setDescription("A Test File");
                body.setMimeType("text/plain");

                java.io.File fileContent = new java.io.File("document.txt");
                final FileContent mediaContent = new FileContent("text/plain",fileContent);

                new Thread(new Runnable() {
                    public void run() {

                        com.google.api.services.drive.model.File file;
                        try {                           
                            file = drive.files().insert(body, mediaContent).execute();
                            Log.i("Hi", "File ID: " + file.getId());
                            alreadyTriedAgain = false; // Global boolean to make sure you don't repeatedly try too many times when the server is down or your code is faulty... they'll block requests until the next day if you make 10 bad requests, I found.
                        } catch (IOException e) {
                            if(!alreadyTriedAgain){
                                alreadyTriedAgain = true;
                                Log.i("Hi", "The upload/insert was caught, which suggests it wasn't successful...");
                                e.printStackTrace();    
                            }    
                        }
                    }
                }).start();

                Intent launch = null;
                launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT);

                if (launch != null) {
                    Log.i("Hi", "Something came back as a KEY_INTENT");
                    startActivityForResult(launch, 3025);
                    return; 
                }
        } catch (OperationCanceledException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (AuthenticatorException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }        
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 3025) {
        switch (resultCode) {
            case RESULT_OK:
                AccountManager am = AccountManager.get(activity);
                Bundle options = new Bundle();
                am.getAuthToken(
                        (am.getAccounts())[8], // #8 just in my phone case. you can debugg the acc variable to find your @gmail account index.
                        "oauth2:" + DriveScopes.DRIVE,
                        options,
                        true, 
                        new OnTokenAcquired(),
                        null); 
                break;
            case RESULT_CANCELED:
                // This probably means the user refused to log in. Explain to them why they need to log in.
                break;
            default:
                // This isn't expected... maybe just log whatever code was returned.
                break;
        }
    } else {
        // Your application has other intents that it fires off besides the one for Drive's log in if it ever reaches this spot. Handle it here however you'd like.
    }
}

还体现:

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

    <uses-sdk android:minSdkVersion="14" />
    <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.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".DrivexampleActivity"
            android:label="@string/app_name" 
            android:exported="true">
            <meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="id=xxxxxxxxxxxx"/>

            <intent-filter>
                <action android:name="com.google.android.apps.drive.DRIVE_OPEN" />
                <data android:mimeType="application/vnd.test.type"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

但总是得到以下错误:

com.google.api.client.http.HttpResponseException: 400 Bad Request
{
  "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "keyInvalid",
    "message": "Bad Request"
   }
  ],
  "code": 400,
  "message": "Bad Request"
 }
}

就我而言,DRIVE SDK 和 Drive API 似乎没有错误。有什么建议吗??请!!

4

1 回答 1

1

您将从 API 控制台获得的客户端 ID 传递给 driveRequest.setKey,但是该方法用于设置 API 密钥而不是客户端 ID。检查您提到的其他问题的第一个答案以获取更多详细信息。

于 2012-09-21T07:51:59.133 回答