execute youtube playlists got GoogleJsonResponseEx

2019-05-31 01:24发布

问题:

I use android AccountManager to get authToken like this:

private void getGoogleAccountName(){
    AccountManager.get(activity.getApplicationContext())
        .getAuthTokenByFeatures("com.google", "oauth2:https://gdata.youtube.com", null, activity, null, null, this, null);
}

// I implement AccountManagerCallback<Bundle> in this class
@Override
public void run(AccountManagerFuture<Bundle> future) {
    boolean hasAccount = checkGoogleAccount(future);

    if (hasAccount) {
        getYoutubeVideoByLib("");
    }
}

private boolean checkGoogleAccount(AccountManagerFuture<Bundle> future){
    try {
        Bundle bundle = future.getResult();
        accountName = bundle.getString(AccountManager.KEY_ACCOUNT_NAME);
        authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
    } catch (Exception e) {
        return false;
    }
    return true;
}

then I use google apis with authToken trying to get user's playlists

private void getYoutubeVideoByLib(String pageToken){
    YouTube youtube = new YouTube.Builder(
        new NetHttpTransport(),
        new JacksonFactory(), 
        new HttpRequestInitializer() {
            @Override
            public void initialize(HttpRequest request) throws IOException {
            }
        }).setApplicationName(activity.getString(R.string.app_name)).build();

    YouTube.Playlists.List query = null;
    try{
        query = youtube.playlists().list("snippet");
        query.setOauthToken(authToken);
        query.setKey("YOUTBE_API_KEY");
        query.setMine(true);
        if(!TextUtils.isEmpty(pageToken)) {
            query.setPageToken(pageToken);
        }

        PlaylistListResponse response = query.execute();
        ...
    } catch(IOException e) {
        return;
    }
}

but I found out some google account got GoogleJsonResponseException in query.execute();

com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
    "code" : 401,
     "errors" : [ {
        "domain" : "global",
        "location" : "Authorization",
        "locationType" : "header",
        "message" : "Invalid Credentials",
         "reason" : "authError"
        } ],
    "message" : "Invalid Credentials"
}

the weird thing is that, some accounts work fine before but after these users got this exception, they can't get their playlists anymore.

Does anyone meet the same problem?

===================================================================

I solved it myself. I made a big mistake... In google developer console, I set API KEY but not OAuth 2.0 client ID. After setting both and change code below, it work fine now.

String[] SCOPES = {YouTubeScopes.YOUTUBE_READONLY};
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES));
credential.setSelectedAccountName(accountName);

YouTube youtube = new YouTube.Builder(transport, jsonFactory,  credential).setApplicationName(getString(R.string.app_name)).build();