Фрагмент поддержки проигрывателя YouTube аварийно завершает работу, когда пользователь выбирает просмотр в полноэкранном режиме

Я реализовал API YouTubePlayerSupportFragment внутри своего собственного фрагмента, а не в действии. Видео воспроизводится нормально, но когда пользователь выбирает просмотр видео в полноэкранном режиме из предоставленных YouTube элементов управления мультимедиа, приложение ориентируется на альбомную ориентацию, показывает черный экран загрузки, а затем сразу же аварийно завершает работу.

ExpandedItem.layout

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 <LinearLayout
    android:id="@+id/youtube_layout_container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/close_button">

    <fragment
        android:id="@+id/youtube_player_fragment"
        android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginTop="15dp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

ExpandedItemFragment.kt

import android.os.Bundle
import android.text.SpannableString
import android.text.style.BulletSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.android.youtube.player.YouTubeInitializationResult
import com.google.android.youtube.player.YouTubePlayer
import com.google.android.youtube.player.YouTubePlayerSupportFragment
class ExpandedItemFragment(private val hasVideo: Boolean) : Fragment(), YouTubePlayer.OnInitializedListener {
    private lateinit var mosquitoVideo: YouTubePlayerSupportFragment

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(
            R.layout.expanded_item, container, false
        )
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        initializeLayout()
    }

    private fun initializeLayout() {
        if (hasVideo) {
           youTubeLayoutContainer.visibility = View.VISIBLE
           mosquitoVideo =
              childFragmentManager.findFragmentById(R.id.youtube_player_fragment) as YouTubePlayerSupportFragment
           mosquitoVideo.initialize(getString(R.string.google_api_key), this)
        }
    }
override fun onInitializationSuccess(
        provider: YouTubePlayer.Provider,
        youTubePlayer: YouTubePlayer,
        b: Boolean
    ) {
        if (!b) {
            youTubePlayer.cueVideo("rD8SmacBUcU")
        }
    }

    override fun onInitializationFailure(
        provider: YouTubePlayer.Provider,
        youTubeInitializationResult: YouTubeInitializationResult
    ) {
        Toast.makeText(activity, "Youtube video failed to play", Toast.LENGTH_SHORT).show()
    }

ExpandedItemFragment нормально расширяется, когда видео еще не в полноэкранном режиме, но после того, как пользователь выбирает его в полноэкранном режиме, приложение аварийно завершает работу. Выбрасывается исключение:

Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.mosquitotracker.ExpandedItemFragment: could not find Fragment constructor 

Исключение находится в моем файле MainActivity.kt по адресу

super.onCreate(savedInstanceState)

person nenur    schedule 18.11.2019    source источник
comment
В сообщении об ошибке говорится, что по умолчанию вам нужно иметь конструктор без аргументов - именно так FragmentManager создает фрагменты после изменений конфигурации или смерти и восстановления процесса.   -  person ianhanniballake    schedule 19.11.2019


Ответы (2)


Причина сбоя моего приложения, когда пользователь выбирает перевод видео YouTube в полноэкранный режим, заключалась в том, что YouTubePlayerSupportFragment автоматически поворачивается в ландшафтный режим. Я не обрабатывал должным образом изменения конфигурации в действии, которое раздуло мой фрагмент, поэтому у него возникли проблемы с попыткой повторного раздувания фрагмента, и это привело к сбою моего приложения. Для всех, у кого есть подобные проблемы, я предлагаю либо обрабатывать изменения конфигурации вручную, либо добавлять android:configChanges="orientation|keyboardHidden к любому действию, содержащему фрагмент, который наполняет YouTubePlayerSupportFragment внутри него. Код, который я предоставил в своем вопросе, будет работать для всех, кто пытается реализовать YouTubePlayerSupportFragment внутри фрагмента, а не действия.

person nenur    schedule 19.11.2019
comment
Вы только что замаскировали проблему - вы все равно столкнетесь с тем же исключением, когда ваш процесс умрет и будет воссоздан (например, если вы используете параметр разработчика для «Не сохранять действия») - person ianhanniballake; 19.11.2019

Компонент YouTubePlayer плохо работает с фрагментами, нужно открывать в активности только для видео, но мой вам совет — используйте этот компонент здесь https://github.com/PierfrancescoSoffritti/android-youtube-player

добавить в build.grandle

dependencies {
     implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5'
        }

добавить к вам XML

<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
        android:id="@+id/youtube_player_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
       />

загрузить видео

YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);


youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
  @Override
  public void onReady(@NonNull YouTubePlayer youTubePlayer) {
    String videoId = "rD8SmacBUcU";
    youTubePlayer.loadVideo(videoId, 0);
  }
});

Этот компонент реализует веб-фрейм, вам не нужно генерировать ключ доступа для использования API YoutTube, отрицательная точка запуска рекламы

person Anderson Soares    schedule 18.11.2019
comment
Я бы сделал это как действие, так как это кажется самым простым решением, но из-за того, что мое приложение написано для оптимизации других функций, мне приходится использовать его во фрагменте. Чем плохо это решение? - person nenur; 19.11.2019
comment
Я понял, почему, и этот ответ не помогает. - person nenur; 19.11.2019
comment
Проект, который я сделал, у меня была проблема, когда я играл в YoutubePlayer внутри фрагмента, если вы используете youtube внутри действия, работает хорошо, но если вам нужно поместить вкладки, например, с другими видео, не работает, только один проигрыватель по действию - person Anderson Soares; 19.11.2019