Android WebView not stopping after user presses back
Asked Answered
D

8

37

I am playing a YouTube video inside a WebView. I am able to play it, but when the person leaves the screen, I am not able to stop the audio from playing.

I tried various things inside onDestroy and onPause, or taking them out entirely, but they didn't seem to make a difference.

Would anyone know why the audio keeps playing and doesn't stop even after the app is turned off and the user opens other apps?

Here is my code for the whole class:

import com.flurry.android.FlurryAgent;

import utils.SendEmail;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebSettings.PluginState;
import android.widget.Button;

public class YoutubeActivity extends Activity
{
    WebView webview = null;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        webview = new WebView(this);

            setContentView(webview);

            webview.getSettings().setAppCacheEnabled(false);
            webview.getSettings().setJavaScriptEnabled(true);
            webview.setInitialScale(1);
            webview.getSettings().setPluginState(PluginState.ON);

            WebSettings webSettings = webview.getSettings();

            webSettings.setLoadsImagesAutomatically(true);
            webSettings.setLoadWithOverviewMode(true);
            webSettings.setBuiltInZoomControls(true);        
            webSettings.setUseWideViewPort(true);

            webview.setWebViewClient(new WebViewClient() {
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    view.loadUrl(url);              
                    return false;
                }
            });        


            webview.setWebChromeClient(new WebChromeClient(){});

            webSettings.setDomStorageEnabled(true);
            webSettings.setAppCacheEnabled(true);
                        webSettings.setAppCachePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/cache");            

            webSettings.setDatabaseEnabled(true);
            webSettings.setDatabasePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/databases");

            SharedPreferences prefs = 
                    PreferenceManager.getDefaultSharedPreferences( YoutubeActivity.this);
            String url_to_watch = prefs.getString( "url_to_watch" , null ); 


            webview.loadUrl(url_to_watch);
    }



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

       try
       {
           if ( webview != null )
           {
               webview.clearCache(true); 
               webview.getSettings().setAppCacheEnabled(false);
               webview.stopLoading();
               webview.destroy();           
               sendEmail ("in pause " , "");
               webview = new WebView(this);
           }

           this.finish();
       }
       catch ( Exception e )
       {

       }
    }


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

       try
       {
           if ( webview != null )
           {
               webview = new WebView(this); // To try to reset the webview - didn't work.
           }
       }
       catch ( Exception e )
       {

       }    
    }

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

       FlurryAgent.onEndSession(this);

       try
       {
           if ( webview != null )
           {
               webview.clearView();
               webview.getSettings().setAppCacheEnabled(false);
               webview.stopLoading();
               webview.destroy();

               sendEmail ("in stop " , "");
           }
       }
       catch ( Exception e )
       {

       }

       this.finish();
    }   

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

        try
        {
            webview.onResume();
        }
        catch ( Exception  e )
        {

        }
    }

    @Override
    protected void onRestart() 
    {
        super.onRestart();
    }    


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
    {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) 
        {
            webview.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }   

    // Subject , body
    public void sendEmail( String subject , String body )
    {
        String[] params = new String[] { "http://www.problemio.com/problems/send_email_mobile.php", subject, body };

        SendEmail task = new SendEmail();
        task.execute(params);               
    }  


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

    public void onBackPressed ( )
    {   
        final AlertDialog.Builder linkedin_builder = new AlertDialog.Builder(this);

             linkedin_builder.setMessage("" +
                    "Go back to the home screen?")
                .setCancelable(false)            
                .setNegativeButton("YES", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) 
                    {
                        if ( webview != null )
                        {
                            webview.destroy();
                        }

                        Intent myIntent = new Intent(YoutubeActivity.this, MainActivity.class);
                        YoutubeActivity.this.startActivity(myIntent);
                    }
                })              
                .setPositiveButton("NO", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) 
                    {
                        dialog.cancel();                  
                    }
                })
;
         AlertDialog alert = linkedin_builder.create();
         alert.show();      
    }


    @Override
    protected void onStart()
    {
        super.onStart();
        FlurryAgent.onStartSession(this, "4VYNFK3V6RCZ53CZ3J32");
    }    
}

