How to stop youtube video playing in Android webview?
Asked Answered
C

18

67

How can I stop a YouTube video which is played in my webview? When I click on the back button the video doesn't stop and instead continues in the background.

Code:

webView = (WebView) findViewById(R.id.webview); 
webView.getSettings().setPluginsEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(false); 
webView.getSettings().setSupportZoom(false);
webView.loadData(myUrl,"text/html", "utf-8");
Crucible answered 10/5, 2011 at 7:35 Comment(3)
Can you post the code you're using?Jugglery
webView = (WebView) findViewById(R.id.webview); webView.getSettings().setPluginsEnabled(true); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setBuiltInZoomControls(false); webView.getSettings().setSupportZoom(false);webView.loadData(myUrl,"text/html", "utf-8");Crucible
Good practice to handle back press https://mcmap.net/q/296803/-android-webview-not-stopping-after-user-presses-back I may help some one.Lilywhite
B
94

See the following post about WebView threads never stopping

Essentially you'll need to call the WebView's onPause method from your own Activity's onPause method.

The only trick with this is that you cannot call the WebView's onPause method directly because it is hidden. Therefore you will need to call it indirectly via reflection. The following code should get you started on setting up your own Activity's onPause method:

@Override
public void onPause() {
    super.onPause();

    try {
        Class.forName("android.webkit.WebView")
                .getMethod("onPause", (Class[]) null)
                            .invoke(webview, (Object[]) null);

    } catch(ClassNotFoundException cnfe) {
        ...
    } catch(NoSuchMethodException nsme) {
        ...
    } catch(InvocationTargetException ite) {
        ...
    } catch (IllegalAccessException iae) {
        ...
    }
}

Note that the variable 'webview' in the try block above is a private instance variable for the class and is assigned to in the Activity's onCreate method.

Blackington answered 3/6, 2011 at 18:3 Comment(12)
i was trying to put logic in "back key press " . but it didnt work. this one worksAutoicous
thank you !!! I was trying for last 8 hours and nothing works. But this is working like a charm !!!Kester
It seems like the WebView.onResume() and WebView.onPause() are not hidden anymore since API 11. See Ryoghurt's answer. On top of that if your fragment is in a ViewPager, you should also call WebView.onPause from Fragment.setUserVisibleHint().Luca
Answer is not up to date. API has changed and webview.onPause() is now available. The correct seems to be: #5947198Edelstein
Such a common problem has such a complication solution.. why is Android so bad, I don't get itPlausive
This solution doesn't work well. When I minimize my app the video on youtube does stop properly, but I when I go back to the page and press play on the video again and then minimize the app the video continues to play.Eichman
doesn't work for me.is there any solution to stop the video?Flight
Need to call both webView.onPause() and webView.onResume() in the activity's / fragment's onPause() and onResume(). Otherwise, video is pause on first time but not on afterward.Sollows
Unfortunately that does not work for me (onPause / onResume).Laundryman
the method is not hiden anymore.Anschauung
Cooool. In 2011, you got a solution.Anschauung
Showing compile time error for kotlin i used like this Class.forName("android.webkit.WebView") .getMethod("onPause", *null as Array<Class<*>?>?) .invoke(wvBody, null as Array<Any?>?) The spread operator (*foo) may not be applied to an argument of nullable typeHither
E
74

Solution: 1 - After spending lot of time, I got the conclusion to pause the video which is playing with WebView <iframe> concept of HTML.

Just override the onPause() method on Activity or Fragment whereever you used WebView, and call it. It works for me.

@Override
public void onPause() {
    super.onPause();
    mWebView.onPause();
}

@Override
public void onResume() {
    super.onResume();
    mWebView.onResume();
}

Solution: 2 - If above solution doesn't work for you then you can force WebView to load a non existent html file.

