Android使用的webcview中带有音乐播放控件,在关闭或分享时处于界面不可见状态下,声音仍在播放的问题解决

来源:互联网 发布:淘宝达管家 编辑:程序博客网 时间:2024/06/06 05:09

Android使用的webview中带有音乐播放控件,在关闭或分享时处于界面不可见状态下,声音仍在播放的问题解决

一. 问题出现原因
        我们在做APP分享时,分享webview加载带有音乐播放控件的网页.当弹出分享界面,webview的网页处于后台状态或关闭该网页时,音乐声仍在播放.出现该类现象使我们所不能容忍,也会给用户一个不好的印象,网上有几种解决办法,但都有不尽如意的地方,今天,我们就来说说如何更好地解决它,我也会把网上一些热心大牛所给的一些解决方法,所存在弊端的地方也会给大家点出来.如果大家有遇到该类似情况的,那么你就可以解决它啦!

二.解决方法
     
  1.    @Override
  2.     protected void onPause() {
  3.         super.onPause();
  4.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  5.             mWebView.onPause();
  6.         }
  7. }
  8.  @Override
  9.     protected void onResume() {
  10.         super.onResume();
  11.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  12.             mWebView.onResume();
  13.         }
  14.         hideKeyBoard();
  15.     }
  16.     @Override
  17.     protected void onDestroy() {
  18.         super.onDestroy();
  19.         mWebView.resumeTimers();
  20.         mWebView.destroy();
  21.     }
      如果网页中的加载的是视频,我们在 onPause() ,onResume(),onDestroy(),是可以很好地暂停播放的,但如果是在网页中加载的是声音或者音乐的话,我们会发现这样不能控制它.通过查阅资料,我们发现这是Android的一个BUG,但因为Android的音乐流,音效流,电话声音是互不干涉的,且通过获取焦点来进行播放,多数情况下我们播放音乐都是使用 STREAM_MUSIC 音频流
  1.  @Override
  2.     protected void onPause() {
  3.         super.onPause();
  4.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  5.             mWebView.onPause();
  6.         }
  7. //让音乐控件失去焦点来禁止掉声音的播放
  8.         if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1) {
  9.         } else {
  10.             try {
  11.                 audioManager = (AudioManager) getSystemService(InterDetailActivity.this.AUDIO_SERVICE);
  12.                int i = 0;
  13.                 do {
  14.                     int result = audioManager.requestAudioFocus(listener
  15.                             , AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
  16.                     if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
  17.                         Log.d("AudioManager", "I get Audio right: ");
  18.                         break;
  19.                     }
  20.                     i++;
  21.                 } while (i < 10);
  22.             } catch (Exception ex) {
  23.                 ex.printStackTrace();
  24.             }
  25.         }
  26.     }

       对控制音乐播放控件的 焦点是否改变进行监听
 
  1. OnAudioFocusChangeListener listener = new OnAudioFocusChangeListener() {
  2.         @Override
  3.         public void onAudioFocusChange(int focusChange) {
  4.             Log.d("audioManager", "onAudioFocusChange: "
  5.                     + focusChange);
  6.         }
  7.     };
        这时候,你会发现,我们在正常打开该webview,音乐控件播放,点击分享弹出分享编辑页面,或者锁屏使网页界面不可见状态,音乐声音也跟着没有了,然后我们再返回到带有音乐控件的网页,但是问题来了,音乐控件的转动播放却没有声音,而我们要的是,在这个网页可见的时候要有音乐的,这是因为,之前做的播放控件失去焦点,禁止掉了声音,这时我们只需要在onResue()或onRestar()中,让该H5页面再重新刷新下,音乐就播放出来了
 
  1. @Override
  2.     protected void onRestart() {
  3.         super.onRestart();
  4.         mWebView.reload();
  5.     }
  6.  @Override
  7.     protected void onResume() {
  8.         super.onResume();
  9.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  10.             mWebView.onResume();
  11.          // mWebView.reload();
  12.         }
  13. }
        但上面也说了,这时在我们正常操作的时候,问题已经解决了,对,这只是正常操作下的,那怎样不正常操作呢?举个例子:如果你打开该H5网页后,快速又点击了分享按钮,这时候h5网页已经进入了后台,但你会发现,声音又出现了,这是因为,当你进入该网页,嵌在网页的视频或音乐播放控件是需要一定时间加载的,在还没加载出来的时候点击了分享使其处于不可见状态后,控件才加载好,音乐声也就出来了.那有如何解决这个问题呢?
         网上查了许多资料 ,也给出了一些解决办法:
   
  1. web.pauseTimers();    
  2. web.stopLoading();    
  3. web.loadData("<a></a>", "text/html", "utf-8");  
       但这些方法都不能达到满意的效果
  web.pauseTimers(); 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,如果你的APP中有两个地方或入口打开一个带音乐播放控件的网页,就会出现,在其中一个页面暂停后,会把另一个入口的网页也禁止掉.且音乐不能播放或者resumeTimers ()不能唤醒.如果该网页是类似多个页面可滑动翻页的话,则也不能滑动进行翻页了.这该效果也不是我们想要的,我们不希望我们应用中,不同地方或入口间会互相影响.
    web.stopLoading();这个方法根本没有作用;
    web.loadData("<a></a>", "text/html", "utf-8");  这个方法,已进入H5网页快速点击分享,在后台没有声音了,但当我们再回到网页界面,该网页空白了,没有了数据,更没有音乐的播放控件了,使用mWebView.reload();也不能刷新出来,我们需要mWebView.loadUrl(....)再重新加载一次这个h5网址.依然是刚才的例子,这是一个可滑动翻页的H5页面,如果分享前我们滑动到第三个页面,点击的分享,WebView.loadUrl()后会又回到第一页.这也不是我们想要的,我们要的是,滑动到那个页面,最后还回到那个页面.
        
        现在我们该真正的解决这个问题了,而常见的几种情况,我们也都说了,也解释了

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  5. initView();
  6. }
  7. @Override
  8. protected void onRestart() {
  9. super.onRestart();
  10. mWebView.reload();
  11. }
  12. @Override
  13. protected void onResume() {
  14. super.onResume();
  15. isPause = false;
  16. hideKeyBoard();
  17. }
  18. @Override
  19. protected void onPause() {
  20. super.onPause();
  21. isPause = true;
  22. requestAudioFocus();
  23. }
  24. @Override
  25. protected void onDestroy() {
  26. super.onDestroy();
  27. mWebView.destroy();
  28. mAudioManager.abandonAudioFocus(audioFocusChangeListener);
  29. }


  1. private void requestAudioFocus() {
  2. int result = mAudioManager.requestAudioFocus(audioFocusChangeListener,
  3. AudioManager.STREAM_MUSIC,
  4. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
  5. if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
  6. Log.e(TAG, "audio focus been granted");
  7. }
  8. }
  9. private OnAudioFocusChangeListener audioFocusChangeListener = new OnAudioFocusChangeListener() {
  10. @Override
  11. public void onAudioFocusChange(int focusChange) {
  12. Log.e(TAG, "focusChange: " + focusChange);
  13. if (isPause && focusChange == AudioManager.AUDIOFOCUS_LOSS) {
  14. requestAudioFocus();
  15. }
  16. }
  17. };

好了,这样我们就可以解决问题了,是不是很简单?重要的地方就是在焦点改变的监听时进行该操作
  1. if (isPause && focusChange == AudioManager.AUDIOFOCUS_LOSS) {
  2. requestAudioFocus();

这个问题到此就结束了,希望能有帮助!


1 0