8

When I try to use YouTube API for Search, I get this error:

There was a service error: 403 : The request did not specify any Android package name or signing-certificate fingerprint. Please ensure that the client is sending them or use the API Console to update your key restrictions.

In the MainActivity I have this code:

youtube = new YouTube.Builder(new NetHttpTransport(), JSON_FACTORY, new HttpRequestInitializer() {
                    @Override
                    public void initialize(HttpRequest httpRequest) throws IOException {

                    }
                }).setYouTubeRequestInitializer(new YouTubeRequestInitializer(apiKey)).setApplicationName("Some Name").build();

In the cloud console I have an ApiKey for Android, with the package name set and the SHA-1 number obtained with keytool command.

Bishan
  • 15,211
  • 52
  • 164
  • 258
Federico Blumetto
  • 967
  • 1
  • 7
  • 12

3 Answers3

21

At last I found a solution for this problem :)

After creating API_KEY in Google Developer Console and restrict it with "Package name" and "SHA-1 certificate fingerprint", You have to provide these data in every youtube api request. Below the steps:

1- get Package Name:

String packageName = context.getPackageName();

2- get SHA-1:

private String getSHA1(String packageName){
    try {
        Signature[] signatures = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures;
        for (Signature signature: signatures) {
            MessageDigest md;
            md = MessageDigest.getInstance("SHA-1");
            md.update(signature.toByteArray());
            return BaseEncoding.base16().encode(md.digest());
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

3- Prepare youtube api http header:

youTube = new YouTube.Builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(), new HttpRequestInitializer() {
    @Override
    public void initialize(HttpRequest request) throws IOException {
        String packageName = context.getPackageName();
        String SHA1 = getSHA1(packageName);

        request.getHeaders().set("X-Android-Package", packageName);
        request.getHeaders().set("X-Android-Cert",SHA1);
    }
}).setApplicationName(appName).build();

4- Build your youtube api query as you like: For example to search for video:

YouTube.Search.List query;
query = youTube.search().list("id, snippet");
query.setKey(YOUR_API_KEY);
query.setType("video");
query.setFields("items(id/videoId,snippet/title,snippet/description,snippet/thumbnails/default/url)");
query.setQ(search keywords);
SearchListResponse response = query.execute();
List<SearchResult> results = response.getItems();

then process returned search results.

Ayman Al-Absi
  • 2,630
  • 24
  • 22
  • Where did you find info for putting the package and sha1 fingerprint there? – DennisVA May 31 '17 at 23:40
  • when you create Android Client key for your project, package name and SHA-1 is required. – Ayman Al-Absi Jun 01 '17 at 21:31
  • 6
    Where did you find this document about hot to add package name and SHA1 fingerprint into a request headers? – Kimi Chiu Jul 03 '17 at 03:04
  • Where did you found those cert and package headers specified in docs :)? – xyman Jul 22 '17 at 22:08
  • You may check steps in this link https://stackoverflow.com/questions/27609442/how-to-get-the-sha-1-fingerprint-certificate-in-android-studio-for-debug-mode – Ayman Al-Absi Jul 24 '17 at 08:48
  • Package name is equivalent to `BuildConfig.APPLICATION_ID` – ramon Mar 23 '18 at 21:24
  • Did you use okhttp for this? – RoCkDevstack May 25 '18 at 04:29
  • 1
    @AymanAl-Absi I tried your above solution. Still i'm getting error as ( "The Android package name and signing-certificate fingerprint, com.example.somename and ZFzdtB22bpkKGc1kSgi0qxUPSWk=, do not match the app restrictions configured on your API key.") – Audumbar Mar 11 '19 at 11:55
  • @JianLi Still no luck. https://stackoverflow.com/questions/55101196/android-youtube-api-v3-search-not-working – Audumbar Sep 27 '19 at 05:41
  • 2
    @Audumbar try sending the SHA1 in lower case hexcode format e.g:(AB:8A:CC:7R....) as (ab8acc7r...). worked for me. – Abhisek Mallick Oct 10 '19 at 17:58
  • Use this link for getting the SHA in all Android versions as packageManager.signatures is deprecated in Android P. https://stackoverflow.com/a/53407183/5095473 – Mehul Kanzariya Mar 12 '20 at 14:06
15

After lot of trial and error, the thing which finally worked for me was changing API KEY restriction to None instead of Android from API Manager console and just save. enter image description here

After doing the above step I am able to make search API call from my Android device using my API KEY.

Exception
  • 2,273
  • 1
  • 24
  • 42
2

Try to double check if you follow properly the setup when creating OAuth Credentials. And make sure you enable the YouTube Data API in your Developer Console.

Here the steps that you need to do.

  1. In the Package name field, enter your Android app's package name

  2. In a terminal, run the Keytool utility to get the SHA1 fingerprint for your digitally signed .apk file's public certificate.

keytool -exportcert -alias androiddebugkey -keystore path-to-debug-or-production-keystore -list -v

  1. Paste the SHA1 fingerprint into the form where requested.

I also found here in this SO question answered by a Googler that a user has to go through OAuth2. Because Service accounts are not supported in Data API v3.

Community
  • 1
  • 1
adjuremods
  • 2,938
  • 2
  • 12
  • 17