0

I'm a newbie Android "programmer" and I've tried to find the answer to this error without luck. There are some half answers but nothing that suggest what to do more exactly in my unique situation.

This error comes when closing a YoutubePlayer activity. It seems I should unregister a receiver, possibly in onPause( )...but how do I do that and maybe more important, which receiver should be unregistered?

Here is my logcat:

06-06 02:17:31.781 26887-26887/? E/ActivityThread: Service com.google.android.youtube.api.service.YouTubeService has leaked IntentReceiver adez@e1c9513 that was originally registered here. Are you missing a call to unregisterReceiver()?
    android.app.IntentReceiverLeaked: Service com.google.android.youtube.api.service.YouTubeService has leaked IntentReceiver adez@e1c9513 that was originally registered here. Are you missing a call to unregisterReceiver()?
        at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:923)
        at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:724)
        at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1182)
        at android.app.ContextImpl.registerReceiver(ContextImpl.java:1162)
        at android.app.ContextImpl.registerReceiver(ContextImpl.java:1156)
        at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:564)
        at adex.<init>(SourceFile:18)
        at adfe.get(SourceFile:15)
        at aerr.get(SourceFile:46)
        at aoqy.get(SourceFile:11)
        at lad.h(SourceFile:148)
        at addo.get(SourceFile:9)
        at aoqy.get(SourceFile:11)
        at laf.a(SourceFile:7)
        at kyp.<init>(SourceFile:10)
        at com.google.android.apps.youtube.embeddedplayer.service.service.jar.ApiPlayerService.<init>(SourceFile:48)
        at com.google.android.apps.youtube.embeddedplayer.service.service.jar.ApiPlayerFactoryService$1.run(SourceFile:4)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5441)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)

Adding some code. Trying to keep it short. Activity:

public class VideoActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener, EasyPermissions.PermissionCallbacks {

This is what I have in onCreate():

youTubeView.initialize("@string/ytkey", this);

...and this is what I have regarding the YoutubePlayer:

@Override
public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored) {
    if (!wasRestored) {
        player.loadVideo(userVideo.getYtId());
         //player.setFullscreen(true);
    }
}

@Override
public void onInitializationFailure(Provider provider, YouTubeInitializationResult errorReason) {
    if (errorReason.isUserRecoverableError()) {
        errorReason.getErrorDialog(this, RECOVERY_REQUEST).show();
    } else {
        String error = String.format(getString(R.string.player_error), errorReason.toString());
        Toast.makeText(this, error, Toast.LENGTH_LONG).show();
    }
}

protected Provider getYouTubePlayerProvider() {
    return youTubeView;
}
John T
  • 814
  • 10
  • 17
  • This issue is regarding memory leak. please check where have you create the instance of player and unregister the instance. – Jaymin Jun 06 '18 at 04:39
  • Navigate on this link- https://stackoverflow.com/questions/35678972/error-youtubeservice-has-leaked-intentreceiver-are-you-missing-a-call-to-un – LuminiousAndroid Jun 06 '18 at 04:46
  • @Jaymin Should be this? youTubeView.initialize("@string/ytkey", this); – John T Jun 06 '18 at 04:48
  • @LuminiousAndroid I've seen that question and didn't find an answer. Neither did the one asking the question. Please see comments on last "answer". – John T Jun 06 '18 at 04:50
  • Can you please post the code? – Jaymin Jun 06 '18 at 04:52
  • @Jaymin Added some code. – John T Jun 06 '18 at 04:58
  • @JohnT, Where have you unregistered player? post that code also. – Jaymin Jun 06 '18 at 05:06
  • @Jaymin I'm sorry for my ignorance but I don't have one...and I don't understand where/how to unregister/release the player. The only place the player object is available is in onInitializationSuccess. – John T Jun 06 '18 at 06:03
  • Works just fine http://stacktips.com/tutorials/android/youtube-android-player-api-example – VVB Jun 06 '18 at 06:19
  • Will take a look @VVB – John T Jun 06 '18 at 06:48
  • @VVB Tested this and it gave the same results. Works without error in emulator but gives error on my physical device. – John T Jun 06 '18 at 09:57
  • @VVB I guess most people have the native YouTube app installed. If I can get my app to work without it...the problem is only solved for me...and I can't use the YouTube native app. Don't see any reason to even try. – John T Jun 06 '18 at 10:22
  • Purpose behind it to check whether leak is occurred by native app, detecting on console – VVB Jun 06 '18 at 11:10
  • @VVB OK, understand your logic. The player don't work at all without the native app installed. – John T Jun 06 '18 at 21:04
  • @VVB OK, not able to view the video at all without the native YouTube app. Request to install without it. If denying, video not possible to view. Have the latest version. For me, only works on emulators with the YouTube native app. The one without it don't load the video. – John T Jun 07 '18 at 05:32

2 Answers2

0

Try this code to make it work:

activity_main.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.youtube.player.YouTubePlayerView
        android:id="@+id/youtube_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends YouTubeBaseActivity implements
    YouTubePlayer.OnInitializedListener {

private static final int REQUEST_DIALOG = 101;

// YouTube player view
private YouTubePlayerView youTubeView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_main);

    youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);

    // Initializing video player with developer key
    youTubeView.initialize(Config.DEVELOPER_API_KEY, this);

}

@Override
public void onInitializationFailure(YouTubePlayer.Provider provider,
        YouTubeInitializationResult errorReason) {
    if (errorReason.isUserRecoverableError()) {
        errorReason.getErrorDialog(this, REQUEST_DIALOG).show();
    } else {
        String errorMessage = String.format(
                getString("Print an error"), errorReason.toString());
        Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
    }
}

@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider,
        YouTubePlayer player, boolean wasRestored) {
    if (!wasRestored) {

        // loadVideo() will auto play video
        // Use cueVideo() method, if you don't want to play it automatically
        player.loadVideo(Config.YOUTUBE_VIDEO_CODE);

        // Hiding player controls
        player.setPlayerStyle(PlayerStyle.CHROMELESS);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == RECOVERY_DIALOG_REQUEST) {
        // Retry initialization if user performed a recovery action
        getYouTubePlayerProvider().initialize(Config.DEVELOPER_API_KEY, this);
    }
}

private YouTubePlayer.Provider getYouTubePlayerProvider() {
    return (YouTubePlayerView) findViewById(R.id.youtube_view);
}

}

AndroidManifest.xml

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
Jaymin
  • 2,879
  • 3
  • 19
  • 35
0

The YouTube Player API is often tricky to use, you may want to consider a WebView-based solution.

For this reason I've built an open source alternative. It's based on WebView and won't give any of this problems. Android-YouTube-Player.

It's a simple View, you can drop it wherever you want. No Activity/Fragment to extend and no leaking services.

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