6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

YoutubePlayerSupportFragmentがandroid11でinitializeに失敗するエラー(Service Missing)の対処法

Last updated at Posted at 2020-11-13

##背景
android11の端末でのみYoutubePlayerSupportFragmentを利用して動画を再生したがinitializeの時にエラー(Service Missing)を返却して再生できなくなった。
コード上でerror表示はあったがビルドは通るしandroid10までの端末では問題なく再生できたので調査を行った。

##対処法
以前投稿したandroid11でTextToSpeechが動作しない時の対処法とほぼ同じ方法で動作するようになった。
マニフェストのqueriesに以下のように追加すると動作するようになります。

AndroidManifest.xml
<manifest>
  ・・・
    <queries>
   ・・・
        <intent>
            <action android:name="com.google.android.youtube.api.service.START" />
        </intent>
    </queries>
</manifest>

これを追加することで無事動画は再生されます。

##別のエラー
上記の方法でビルドは通り動画は再生できるようになりますが、transaction.addの部分にErrorの表示が出ます。

YoutubeFragment.java
// YouTubeフラグメントインスタンスを取得
        YouTubePlayerSupportFragment youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance();

        // レイアウトにYouTubeフラグメントを追加
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.add(R.id.youtube_layout, youTubePlayerFragment).commit();
//                      ↑ここにエラーが表示される

原因はandroidX対応している場合、androidx.fragment.app.FragmentTransactionをimportすることになるが、YoutubeSupportFragmentがandroid.support.v4.app.Fragmentをextendしている為,
Cannot resolve method addというエラーが表示されます。

##対処法
ビルド可能なので対応としてはandroidx対応したYoutubeSuppportFragmentが提供されるのを待つでも良いですが、自分でandroidXに対応した YouTubePlayerSupportFragment(YouTubePlayerSupportFragmentX)を作成するという方法があります。

Projectのjava配下にcom.google.android.youtube.playerというディレクトリを作成し、androidX対応したYoutubePlayerSupportFragmentXを作ればエラーは消えます。
スクリーンショット 2020-11-13 16.46.44.png

YoutubePlayerSupportFragmentXの中身はYoutubePlayerSupportFragmentからコピペしてYoutubePlayerSupportFragmentXにリネームしてimportを置換えます。

import android.support.v4.app.Fragment;
→ import androidx.fragment.app.Fragment;

import android.support.v4.app.FragmentActivity;
→ import androidx.fragment.app.FragmentActivity;

YoutubePlayerSupportFragmentX.java
package com.google.android.youtube.player;

import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.google.android.youtube.player.internal.ab;

public class YouTubePlayerSupportFragmentX extends Fragment implements YouTubePlayer.Provider {
    private final YouTubePlayerSupportFragmentX.a a = new YouTubePlayerSupportFragmentX.a();
    private Bundle b;
    private YouTubePlayerView c;
    private String d;
    private YouTubePlayer.OnInitializedListener e;
    private boolean f;

    public static YouTubePlayerSupportFragmentX newInstance() {
        return new YouTubePlayerSupportFragmentX();
    }

    public YouTubePlayerSupportFragmentX() {
    }

    public void initialize(String var1, YouTubePlayer.OnInitializedListener var2) {
        this.d = ab.a(var1, "Developer key cannot be null or empty");
        this.e = var2;
        this.a();
    }

    private void a() {
        if (this.c != null && this.e != null) {
            this.c.a(this.f);
            this.c.a(this.getActivity(), this, this.d, this.e, this.b);
            this.b = null;
            this.e = null;
        }

    }

    public void onCreate(Bundle var1) {
        super.onCreate(var1);
        this.b = var1 != null ? var1.getBundle("YouTubePlayerSupportFragment.KEY_PLAYER_VIEW_STATE") : null;
    }

    public View onCreateView(LayoutInflater var1, ViewGroup var2, Bundle var3) {
        this.c = new YouTubePlayerView(this.getActivity(), (AttributeSet)null, 0, this.a);
        this.a();
        return this.c;
    }

    public void onStart() {
        super.onStart();
        this.c.a();
    }

    public void onResume() {
        super.onResume();
        this.c.b();
    }

    public void onPause() {
        this.c.c();
        super.onPause();
    }

    public void onSaveInstanceState(Bundle var1) {
        super.onSaveInstanceState(var1);
        Bundle var2 = this.c != null ? this.c.e() : this.b;
        var1.putBundle("YouTubePlayerSupportFragment.KEY_PLAYER_VIEW_STATE", var2);
    }

    public void onStop() {
        this.c.d();
        super.onStop();
    }

    public void onDestroyView() {
        this.c.c(this.getActivity().isFinishing());
        this.c = null;
        super.onDestroyView();
    }

    public void onDestroy() {
        if (this.c != null) {
            FragmentActivity var1 = this.getActivity();
            this.c.b(var1 == null || var1.isFinishing());
        }

        super.onDestroy();
    }

    private final class a implements YouTubePlayerView.b {
        private a() {
        }

        public final void a(YouTubePlayerView var1, String var2, YouTubePlayer.OnInitializedListener var3) {
            YouTubePlayerSupportFragmentX.this.initialize(var2, YouTubePlayerSupportFragmentX.this.e);
        }

        public final void a(YouTubePlayerView var1) {
        }
    }
}

##参考
https://stackoverflow.com/questions/52577000/youtube-player-support-fragment-no-longer-working-on-android-studio-3-2-android
https://gist.github.com/medyo/f226b967213c3b8ec6f6bebb5338a492
https://stackoverflow.com/questions/63909770/why-youtube-player-api-does-not-work-on-android-11

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?