Stop Android MediaPlayer automatically launched by webpage within WebView

android, android-mediaplayer, android-webview, grooveshark

Solution

After struggling with a similar issue, I finally found a solution. It appears that if the AudioService does not have focus when you close the Webview, it is not paused. This causes severals issues (another player cannot start playing etc.)

The only solution that 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);

}

This will cause the current player to be paused/killed (not sure which) when going down and solve all of my issues / problems. Hope it could help you too...

Problem

one of the activities of my Android app contains a WebView that displays the GrooveShark player webpage. When the user taps on the play button of the webpage the activity automatically launches a default MediaPlayer that plays the track. Everything works fine, the problem arises when the user closes this activity and the MediaPlayer, although is not playing the track anymore, it remains alive... even when the app is closed, the MediaPlayer is still alive. The only way to kill it is by forcing the app to stop... I doesn't seem a big deal but in some devices when the user hangs up after a phone call, this "zombie" MediaPlayer all of a sudden starts to play the track even though the app was already previously destroyed... This is a summary of the code of my Activity: ``` @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_song); myWV = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWV.getSettings(); webSettings.setJavaScriptEnabled(true); myWV.setWebViewClient(new MyWebViewClient()); myWV.setWebChromeClient(new WebChromeClient()); myWV.loadUrl(url); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); myWV.onPause(); myWV.pauseTimers(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); myWV.onResume(); myWV.resumeTimers(); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); myWV.destroy(); } private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (Uri.parse(url).getHost().equals("grooveshark.com")) { return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); return true; } } ``` And this is what the log shows when the track is played for the first time: ``` 12-03 20:52:13.184: D/webkit(23440): euler: isUrlBlocked = false 12-03 20:52:13.794: V/MediaPlayer(23440): constructor 12-03 20:52:13.804: V/MediaPlayer(23440): setListener 12-03 20:52:13.814: D/HTML5Audio(23440): setDataSource() 12-03 20:52:13.894: V/MediaPlayer(23440): setVideoSurfaceTexture 12-03 20:52:13.894: V/MediaPlayer(23440): prepareAsync 12-03 20:52:16.144: V/MediaPlayer(23440): message received msg=3, ext1=12, ext2=0 12-03 20:52:16.154: V/MediaPlayer(23440): buffering 12 12-03 20:52:16.154: V/MediaPlayer(23440): callback application 12-03 20:52:16.154: V/MediaPlayer(23440): back from callback 12-03 20:52:16.154: V/MediaPlayer(23440): message received msg=5, ext1=0, ext2=0 12-03 20:52:16.154: V/MediaPlayer(23440): New video size 0 x 0 12-03 20:52:16.154: V/MediaPlayer(23440): callback application 12-03 20:52:16.154: V/MediaPlayer(23440): back from callback 12-03 20:52:16.154: V/MediaPlayer(23440): message received msg=1, ext1=0, ext2=0 12-03 20:52:16.154: V/MediaPlayer(23440): prepared 12-03 20:52:16.154: V/MediaPlayer(23440): callback application 12-03 20:52:16.154: V/MediaPlayer(23440): back from callback 12-03 20:52:16.184: E/MediaPlayer(23440): mOnVideoSizeChangedListener is null. Failed to send MEDIA_SET_VIDEO_SIZE message. 12-03 20:52:16.194: I/MediaPlayer(23440): Don't send intent. msg.arg1 = 0, msg.arg2 = 0 12-03 20:52:16.194: I/MediaPlayer(23440): mOnPreparedListener. Send MEDIA_PREPARED message. 12-03 20:52:16.194: D/HTML5Audio(23440): onPrepared() 12-03 20:52:16.214: V/MediaPlayer(23440): getDuration 12-03 20:52:16.224: V/MediaPlayer(23440): seekTo 0 12-03 20:52:16.224: V/MediaPlayer(23440): getDuration 12-03 20:52:16.224: V/MediaPlayer(23440): message received msg=4, ext1=0, ext2=0 12-03 20:52:16.224: D/HTML5Audio(23440): play() called. mState = 2 12-03 20:52:16.224: V/MediaPlayer(23440): Received seek complete 12-03 20:52:16.224: V/MediaPlayer(23440): All seeks complete - return to regularly scheduled program 12-03 20:52:16.224: V/MediaPlayer(23440): callback application 12-03 20:52:16.224: V/MediaPlayer(23440): back from callback 12-03 20:52:16.244: V/MediaPlayer(23440): start 12-03 20:52:16.264: D/HTML5Audio(23440): play() - start() 12-03 20:52:16.284: I/MediaPlayer(23440): mOnSeekCompleteListener. Send MEDIA_SEEK_COMPLETE message. 12-03 20:52:16.464: V/MediaPlayer(23440): isPlaying: 1 12-03 20:52:16.714: V/MediaPlayer(23440): isPlaying: 1 .... ``` And finally this is what the log keeps showing forever once the activity has finished ``` 12-03 20:52:36.164: V/MediaPlayer(23440): message received msg=3, ext1=100, ext2=0 12-03 20:52:36.164: V/MediaPlayer(23440): buffering 100 12-03 20:52:36.164: V/MediaPlayer(23440): callback application 12-03 20:52:36.164: V/MediaPlayer(23440): back from callback 12-03 20:52:36.244: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:36.494: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:36.744: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:36.994: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:37.164: V/MediaPlayer(23440): message received msg=3, ext1=100, ext2=0 12-03 20:52:37.164: V/MediaPlayer(23440): buffering 100 12-03 20:52:37.164: V/MediaPlayer(23440): callback application 12-03 20:52:37.164: V/MediaPlayer(23440): back from callback 12-03 20:52:37.244: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:37.504: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:37.754: V/MediaPlayer(23440): isPlaying: 0 12-03 20:52:38.004: V/MediaPlayer(23440): isPlaying: 0 .... ``` I need to find a way to retrieve that "zombie" MediaPlayer and stop it... Many thanks

Original source