即使在获得许可后也始终获得NEED_PERMISSION异常

时间:2013-07-20 06:58:38

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

我正在使用Google云端硬盘跨客户端身份,以便当用户向我的Android应用授予驱动器访问权限时,我的网络服务器也可以访问用户Google云端硬盘。

首先,我必须获得授权码。为此,我使用以下代码:

private String getAccessToken(Context mContext) {
      String SERVER_CLIENT_ID = "1009999994.apps.googleusrcontent.com";
      String scopes = "oauth2:server:client_id:"+SERVER_CLIENT_ID+":api_scope:"+DriveScopes.DRIVE;
      String accessToken = null;

      try {
        accessToken = GoogleAuthUtil.getToken(mContext, accountName, scopes); 
        Log.d("token is:", "token:"+accessToken);
    } catch (UserRecoverableAuthException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    } catch (GoogleAuthException e) {

        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

      return accessToken;
  }

以下是我在Logcat中遇到的异常:

   07-20 12:12:10.210: W/GLSActivity(29164): [qq] Status from wire: INVALID_SCOPE status: INVALID_SCOPE
    07-20 12:12:12.453: W/System.err(29037): com.google.android.gms.auth.GoogleAuthException: INVALID_SCOPE
    07-20 12:12:12.492: W/System.err(29037):    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    07-20 12:12:12.492: W/System.err(29037):    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    07-20 12:12:12.500: W/System.err(29037):    at com.example.googledriveaccess1.MainActivity.getAccessToken(MainActivity.java:161)
    07-20 12:12:12.500: W/System.err(29037):    at com.example.googledriveaccess1.MainActivity.access$0(MainActivity.java:155)

这里我使用相同的项目进行Android和服务器端访问。 我也传递了Web的Client-ID。

之前我没有使用跨客户端身份和我的应用正确获取访问令牌。

以前我的范围是

String scope = "oauth2:"+DriveScopes.DRIVE;

等待你的回复

修改:2

我在这里上传完整的代码。在此代码中,我使用PLUS.LOGIN范围以及DriveScope.Drive解决了INVALID_SCOPE问题。

package com.example.googleaccess;

import java.io.IOException;

import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.plus.PlusClient;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.services.drive.DriveScopes;


public class MainActivity extends Activity {

    private String accountName = null;
    private GoogleAccountCredential credential;
    private int REQUEST_ACCOUNT_PICKER = 2;
    private int REQUEST_AUTHORIZATION = 11;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String CLIENT_ID = "60000000007.apps.googleusercontent.com";
        String scope = "server:client_id:"+CLIENT_ID+":api_scope:"+DriveScopes.DRIVE+" "+"https://www.googleapis.com/auth/plus.login";
        credential = GoogleAccountCredential.usingOAuth2(MainActivity.this, scope);
        startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
        GooglePlayServicesUtil.isGooglePlayServicesAvailable(MainActivity.this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return false;
    }

    class Async extends AsyncTask<Void, Void, Void> {

        Context credential = null;

        public Async(Context credential) {
            this.credential = credential;
        }

        @Override
        protected Void doInBackground(Void... params) {
            getAccessToken(credential);
            return null;
        }

    }

    public void getAccessToken(Context mContext) {

        try {

            String token = credential.getToken();
            Log.d("Token", "token:"+token);
        } catch (GooglePlayServicesAvailabilityException playEx) {
            playEx.getMessage();
            playEx.printStackTrace();

          }catch (UserRecoverableAuthException e) {
            e.printStackTrace();
            Log.d("Token", "token:"+e.getCause());

            startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("Token", "token:"+e.getMessage());
        } catch (GoogleAuthException e) {
            e.printStackTrace();
            Log.d("Token", "token:"+e.getMessage());
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == REQUEST_ACCOUNT_PICKER) {
            if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
            accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);

                if (accountName != null) {
                  credential.setSelectedAccountName(accountName);

                  new Async(getApplicationContext()).execute();
                }
              }
        }

        if(requestCode == REQUEST_AUTHORIZATION) {
            if (resultCode == Activity.RESULT_OK) {
                data.getExtras();
                new Async(getApplicationContext()).execute();
              } else {
                  startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
              }
        }
    }


}

现在我总是遇到Need_Permission异常,我总是从设备那里获得许可,但是它没有工作。 一次又一次出现NEED_EXCEPTION错误。您也可以通过输入项目CLIENT_ID来尝试我的代码。请帮助我,我真的陷入了困境。

可能有更多的许可我必须给予,但我现在不允许。

抱歉我的英语不好。

2 个答案:

答案 0 :(得分:5)

使用GoogleAuthUtil.getToken检索交换代码。

final private String CLIENT_ID = "abc123.apps.googleusercontent.com";
final private List<String> SCOPES = Arrays.asList(new String[]{
    "https://www.googleapis.com/auth/plus.login",
    "https://www.googleapis.com/auth/drive"
});

String scope = String.format("oauth2:server:client_id:%s:api_scope:%s", CLIENT_ID, TextUtils.join(" ", SCOPES));
String exchangeCode = GoogleAuthUtil.getToken(context, accountName, scope);

工作样本在https://github.com/googledrive/crossclientoauth2-android上,详细解释在https://developers.google.com/drive/auth/android#cross-client_identity

答案 1 :(得分:0)

示例中的

代码:

startActivityForResult(userRecoverableException.getIntent(), CalendarSampleActivity.REQUEST_AUTHORIZATION);

完整代码:

} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
      activity.showGooglePlayServicesAvailabilityErrorDialog(
          availabilityException.getConnectionStatusCode());
    } catch (UserRecoverableAuthIOException userRecoverableException) {
      activity.startActivityForResult(
          userRecoverableException.getIntent(), CalendarSampleActivity.REQUEST_AUTHORIZATION);
    } catch (IOException e) {
      Utils.logAndShow(activity, CalendarSampleActivity.TAG, e);
    }
    return false;