mWebview.loadUrl("file:///android_asset/nonexistent.html");
Extrados answered 19/8, 2014 at 9:53 Comment(10)
WebView.onPause() was added in API 11, making this the more-correct answer.Dumanian
Didn't work for me on API 19, AudioBoom embedded player continues playing audio.Tremolo
@jarrodSmith try pauseTimers();. Maybe it's more javascript based.Downspout
Warning: This methods behaves like a static method although it's a instance method. ALL WebView instances will pause when you call mWebView.onPause on either.Downspout
Correction: comment above only valid for pauseTimers, not onPause. Tested on HTC One and One M8 w/Android 5.0.1, Chrome v43Downspout
On what page in Cordova's /platforms/android folder do you put this code? Under what lines?Gluttony
Need to call both webView.onPause() and webView.onResume() in the activity's / fragment's onPause() and onResume(). Otherwise, video is pause on first time but not on afterward.Sollows
Is it safe to combine dangels answer with this one to make sure I cover every cases?Bresnahan
This worked fine for me (at least with youtube embed) without the need for pauseTimers, FWIW. Also note that John Pang's comment has been implemented into it now.Melone
Although the developer documentation says onPause was added in API 11, it has actually been there since API 1 but undocumented. As evidence of this, the old Eclipse-based ADT, when set to an API target of 1, does not complain about it as it complains about other methods above the target API. Therefore, even if you target API 1, you can still use this answer by itself without needing any fallbacks.Dupuy
H
19

you also have to implement the onResume() method or second time it won't work

@Override
public void onResume()
{
    super.onResume();
    webView.onResume();
}

@Override
public void onPause()
{
    super.onPause();
    webView.onPause();
}
Halflength answered 3/12, 2014 at 12:12 Comment(2)
This shall be the better answer than above.Sollows
The other answer was updated to "adopt" this, for followers :)Melone
S
16

The above solution failed for me on Samsung Galaxy S with Android 2.3.3. But I made success trying the below workaround:

    webview.loadUrl("file:///android_asset/nonexistent.html");

I am forcing the webview to load a non existent html file. This seems to be forcing the webview to clean things up.

Sylvestersylvia answered 9/5, 2013 at 10:1 Comment(2)
did you find a solution for this problem? because i'm still facing itMagnify
This solution does not take into account the newer APIs at allKenny
R
7

Try this:

@Override
public void onPause() {
    super.onPause();
    myWebView.onPause();
    myWebView.pauseTimers();
}

@Override
public void onResume() {
    super.onResume();
    myWebView.resumeTimers();
    myWebView.onResume();
}


@Override
protected void onDestroy() {
    myWebView.destroy();
    myWebView = null;
    super.onDestroy();
}
Ruel answered 20/5, 2016 at 4:5 Comment(0)
D
6

And here's my personal favourite:

@Override
protected void onPause() {
    super.onPause();
    if (isFinishing()) {
        webView.loadUrl("about:blank");
    } else {
        webView.onPause();
        webView.pauseTimers();
    }
}

@Override
protected void onResume() {
    super.onResume();
    webView.resumeTimers();
    webView.onResume();
}

It pauses the webview if the view is only paused, but clears it when the activity is finished.

This requires at least Android 3.0 - API 11 (Honeycomb)

Discontinuance answered 25/9, 2015 at 16:24 Comment(0)
K
4
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // TODO Auto-generated method stub
    if(keyCode==event.KEYCODE_BACK)
    {
        mWebview.loadUrl("");
        mWebview.stopLoading();

        finish();

    }
    return super.onKeyDown(keyCode, event);
}

it works

Kaolinite answered 19/3, 2014 at 10:20 Comment(3)
What's with the "m" in "mWebView"?Gluttony
@Gluttony It is a naming convention outlined in the Android Code Style for Contributors documentation, it stands for 'member'. Though this code style is meant for the Android source code (not necessarily application code), many Android application developers have adopted it.Cotswold
@Steve, its also a nice trick to leverage the intellisense if you are using Android Studio (just like any other IDE like Visual Studio). When you are in your class and typed m, a popup list menu will appear listing all the variables you have in the class that starts with 'm'. You can use other letter if you want to.Bresnahan
A
4

The above approach did not work for me, one which worked for me is :

