Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why YouTube Player API does not work on Android 11?

I tried the project explained on this YouTube video of how to play YouTube videos on Android apps:

https://www.youtube.com/watch?v=Up9BjrIuoXY

I tried to play YouTube videos with devices using Android 9 and Android 10 and the videos are played correctly, but in Android 11 devices I received this message inside the YouTube video window:

"An error occurred while initializing the YouTube player".

This is the code of MainActivity.java:

package com.example.youtube;

import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;

import android.widget.Toast;

public class MainActivity extends YouTubeBaseActivity {

    Button play_btn;
    YouTubePlayerView youtubePlayerView;
    YouTubePlayer.OnInitializedListener onInitializedListener;

    private static final int RECOVERY_DIALOG_REQUEST = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        youtubePlayerView = findViewById(R.id.youtubeView);
        play_btn = findViewById(R.id.playvideo_btn);

        final android.app.Activity myActivity = this;

        onInitializedListener =new YouTubePlayer.OnInitializedListener() {
            @Override
            public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
                youTubePlayer.loadVideo("Up9BjrIuoXY");
            }

            @Override
            public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
                if (youTubeInitializationResult.isUserRecoverableError()) {
                    youTubeInitializationResult.getErrorDialog(myActivity, RECOVERY_DIALOG_REQUEST).show();
                } else {
                    String errorMessage = String.format(
                            getString(R.string.error_player), youTubeInitializationResult.toString());
                    Toast.makeText(myActivity, errorMessage, Toast.LENGTH_LONG).show();
                }
            }
        };

        play_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                youtubePlayerView.initialize("AIzaSyZ2", onInitializedListener);
            }
        });

    }
}

YouTube app of the Android 11 devices is updated.

Hope somebody could help me. Thanks!

like image 207
Misael L. Avatar asked Sep 15 '20 20:09

Misael L.


People also ask

Can I use YouTube API in my app?

So, yes, it is legal.

How do I fix an error occurred while initializing the YouTube player?

Update your Android youtube app to the latest version and it will work for Sure!!


4 Answers

With the package visibility restrictions in Android 11 the SDK wont be able to find the Youtube service unless you add a reference to it to your manifest.

<queries>
   <intent>
     <action android:name="com.google.android.youtube.api.service.START" />
   </intent>
</queries>
like image 67
ivagarz Avatar answered Oct 17 '22 01:10

ivagarz


Update to Ivagarz's answer queries tag does not work under application tag So you have to add it outside application tag in manifest tag like this

<manifest
//permissions here
    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        </application>
        <queries>
        <intent>
         <action android:name="com.google.android.youtube.api.service.START"/>
        </intent>
        </queries>
    </manifest>
like image 20
Quick learner Avatar answered Oct 17 '22 02:10

Quick learner


This is happening because from Android 11 onwards (API 30+) Android hides all other apps and services which are not part of the core system apps/services by default, and you have to explicitly declare in your Manifest.xml that you need access to particular apps. From the docs, these are the only apps which you do NOT have to declare you need access to:

  • Your own app.

  • Certain system packages, such as the media provider, that implement core Android functionality. Learn more about how to determine which packages are visible automatically on the device that runs your app. The app that installed your app.

  • Any app that launches an activity in your app using the startActivityForResult() method, as described in the guide about how to get a result from an activity.

  • Any app that starts or binds to a service in your app.

  • Any app that accesses a content provider in your app.

  • Any app that has a content provider, where your app has been granted URI permissions to access that content provider.

  • Any app that receives input from your app. This case applies only when your app provides input as an input method editor.

You can declare that you need access in 3 ways:

...add the element in your app's manifest file. Within the element, specify the other apps by package name, by intent signature, or by provider authority

In the case of YouTube it seems to make most sense to declare by package name, which looks like this (note - the package name is NOT com.youtube!):

<queries>
   <package android:name="com.google.android.youtube" />
</queries>

It appears that you need this even if you're just opening a YouTube web link, I think because if you have YouTube app installed, it registers any attempts to open something like https://youtu.be/blah as a request to the YouTube app, not the web browser.

like image 45
James Allen Avatar answered Oct 17 '22 03:10

James Allen


While specifically requesting the Youtube app works, I found it a bit too specific as the solution would break if a user installed an alternative player (not sure if there are any). I think that the correct explanation is that the Youtube app not only filters for the https scheme, but also for the host "youtube.com" (which makes a lot of sense). So, by specifying the host as well, I got the Youtube app to be available to my app without a package specific declaration:

<queries>    
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data  android:scheme="https" android:host="youtube.com" />
    </intent>
</queries>

BTW: When I tested, both "youtube.com" and "youtu.be" worked equally on both kinds of links. I still threw in both in my app to be safe.

like image 6
Sebastian Staacks Avatar answered Oct 17 '22 02:10

Sebastian Staacks