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");
Sergey Litvinov
  • 7,408
  • 5
  • 46
  • 67
Droid
  • 1,091
  • 2
  • 9
  • 14
  • Can you post the code you're using? – Jordan May 10 '11 at 14:13
  • 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"); – Droid May 11 '11 at 11:46
  • Good practice to handle back press https://stackoverflow.com/a/37337884/2795035 I may help some one. – Shashi Shiva L Jul 26 '21 at 17:42

18 Answers18

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.

Community
  • 1
  • 1
Andrew Thompson
  • 2,396
  • 1
  • 21
  • 23
  • 2
    i was trying to put logic in "back key press " . but it didnt work. this one works – png Feb 25 '12 at 02:00
  • thank you !!! I was trying for last 8 hours and nothing works. But this is working like a charm !!! – dakshbhatt21 Sep 07 '13 at 14:19
  • 1
    It seems like the [WebView.onResume()](http://developer.android.com/reference/android/webkit/WebView.html#onResume()) and [WebView.onPause()](http://developer.android.com/reference/android/webkit/WebView.html#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()](http://developer.android.com/reference/android/support/v4/app/Fragment.html#setUserVisibleHint(boolean)). – grandouassou Feb 13 '15 at 16:06
  • 7
    Answer is not up to date. API has changed and webview.onPause() is now available. The correct seems to be: http://stackoverflow.com/questions/5946698/how-to-stop-youtube-video-playing-in-android-webview/25380464#25380464 – 0xPixelfrost Apr 08 '15 at 21:21
  • Such a common problem has such a complication solution.. why is Android so bad, I don't get it – SpaceMonkey Jul 27 '15 at 23:25
  • 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. – bashan Sep 08 '15 at 06:14
  • doesn't work for me.is there any solution to stop the video? – Rajesh Jan 05 '16 at 10:49
  • 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. – John Pang Aug 08 '16 at 01:25
  • Unfortunately that does not work for me (onPause / onResume). – Mackovich Jun 12 '19 at 09:24
  • the method is not hiden anymore. – hsu.tw Jul 15 '19 at 15:46
  • Cooool. In 2011, you got a solution. – hsu.tw Mar 30 '20 at 08:23
  • Showing compile time error for kotlin i used like this Class.forName("android.webkit.WebView") .getMethod("onPause", *null as Array?>?) .invoke(wvBody, null as Array?) The spread operator (*foo) may not be applied to an argument of nullable type – Gyan Swaroop Awasthi Feb 08 '23 at 11:14
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");
Vishesh Chandra
  • 6,951
  • 6
  • 35
  • 38
  • 1
    WebView.onPause() was added in API 11, making this the more-correct answer. – Sean Beach May 21 '15 at 22:38
  • Didn't work for me on API 19, AudioBoom embedded player continues playing audio. – sleep Aug 15 '15 at 13:16
  • 1
    @jarrodSmith try `pauseTimers();`. Maybe it's more javascript based. – Nilzor Aug 19 '15 at 09:27
  • **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. – Nilzor Aug 19 '15 at 11:00
  • Correction: comment above only valid for `pauseTimers`, not `onPause`. Tested on HTC One and One M8 w/Android 5.0.1, Chrome v43 – Nilzor Aug 19 '15 at 11:23
  • On what page in Cordova's /platforms/android folder do you put this code? Under what lines? – Steve May 01 '16 at 23:28
  • 1
    Works with youtube video in webview. Thanks! – DH28 May 31 '16 at 09:08
  • 1
    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. – John Pang Aug 08 '16 at 01:25
  • Is it safe to combine dangels answer with this one to make sure I cover every cases? – Neon Warge Aug 31 '16 at 03:22
  • 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. – rogerdpack Oct 22 '17 at 02:28
  • 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. – Silas S. Brown Apr 27 '18 at 15:22
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();
}
sommesh
  • 923
  • 9
  • 19
CLucera
  • 1,091
  • 11
  • 29
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.

dangel
  • 1,506
  • 15
  • 10
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();
}
Thiago
  • 12,778
  • 14
  • 93
  • 110
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)

Björn Kechel
  • 7,933
  • 3
  • 54
  • 57
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

  • What's with the "m" in "mWebView"? – Steve May 02 '16 at 04:11
  • 1
    @Steve It is a naming convention outlined in the [Android Code Style for Contributors](http://source.android.com/source/code-style.html#follow-field-naming-conventions) 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. – Bryan May 23 '16 at 18:17
  • 1
    @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. – Neon Warge Aug 31 '16 at 03:19
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);
}
sommesh
  • 923
  • 9
  • 19
  • Works for me, but this method `requestAudioFocus ` is deprecated since API level 26. – rayworks Dec 30 '19 at 04:28
  • 1
    Please check https://developer.android.com/guide/topics/media-apps/audio-focus#java and https://developer.android.com/reference/android/media/AudioFocusRequest.html – sommesh Dec 30 '19 at 04:42
  • 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 webview – Asiel Diaz Benitez Apr 04 '22 at 18:50
3

Webview.loadUrl("about:blank");

it is also working

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

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

Community
  • 1
  • 1
Azmat Karim Khan
  • 437
  • 5
  • 18
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)
    }
}
rayworks
  • 741
  • 9
  • 15
1

This works for me.

@Override
protected void onPause() {
    super.onPause();
    if (wViewCampaign != null){
        wViewCampaign.stopLoading(); 
        wViewCampaign.loadUrl("");
        wViewCampaign.reload();
        wViewCampaign = null;
    }
}
Community
  • 1
  • 1
Manuel Schmitzberger
  • 5,162
  • 3
  • 36
  • 45
  • 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. – bashan Sep 08 '15 at 06:16
  • In my application this solution is working, because I haven't the case where I go back to the FragmentActivity. – Manuel Schmitzberger Jan 13 '16 at 22:23
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)
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
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;
    }
Abhishek Garg
  • 3,092
  • 26
  • 30
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();
}
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.)

hsu.tw
  • 148
  • 2
  • 10
-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();
}