2012-10-28 13 views
6

Stephen WylieのGoogleドライブの例(here)を実装しようとしています。ここに私のコードは次のとおりです。ここでGoogleドライブSDKのアクティビティが見つかりません例外

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"); 
     } 
    } 
} 

は私のマニフェストです:ここでは

<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> 

は私activity_main.xmlです:

<?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> 

そして、ここでは、私が受け取るLogCatエラーです。ボタンが押されたときに発生します。

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) 

誰でも手助けできますか?

答えて

7

GoogleドライブAPIは実際のデバイスでのみ動作するように見えますが、エミュレータではこのエラーでクラッシュします。

私のアドバイスは、実際のデバイスで試してみてください。

+0

ええ、私は同じことを聞いたことがあります - 残念なことです。しかたがない。コールドケースを開けていただきありがとうございます。 –

+0

Googleの人々とのセッション中に、同じエラーが発生しました。彼らは私に言った... – Frank

+0

これは、今はAPI 23エミュレータで私のために壊れています。 – powder366

8

私たちはいくつかの実験を行ってきましたが、現在の理論では、新しいGoogle OAuthライブラリは最新バージョンのGoogle Playを使用することに依存しています。

お使いの端末にまだAndroidマーケットプレイスまたは古いGoogle Playが搭載されている場合は、OAuthを動作させることができませんでした。

アップグレードを開始するには、AndroidマーケットプレイスまたはGoogle Playアプリを開こうとするとよいでしょう。

Androidマーケットプレイスを開き、Google Playへのアップグレードを承認します。
マーケットプレイスを閉じて、Google Playアプリを開きます。 Google Playの利用規約に同意します。 数秒待って鶏を犠牲にしてください。すると、Google OAuthを実行できるはずです。

EDIT:Googleと似ています。ユーザーが正しいGoogle Playのバージョンを見つけられなかった場合に、アプリが何をすべきかに関するガイダンスを提供します。参照:https://developer.android.com/google/play-services/setup.html#ensure

関連する問題