【问题标题】:Google Drive SDK : Drive QuickStart App example doesn't work on AndroidGoogle Drive SDK:Drive QuickStart App 示例不适用于 Android
【发布时间】:2013-04-03 14:53:16
【问题描述】:

Drive QuickStart App 示例不适用于 Android (https://developers.google.com/drive/quickstart-android)。

我有一个在 Android 4.1.2 上运行的 Note 2。我按照教程中的所有步骤(使用 eclipse + ADT + google 控制台)并在上面花费了 30 多个小时。

以下行中有一个“ClassNotFoundException”: 文件文件 = service.files().insert(body, mediaContent).execute();

我发现异常发生在 Drive.Files.Insert.execute() 部分。

有没有人能够让这个相机应用程序工作?我看了这个应用的视频教程,甚至开发者都说这个应用只是“可能会工作”......

互联网上是否有确认可用的 Drive SDK 应用程序?我想做的就是从谷歌驱动器下载一个简单的谷歌电子表格。

我尝试过的其他事情: - 谷歌提供的 DrEdit 示例应用程序也没有与谷歌驱动器正确同步。 - 我在 Google Document List API 网站上也找不到工作示例应用程序。

我相信从Android访问Google Drive应该是一个简单的任务,附带一个例子......否则,人们还不如使用DropBox。

谢谢!

【问题讨论】:

    标签: google-drive-api


    【解决方案1】:

    当我在寻找如何从 Drive 打开单个电子表格时,我使用了同一个 QuickStart 应用程序,并且我使用的是 Eclipse Juno,Windows 7,64 位。两个视频我都看了,第二个是Integerate with the Android Drive App

    我使用了两者中的步骤,尤其是在我的清单 xml 中。我不得不去看视频两次,以确保我完成了所有步骤。我必须将用户功能添加到我的清单中。

     <uses-feature android:name="android.hardware.camera" />
    

    我还发现了一些其他的东西。我根本无法在模拟器上运行它。在调试模式下在手机上运行它最初也不起作用,它可以访问手机的 SD 卡(显然)。我将APK复制到手机上并安装了它,请确保您的安全设置已放松。当没有通过 ADB 连接时,它可以在我的手机 (Jellybean Droid Razr) 上运行。

    这是我的大部分清单。请注意,您必须将 API 控制台中的“YOURCLIENTID”替换为您的。我只使用了第一组数字,'-'之后什么都没有,即123456789-blah,blah。只是 123456789。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.birdsall.tda"
    android:versionCode="1"
    android:versionName="1.0" >
    
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="17" />
    
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <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"
        android:uiOptions="splitActionBarWhenNarrow"
         android:exported="true" >
    
        <meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="id=YOURCLIENTID" />
    
        <intent-filter>
        <action android:name="com.google.android.apps.drive.DRIVE_OPEN" />
        <data android:mimeType="application/vnd.google-apps.drive-sdk.YOURCLIENTID" />
        <data android:mimeType="image/png" />
        <data android:mimeType="image/jpeg" />
        <data android:mimeType="image/jpg" />
        </intent-filter>
    
        <meta-data
            android:name="android.app.default_searchable"
            android:value=".ActivitySearch" />
    
        <activity
            android:name="com.birdsall.tda.ActivityMain"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <activity android:name=".ActivityTakePhoto" >
        </activity>
    
    
        <provider
            android:name="com.birdsall.tda.TDAProvider"
            android:authorities="com.birdsall.tda.contentprovidertda"
            android:exported="true"
            android:readPermission="true"
            android:writePermission="true" />
    
        <activity
            android:name=".ActivitySearch"
            android:label="Rule Search"
            android:launchMode="singleTop" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
    
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
    
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
    </application>
    
    </manifest>
    

    我想我只是更改了活动的类名,否则我不必更改任何 java 代码。这是我的活动:

    package com.birdsall.tda;
    
    
    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;
    
    public class ActivityTakePhoto 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 + "BCM_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_LONG).show();
      }
    });
      }
    }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      不确定这是否对您有很大帮助,但是是的,我让 QuickStart 应用程序与 Eclipse/Kepler 一起工作。我在使用 Eclipse/Juno 时遇到了很多问题,并且还阅读了有关 Juno 和 ADT 如何不完全正确啮合的帖子。

      我目前正在使用他们的部分代码将文本文件从手机上传到云端硬盘。我有一个运行 4.2.2 的 Nexus 4。我注意到 Quickstart 应用程序的最低 API 级别是 4.2,所以这可能就是问题所在。您是否在 4.2 模拟器而不是 Note 上尝试过?

      是的,这是一项简单的任务,但必须完全正确设置。 Drive 有自己的文件处理方式(即不会覆盖同名文件,只会创建另一个文件)。

      【讨论】:

      • 他们有 4.1.2 的例子吗?大多数 S3 和 Note 1/2 用户仍在使用 4.1.2
      • AFAIK 他们唯一的例子是 4.2。我对 4.1 和 4.2 之间的区别不太熟悉。
      猜你喜欢
      • 1970-01-01
      • 2012-07-18
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多