无法通过Google云端硬盘"选择帐户" Android中的屏幕

时间:2016-07-01 18:06:13

标签: java android google-drive-android-api

我试图在我的Android应用程序中加入Google Drive API。

我已将Google Play服务添加到build.gradle并获取Android API密钥。我的问题是在用户选择帐户的OnResume()内。

它只是不断重新命令用户选择帐户而不会继续。

愿任何人帮助我吗?

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{

    private static final String TAG = "Google Drive Activity";
    private static final int REQUEST_CODE_RESOLUTION = 1;
    private static final  int REQUEST_CODE_OPENER = 2;
    private GoogleApiClient mGoogleApiClient;
    private boolean fileOperation = false;
    private DriveId mFileId;
    public DriveFile file;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    @Override
    protected void onResume() {
        super.onResume();
        if (mGoogleApiClient == null) {

            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(Drive.API)
                    .addScope(Drive.SCOPE_FILE)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }

        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mGoogleApiClient != null) {

            // disconnect Google API client connection
            mGoogleApiClient.disconnect();
        }
        super.onPause();
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());

        if (!result.hasResolution()) {
            GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
            return;
        }


        try {   
            result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
        } catch (IntentSender.SendIntentException e) {
            Log.e(TAG, "Exception while starting resolution activity", e);
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {

        Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onConnectionSuspended(int cause) {

        Log.i(TAG, "GoogleApiClient connection suspended");
    }

    public void onClickCreateFile(View view){
        fileOperation = true;
        Drive.DriveApi.newDriveContents(mGoogleApiClient)
                .setResultCallback(driveContentsCallback);
    }

    public void onClickOpenFile(View view){
        fileOperation = false;
        Drive.DriveApi.newDriveContents(mGoogleApiClient)
                .setResultCallback(driveContentsCallback);
    }

    public void OpenFileFromGoogleDrive(){
        IntentSender intentSender = Drive.DriveApi
                .newOpenFileActivityBuilder()
                .setMimeType(new String[] { "text/plain", "text/html" })
                .build(mGoogleApiClient);
        try {
            startIntentSenderForResult(
                    intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
        } catch (IntentSender.SendIntentException e) {
            Log.w(TAG, "Unable to send intent", e);
        }
    }


    final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
            new ResultCallback<DriveApi.DriveContentsResult>() {
                @Override
                public void onResult(DriveApi.DriveContentsResult result) {
                    if (result.getStatus().isSuccess()) {
                        if (fileOperation == true) {
                            CreateFileOnGoogleDrive(result);
                        } else {
                            OpenFileFromGoogleDrive();
                        }
                    }
                }
            };


    public void CreateFileOnGoogleDrive(DriveApi.DriveContentsResult result){
        final DriveContents driveContents = result.getDriveContents();

        new Thread() {
            @Override
            public void run() {
                // write content to DriveContents
                OutputStream outputStream = driveContents.getOutputStream();
                Writer writer = new OutputStreamWriter(outputStream);
                try {
                    writer.write("Hello abhay!");
                    writer.close();
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage());
                }

                MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                        .setTitle("abhaytest2")
                        .setMimeType("text/plain")
                        .setStarred(true).build();

                Drive.DriveApi.getRootFolder(mGoogleApiClient)
                        .createFile(mGoogleApiClient, changeSet, driveContents)
                        .setResultCallback(fileCallback);
            }
        }.start();
    }

    final private ResultCallback<DriveFolder.DriveFileResult> fileCallback = new
            ResultCallback<DriveFolder.DriveFileResult>() {
                @Override
                public void onResult(DriveFolder.DriveFileResult result) {
                    if (result.getStatus().isSuccess()) {
                        Toast.makeText(getApplicationContext(), "file created: "+""+
                                result.getDriveFile().getDriveId(), Toast.LENGTH_LONG).show();
                    }
                    return;
                }
            };

    @Override
    protected void onActivityResult(final int requestCode,
                                    final int resultCode, final Intent data) {
        switch (requestCode) {
            case REQUEST_CODE_OPENER:
                if (resultCode == RESULT_OK) {
                    mFileId = (DriveId) data.getParcelableExtra(
                            OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
                    Log.e("file id", mFileId.getResourceId() + "");
                    String url = "https://drive.google.com/open?id="+ mFileId.getResourceId();
                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(url));
                    startActivity(i);
                }
                break;
            default:
                super.onActivityResult(requestCode, resultCode, data);
                break;
        }
    }
}

这是我的清单。阻止API密钥。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="edu.moli9479csumb.version1googledrive">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="AIzaSyD_2eJ5pPdRMysVwxxxxxxxxxxxxxx"/>
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4 个答案:

答案 0 :(得分:0)

你可以分享你的清单吗? 尝试向下一个屏幕的班级制作一个明确的清单

答案 1 :(得分:0)

当GoogleApiClient无法连接并且其分辨率要求用户为API授权应用时,您会获得AccountSelector。当你调用“result.startResolutionForResult(this,REQUEST_CODE_RESOLUTION);”时会发生这种情况。来自onConnectionFailed方法。

用户选择帐户后,您的活动会使用代码REQUEST_CODE_RESOLUTION获得回调。必须处理此代码,并且当在onActivityResult方法中收到此代码时,应该再次调用apiClient.connect()进行连接。

有关详细信息,请参阅this。我希望它有效:)

答案 2 :(得分:0)

您可以使用[Account Picker](https://developer.android.com/reference/android/accounts/AccountManager.html#newChooseAccountIntent(android.accounts.Account,java.util.ArrayList,java.lang.String [],boolean,java.lang轻松强制提示用户选择帐户。 String,java.lang.String,java.lang.String [],android.os.Bundle)),普通帐户选择器类似于newChooseAccountIntent中引入的标准框架帐户选择器。返回对Activity的意图,提示用户从帐户列表中进行选择。然后,呼叫者通常会通过呼叫startActivityForResult(intent, ...);来启动活动。

成功时,活动会返回一个包含使用密钥KEY_ACCOUNT_NAMEKEY_ACCOUNT_TYPE指定的帐户名称和类型的捆绑包。

最常见的情况是使用一种帐户类型来调用它,例如:

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

当用户选择和/或创建帐户时,帐户选择器活动将返回,并且可以按如下方式检索生成的帐户名称:

protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) {
if (requestCode == SOME_REQUEST_CODE && resultCode == RESULT_OK) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
}
}

以下是使用上述代码的官方Google示例代码,以及如何使用API​​的具体说明:https://developers.google.com/drive/v3/web/quickstart/android#step_5_setup_the_sample

答案 3 :(得分:0)

查看你的onResume()和onConnectionFailded()方法。

@Override
protected void onResume() {
    super.onResume();
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Drive.API)
                .addScope(Drive.SCOPE_FILE)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }
    mGoogleApiClient.connect();
}


@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());

    if (!result.hasResolution()) {
        GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
        return;
    }


    try {   
        result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
    } catch (IntentSender.SendIntentException e) {
        Log.e(TAG, "Exception while starting resolution activity", e);
    }
}

会发生什么?

在onResume()中,您可以创建GoogleApiClient并调用connect()。由于您未获得帐户授权,因此连接失败。方法onConnectionFailed()被执行,它打开一个分辨率,这实际上是另一个为结果调用的活动。您选择了一个帐户但我认为授权失败或被取消。 您将返回到原始活动并执行onResume()。然后你再去一圈。 为什么您的授权失败?我想因为你的凭证有问题。转到开发人员控制台,为您的包和密钥签名创建O Auth凭证。