@Override
protected void onPause() {
    super.onPause();
    ((AudioManager)getSystemService(
            Context.AUDIO_SERVICE)).requestAudioFocus(
                    new OnAudioFocusChangeListener() {
                        @Override
                        public void onAudioFocusChange(int focusChange) {}
                    }, AudioManager.STREAM_MUSIC, 
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}
Alexisaley answered 22/5, 2018 at 4:52 Comment(3)
Works for me, but this method requestAudioFocus is deprecated since API level 26.Profuse
Please check developer.android.com/guide/topics/media-apps/audio-focus#java and developer.android.com/reference/android/media/…Alexisaley
this is the onPause() implementation but what about onResume() ?? how do you resume the music the webview might be playing etc? I tested this with a game that have background music and it pauses the music when minimized but then the game is silent when you resume the webviewDewan
E
3

Webview.loadUrl("about:blank");

it is also working

Empress answered 20/11, 2014 at 7:44 Comment(1)
...and works better than onPause() which on some devices seems to do nothing.Glyceric
K
3

After having encountered this problem it seems that onPause might not be doing anything... for me it was not stopping whatever was playing in background.

so my code now looks like

@Override
protected void onPause() {
    mWebView.onPause();
    super.onPause();
}

@Override
protected void onResume() {
    mWebView.onResume();
    super.onResume();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    mWebView.saveState(outState);
    super.onSaveInstanceState(outState);
}

@Override
protected void onDestroy() {
    mWebView.destroy();
    mWebView = null;        
    super.onDestroy();
}

Hope it helps anyone with the same problem as me

Kenny answered 20/4, 2015 at 12:31 Comment(0)
E
3

you can try this

webView.loadUrl("javascript:document.location=document.location");

if the page which is loading is one you can edit then you can write a javascript method which stop the audio and call when you want to stop like.

Javascript function

 function stopAudio(){
    audios=document.querySelectorAll('audio');
      for(i=0;i<audios.length;i++){
       audios[i].stop();
      }
    }

From Andorid Call this method

webView.loadUrl("javascript:stopAudio()");

if the page is not editable by you the you can inject the js code

   @Override
   public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);

      injectScriptFile(view, "js/script.js"); 

   }

How to Inject See Here in Detail

Eckman answered 12/8, 2016 at 15:41 Comment(0)
P
2

Based on @sommesh's answer:

override fun onPause() {
    super.onPause()

    val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

    if (Utils.hasOreoSDK26()) {
        val audioAttributes = AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build()
        val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
                .setAudioAttributes(audioAttributes)
                .setAcceptsDelayedFocusGain(true)
                .setWillPauseWhenDucked(true)
                .setOnAudioFocusChangeListener(
                        { focusChange -> Timber.i(">>> Focus change to : %d", focusChange) },
                        Handler())
                .build()
        audioManager.requestAudioFocus(audioFocusRequest)
    } else {
        audioManager.requestAudioFocus({ }, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
    }
}
Profuse answered 30/12, 2019 at 9:25 Comment(0)
S
1

This works for me.

@Override
protected void onPause() {
    super.onPause();
    if (wViewCampaign != null){
        wViewCampaign.stopLoading(); 
        wViewCampaign.loadUrl("");
        wViewCampaign.reload();
        wViewCampaign = null;
    }
}
Selfness answered 23/1, 2015 at 10:10 Comment(2)
This is not a good solution, since you will probably want to go back to the page again after a while and you expect the webview to be on the same state when you left it.Eichman
In my application this solution is working, because I haven't the case where I go back to the FragmentActivity.Selfness
H
1

You can do it by using the method onPause() of the of WebView when is executed the method onPause()of your Activity :

@override
public void onPause() {
        super.onPause();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
          webview.onPause();
        }
}
  • works for API >= 11 (Honeycomb)
Homosexuality answered 23/6, 2015 at 22:43 Comment(1)
what is the file name to update. Also will it work on latest API 19-26Pep
T
1

I tried all above answer , but most of them not work for me. so i just write my own solution which works fine in all type of media playing in webview

 String lastUrl = "";
 @Override
    public void onPause() {
        super.onPause();
        lastUrl =  webView.getUrl();
        webView.loadUrl("");
    }

    @Override
    protected void onResume() {
        super.onResume();
        webView.loadUrl(lastUrl);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        webView = null;
    }
Toshiatoshiko answered 12/3, 2019 at 6:33 Comment(0)
C
0

This is what finally worked after trying each and every code provided on this page. Uff!

@Override
protected void onPause() {
    super.onPause();
    if (mWebView != null) {
        mWebView.stopLoading();
        mWebView.reload();
    }
}

@Override
protected void onResume() {
    super.onResume();
}
Carve answered 19/11, 2015 at 11:55 Comment(0)
A
0

In my situation, the player keep running after the WebView is "onPause." So I check if the WebView is attached to the windows before playing video or music.

It is JavaScriptInterface method for checking WebView's "isAttachedToWindow()" return true/false.

(And I didn't forget to call onPause/onResume in Activity/Fragment.)

Anschauung answered 15/7, 2019 at 17:40 Comment(0)
C
-1

This code works perfect for me.

 @Override protected void onPause() {
    super.onPause();
    wv.onPause();
    wv.pauseTimers();
}
    @Override protected void onResume() {
    super.onResume();
    wv.resumeTimers();
    wv.onResume();
}
Comintern answered 5/1, 2016 at 8:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.