2012-10-28 42 views
6

Tôi đang cố triển khai ví dụ Google Drive của Stephen Wylie (here). Đây là mã của tôi:Không tìm thấy Hoạt động SDK Google Drive Ngoại lệ

package com.googledrive.googledriveapp; 
// For Google Drive/Play Services 
// Version 1.1 - Added new comments & removed dead code 
// Stephen Wylie - 10/20/2012 
import java.io.IOException; 
import java.util.ArrayList; 

import android.accounts.Account; 
import android.accounts.AccountManager; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.DialogInterface.OnClickListener; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 

import com.google.android.gms.auth.GoogleAuthException; 
import com.google.android.gms.auth.GoogleAuthUtil; 
import com.google.android.gms.auth.UserRecoverableAuthException; 
import com.google.android.gms.common.AccountPicker; 
import com.google.api.client.auth.oauth2.BearerToken; 
import com.google.api.client.auth.oauth2.Credential; 
import com.google.api.client.extensions.android2.AndroidHttp; 
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager; 
import com.google.api.client.http.HttpRequestFactory; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.http.json.JsonHttpRequest; 
import com.google.api.client.http.json.JsonHttpRequestInitializer; 
import com.google.api.client.json.jackson.JacksonFactory; 
import com.google.api.services.drive.Drive; 
import com.google.api.services.drive.Drive.Apps.List; 
import com.google.api.services.drive.Drive.Files; 
import com.google.api.services.drive.DriveRequest; 
import com.google.api.services.drive.DriveScopes; 
import com.google.api.services.drive.model.File; 
import com.google.api.services.drive.model.FileList; 

public class MainActivity extends Activity { 
    private static final int CHOOSE_ACCOUNT=0; 
    private static String accountName; 
    private static int REQUEST_TOKEN=0; 
    private Button btn_drive; 
    private Context ctx = this; 
    private Activity a = this; 

    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     // set up the GUI layout 
     setContentView(R.layout.activity_main); 
     // set the variables to access the GUI controls 
     btn_drive = (Button) findViewById(R.id.btn_drive); 
      btn_drive.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       chooseAccount(); 
      } 
      }); 
    } 

    public void chooseAccount() { 
     Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null, null, null, null); 
     startActivityForResult(intent, CHOOSE_ACCOUNT); 
    } 

    // Fetch the access token asynchronously. 
    void getAndUseAuthTokenInAsyncTask(Account account) { 
     AsyncTask<Account, String, String> task = new AsyncTask<Account, String, String>() { 
      ProgressDialog progressDlg; 
      AsyncTask<Account, String, String> me = this; 

      @Override 
      protected void onPreExecute() { 
       progressDlg = new ProgressDialog(ctx, ProgressDialog.STYLE_SPINNER); 
       progressDlg.setMax(100); 
       progressDlg.setTitle("Validating..."); 
       progressDlg.setMessage("Verifying the login data you entered...\n\nThis action will time out after 10 seconds."); 
       progressDlg.setCancelable(false); 
       progressDlg.setIndeterminate(false); 
       progressDlg.setOnCancelListener(new android.content.DialogInterface.OnCancelListener() { 
        public void onCancel(DialogInterface d) { 
         progressDlg.dismiss(); 
         me.cancel(true); 
        } 
       }); 
       progressDlg.show(); 
      } 

      @Override 
      protected String doInBackground(Account... params) { 
       return getAccessToken(params[0]); 
      } 

      @Override 
      protected void onPostExecute(String s) { 
       if (s == null) { 
        // Wait for the extra intent 
       } else { 
        accountName = s; 
        getDriveFiles(); 
       } 
       progressDlg.dismiss(); 
      } 
     }; 
     task.execute(account); 
    } 

    /** 
    * Fetches the token from a particular Google account chosen by the user. DO NOT RUN THIS DIRECTLY. It must be run asynchronously inside an AsyncTask. 
    * @param activity 
    * @param account 
    * @return 
    */ 
    private String getAccessToken(Account account) { 
     try { 
      return GoogleAuthUtil.getToken(ctx, account.name, "oauth2:" + DriveScopes.DRIVE_READONLY); // IMPORTANT: DriveScopes must be changed depending on what level of access you want 
     } catch (UserRecoverableAuthException e) { 
      // Start the Approval Screen intent, if not run from an Activity, add the Intent.FLAG_ACTIVITY_NEW_TASK flag. 
      a.startActivityForResult(e.getIntent(), REQUEST_TOKEN); 
      e.printStackTrace(); 
      return null; 
     } catch (GoogleAuthException e) { 
      e.printStackTrace(); 
      return null; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    private Drive getDriveService() { 
     HttpTransport ht = AndroidHttp.newCompatibleTransport();    // Makes a transport compatible with both Android 2.2- and 2.3+ 
     JacksonFactory jf = new JacksonFactory();       // You need a JSON parser to help you out with the API response 
     Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(accountName); 
     HttpRequestFactory rf = ht.createRequestFactory(credential); 
     Drive.Builder b = new Drive.Builder(ht, jf, null); 
     b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { 

      @Override 
      public void initialize(JsonHttpRequest request) throws IOException { 
       DriveRequest driveRequest = (DriveRequest) request; 
       driveRequest.setPrettyPrint(true); 
       driveRequest.setOauthToken(accountName); 
      } 
     }); 
     return b.build(); 
    } 

    /** 
    * Obtains a list of all files on the signed-in user's Google Drive account. 
    */ 
    private void getDriveFiles() { 
     Drive service = getDriveService(); 
     Log.d("SiteTrack", "FUNCTION getDriveFiles()"); 
     Files.List request; 
     try { 
      request = service.files().list(); // .setQ("mimeType=\"text/plain\""); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return; 
     } 
     do { 
      FileList files; 
      try { 
       Log.d("SiteTrack", request.toString()); 
       files = request.execute(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       Log.d("SiteTrack", "Exception"); 
       return; 
      } 
      ArrayList<File> fileList = (ArrayList<File>) files.getItems(); 
      Log.d("SiteTrack", "Files found: " + files.getItems().size()); 
      for (File f : fileList) { 
       String fileId = f.getId(); 
       String title = f.getTitle(); 
       Log.d("SiteTrack", "File " + fileId + ": " + title); 
      } 
      request.setPageToken(files.getNextPageToken()); 
     } while (request.getPageToken() != null && request.getPageToken().length() >= 0); 
    } 

    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { 
     if (requestCode == CHOOSE_ACCOUNT && resultCode == RESULT_OK) { 
      accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); 
      GoogleAccountManager gam = new GoogleAccountManager(this); 
      getAndUseAuthTokenInAsyncTask(gam.getAccountByName(accountName)); 
      Log.d("SiteTrack", "CHOOSE_ACCOUNT"); 
     } else if (requestCode == REQUEST_TOKEN && resultCode == RESULT_OK) { 
      accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); 
      Log.d("SiteTrack", "REQUEST_TOKEN"); 
     } 
    } 
} 

