28

I'm trying to use the YouTubeData API with OAuth 2.0 authentication on Android, and i'm kind of struggling with it.

I've searched a lot online, but there's not much help for the Android implementation.

First of all, it's not clear to me what's the best way to obtain an OAuth token. In the doc they suggest that for Android is better to obtain it using the Google Play services lib. Is that true? if yes, it should be pretty trivial following this guide: https://developers.google.com/android/guides/http-auth. But at this point i will have the token in a String object .. how should I use it with the YouTubeData API? Should I place it somewhere in the YouTube.Builder ?

YouTube youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
        public void initialize(HttpRequest request) throws IOException {
        }
    }).setApplicationName("AppName").build();

if yes, does anyone know where?

Searching on StackOverflow i've come across this question: What to do after getting Auth Token - Android Youtube API. Here Ibrahim Ulukaya says it's better to use GoogleAccountCredential. For what i've understood (Access to Google API - GoogleAccountCredential.usingOAuth2 vs GoogleAuthUtil.getToken()) the Android version of GoogleAccountCredential should use the GoogleAuthUtil provided from the Google Play services lib, so it could be pretty useful to simplify the process. I've looked at the sample project suggested from Ibrahim Ulukaya (https://github.com/youtube/yt-direct-lite-android) and i've implemented everything as he does. But it doesn't seem to work very well as i'm only obtaining this message in the logcat: "There was an IO error: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission : null".
(Note that I've enabled all the required APIs on the Google Console, and created the Client ID for my app)

At this point i'm kind of lost.
Should I use directly the GoogleAuthUtil from the Google Play services lib? in this case once obtained the token as a String how can i use it with the YouTubeData APIs?
Or should I use the GoogleAccountCredential ? in this case someone knows how can I solve the "NeedPersmission : null" error?

---- EDIT:

details on what my app is trying to do: being this my first experience with this kind of APIs I started from the easy stuff: retrieve video information and then play those videos, without any user authentication. I managed to do that pretty easily, but for my app's purpose i need to access the user data, in particular users must be able to like and comment videos. So I started implementing OAuth2, trying to do the same exact queries I was doing before (retrieve video info).

Community
  • 1
  • 1
Pierfrancesco Soffritti
  • 1,678
  • 1
  • 18
  • 22

2 Answers2

6

Wow. The documentation on this is super confusing. Full disclosure, I'm not an Android developer but I am a Java developer who has worked with Google apps and OAuth2.

Google Play or not Google Play? First off, Google Play Services will only be available on Android devices with Google Play Services installed (so not OUYA, Amazon devices, etc.). Google state that "the Google Play library will give you the best possible performance and experience.".

There are numerous discussions (e.g. here, here) from actual Android developers that list the various merits of Google Play verses other techniques. I would imagine that once you are able to get your application working using one method, then it should be an easy enough to change if you so desire.

Much of the example code about uses the Android AccountManager (Tasks and Calendars being favourite examples) so that is what I will show.

Your example code looks like it might be for a simple search, I would guess that many of the YouTube API interactions do not require OAuth2, in other code I've seen this empty HttpRequestInitializer implementation referred to as a no-op function. (e.g. GeolocationSearch.java).

It sounds like you want access to YouTube API operations that need account credentials. You can do something similar to this Android Calendar example (CalendarSampleActivity.java) except with YouTube, like the example answer from here.

// Google Accounts
credential = GoogleAccountCredential.usingOAuth2(this, YouTubeScopes.YOUTUBE, YouTubeScopes.YOUTUBE_READONLY);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
// YouTube client
service =
        new com.google.api.services.youtube.YouTube.Builder(transport, jsonFactory, credential)
            .setApplicationName("Google-YouTubeAndroidSample/1.0").build();

I hope this helps.

Community
  • 1
  • 1
Mark McLaren
  • 11,470
  • 2
  • 48
  • 79
  • Hi, this is exactly what the example from Ibrahim Ulukaya (https://github.com/youtube/yt-direct-lite-android) does. It looks indeed the best solution. The problem is that i'm receiving this error: "There was an IO error: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission : null" in the logcat, and obviously the API doesn't work. Any idea on how to solve it? – Pierfrancesco Soffritti Jul 02 '15 at 15:47
  • http://stackoverflow.com/questions/14383965/userrecoverableauthexception-needpermission I'm sure you know this but your application needs various permissions to access the device features (e.g. Internet!) and access YouTube on the users behalf. Exactly what permissions you need will vary depending on the authentication mechanism you have chosen. See the linked Android discussions where it talks about GET_ACCOUNTS and USE_CREDENTIALS. What does your manifest look like? (it might be worth asking this as a separate question) – Mark McLaren Jul 02 '15 at 16:41
  • See manifest e.g.https://github.com/youtube/yt-direct-lite-android/blob/master/app/src/main/AndroidManifest.xml You also need to include your developer API credentials, e.g. - http://stackoverflow.com/questions/29656454/declare-google-api-key-in-manifest-for-youtube-api. It might be helpful to know exactly what you application is trying to do. – Mark McLaren Jul 02 '15 at 16:48
  • i've been doing some tests focusing on the app's permissions instead of OAuth2, as you suggested. That's not the problem, i've granted all the required user permissions. Also i'm pretty sure i'm using correctly the API key, since without OAuth the YouTube player runs smooth. About what my app is trying to do.. i've just edited my question – Pierfrancesco Soffritti Jul 02 '15 at 19:20
  • 1
    It is getting difficult to diagnose without seeing more code (would you be happy to put it on GitHub?). Do you catch the UserRecoverableAuthIOException and call your activity's startActivityForResult? e.g. https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.19.1/com/google/api/client/googleapis/extensions/android/gms/auth/UserRecoverableAuthIOException and https://github.com/youtube/yt-direct-lite-android/blob/master/app/src/main/java/com/google/ytdl/MainActivity.java – Mark McLaren Jul 02 '15 at 22:07
  • 1
    i didn't catch the `UserRecoverableAuthIOException` and because of that the authentication process never started!! thank you very much for your help and disponibility, now I can authenticate with OAuth2 and execute every query :) – Pierfrancesco Soffritti Jul 03 '15 at 06:52
2

In the initialize method of the HttpRequestInitializer you can set headers of the request. According to Googles documention for Oath2 for devices https://developers.google.com/identity/protocols/OAuth2ForDevices if you have an access token you should put it in the Authorization: Bearer HTTP header.

YouTube youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
    public void initialize(HttpRequest request) throws IOException {
        request.put("Authorization", "Bearer " + yourAccessTokenString);
    }
}).setApplicationName("AppName").build();

Remember the space after the Bearer in the authorization header value

Malthan
  • 7,005
  • 3
  • 20
  • 22