Any thoughts on what might stop the audio from playing and what may be causing it? Thank you!

Drink answered 8/10, 2013 at 16:13 Comment(7)
Why do you create new one at onDestroy ? You should stop it at onDestroy method. And what is your way to "leave screen" ?Cousteau
@Cousteau I thought it I reset that object, the old things in it like the audio would go away :) It was just a try. What do you suggest I do? I don't see a .stop method in the apiDrink
I think, this link should be useful.. #5947198Cousteau
@Cousteau thank you, looking now :)Drink
if you find out the solution, let me know :)Cousteau
@Cousteau amazing, both of the solutions there worked! If you would like, you can post the link as the answer and I will accept :)Drink
I love stackoverflow :)Drink
C
60

try this, hope it helps:

@Override
public void onPause() {
    myWebView.onPause();
    myWebView.pauseTimers();//this may cause adMob to stop working
    super.onPause();
}

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


@Override
protected void onDestroy() {
    myWebView.destroy();
    myWebView = null;
    super.onDestroy();
}
Conferee answered 20/5, 2016 at 4:20 Comment(2)
Thank you, This is the best practice if you work with Webview.Finn
If you call webView.pauseTimers(), it may break adMob ads.Warrantor
P
30

You should call:

webView.loadUrl("about:blank");

It will destroy all audio/video as well as Javasript objects and stop all running functions on webview

Puparium answered 29/11, 2013 at 1:22 Comment(3)
That's good. Because I would like the webView to stop playing no only when activity is paused...Fina
It gonna be white but audio/video doesn't stop it became from background.Eolande
A caveat with this solution: started calls still continue and are not abortedInnoxious
T
11

Taken from https://mcmap.net/q/297978/-android-when-exiting-a-webview-the-audio-still-keeps-playing:

You should call through to the WebView's onPause() and onResume() from your Activity's onPause() and onResume(), respectively.

Pauses any extra processing associated with this WebView and its associated DOM, plugins, JavaScript etc. For example, if this WebView is taken offscreen, this could be called to reduce unnecessary CPU or network traffic. When this WebView is again "active", call onResume().

Threegaited answered 5/5, 2014 at 8:18 Comment(0)
D
10

Nothing worked for me in some or all devices. This is the exact solution I guess. Worked for me well.

How to stop youtube video playing in Android webview?

alternatively for API >= 11 you can use _webview.onPause(); on the activity's / fragment's onPause

public void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        _webview.onPause();
}
Disintegration answered 11/3, 2014 at 5:54 Comment(1)
,i am facing the same problem webview is not stopped when moving to the next screen.please see the my so question here #34607355 if you know the please help meSaccharoid
Y
6

In activity's onDestroy() do:

@Override
protected void onDestroy() {
    super.onDestroy();
    webView.destroy();
}
Yesima answered 29/6, 2015 at 6:5 Comment(0)
K
3

You can do it using the method onPause() of your Activity :

@override
public void onPause() {
    super.onPause();
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        webview.onPause();
    }
}

adding a validation for use in API >= 11 (Honeycomb)

Kainite answered 23/6, 2015 at 22:40 Comment(0)
W
0
  private void destroyWebView() {
        if (webView != null) {
            webView.clearHistory();
            webView.clearCache(false);
            webView.loadUrl("about:blank");
            webView.onPause();
            webView.removeAllViews();
            // webView.destroyDrawingCache();

            // NOTE: This pauses JavaScript execution for ALL WebViews,
            // do not use if you have other WebViews still alive.
            // If you create another WebView after calling this,
            // make sure to call mWebView.resumeTimers().
            // webView.pauseTimers();//adMob will fail to load if called
            webView.destroy();
            webView = null;
        }
    }
Warrantor answered 31/5, 2022 at 7:59 Comment(0)
O
0

The way I did it is by calling clearFocus for webview object. In my case I had fragments stacked up. So for the fragments not on top I called clearFocus for webview instances. It pauses the video for me.

Oersted answered 13/4, 2023 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.