Đây là biểu hiện của tôi:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.googledrive.googledriveapp" 
    android:versionCode="1" 
    android:versionName="1.0" > 

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

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

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
      <meta-data 
       android:name="android.support.PARENT_ACTIVITY" 
       android:value="android.app.ActivityGroup" /> 
     </activity> 
    </application> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
</manifest> 

Đây là activity_main.xml tôi:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <Button 
     android:id="@+id/btn_drive" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Connect to Google Drive" /> 
</LinearLayout> 

Và đây là lỗi LogCat tôi nhận được. Điều này xảy ra khi nút được nhấn:

10-28 00:25:28.637: E/AndroidRuntime(842): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.google.android.gms.common.account.CHOOSE_ACCOUNT (has extras) } 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1512) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1384) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.Activity.startActivityForResult(Activity.java:3190) 
10-28 00:25:28.637: E/AndroidRuntime(842): at com.googledrive.googledriveapp.MainActivity.chooseAccount(MainActivity.java:67) 
10-28 00:25:28.637: E/AndroidRuntime(842): at com.googledrive.googledriveapp.MainActivity$1.onClick(MainActivity.java:60) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.view.View.performClick(View.java:3511) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.view.View$PerformClick.run(View.java:14105) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.os.Handler.handleCallback(Handler.java:605) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.os.Handler.dispatchMessage(Handler.java:92) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.os.Looper.loop(Looper.java:137) 
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.ActivityThread.main(ActivityThread.java:4424) 
10-28 00:25:28.637: E/AndroidRuntime(842): at java.lang.reflect.Method.invokeNative(Native Method) 
10-28 00:25:28.637: E/AndroidRuntime(842): at java.lang.reflect.Method.invoke(Method.java:511) 
10-28 00:25:28.637: E/AndroidRuntime(842): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
10-28 00:25:28.637: E/AndroidRuntime(842): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
10-28 00:25:28.637: E/AndroidRuntime(842): at dalvik.system.NativeStart.main(Native Method) 

Có ai có thể giúp bạn không?

Trả lời

7

API Google Drive dường như (theo người của Google) chỉ hoạt động trên một Thiết bị thực, trong Trình mô phỏng nó sẽ gặp sự cố với lỗi này.

Vì vậy, lời khuyên của tôi, hãy thử trên một thiết bị thực.

+0

Vâng, tôi đã nghe điều tương tự - loại không may. Ồ, tốt. Cảm ơn bạn đã mở một trường hợp lạnh. –

+0

Đã có mặt trên phiên họp với người của Google, đã gặp lỗi tương tự .. họ đã nói với tôi ... – Frank

+0

Điều này được sử dụng để hoạt động, giờ đây nó cũng bị hỏng đối với tôi trong trình mô phỏng API 23. – powder366

8

Chúng tôi đã thực hiện một số thử nghiệm và lý thuyết hiện tại của chúng tôi là Thư viện Google OAuth mới phụ thuộc vào việc có phiên bản Google Play mới nhất.

Chúng tôi nhận thấy rằng nếu thiết bị của bạn vẫn có Android Marketplace hoặc Google Play cũ hơn, chúng tôi không thể yêu cầu OAuth hoạt động.

Vì vậy, bạn có thể thử mở Android Marketplace hoặc Google Play App để bắt đầu nâng cấp.

Mở Android Marketplace, Chấp nhận nâng cấp lên Google Play.
Đóng Marketplace và mở ứng dụng Google Play. Chấp nhận Điều khoản dịch vụ dành cho Google Play. Đợi vài giây, hy sinh một con gà, và sau đó bạn sẽ có thể chạy Google OAuth.

EDIT: Có vẻ như Google Cung cấp một số hướng dẫn về ứng dụng của bạn nên làm gì nếu người dùng của bạn thiếu phiên bản Google Play chính xác. Xem: https://developer.android.com/google/play-services/setup.html#ensure

Các vấn đề liên quan