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

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

    如果网页中的加载的是视频,我们在 onPause() ,onResume(),onDestroy(),是可以很好地暂停播放的,但如果是在网页中加载的是声音或者音乐的话,我们会发现这样不能控制它.通过查阅资料,我们发现这是Android的一个BUG,但因为Android的音乐流,音效流,电话声音是互不干涉的,且通过获取焦点来进行播放,多数情况下我们播放音乐都是使用 STREAM_MUSIC 音频流。

        @Override
        protected void onPause() {
            super.onPause();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                mWebView.onPause();
            }
            //让音乐控件失去焦点来禁止掉声音的播放
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1) {
            } else {
                try {
                    audioManager = (AudioManager) getSystemService(InterDetailActivity.this.AUDIO_SERVICE);
                   int i = 0;
                    do {
                        int result = audioManager.requestAudioFocus(listener
                                , AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                            Log.d("AudioManager", "I get Audio right: ");
                            break;
                        }
                        i++;
                    } while (i < 10);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

     对控制音乐播放控件的 焦点是否改变进行监听

        OnAudioFocusChangeListener listener = new OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {
                Log.d("audioManager", "onAudioFocusChange: "
                        + focusChange);
            }
        };

     这时候,你会发现,我们在正常打开该webview,音乐控件播放,点击分享弹出分享编辑页面,或者锁屏使网页界面不可见状态,音乐声音也跟着没有了,然后我们再返回到带有音乐控件的网页,但是问题来了,音乐控件的转动播放却没有声音,而我们要的是,在这个网页可见的时候要有音乐的,这是因为,之前做的播放控件失去焦点,禁止掉了声音,这时我们只需要在onResue()或onRestar()中,让该H5页面再重新刷新下,音乐就播放出来了

        @Override
        protected void onRestart() {
            super.onRestart();
            mWebView.reload();
        }
        @Override
        protected void onResume() {
            super.onResume();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
            {
                mWebView.onResume();
             // mWebView.reload();
            }
       }
    但上面也说了,这时在我们正常操作的时候,问题已经解决了,对,这只是正常操作下的,那怎样不正常操作呢?举个例子:如果你打开该H5网页后,快速又点击了分享按钮,这时候h5网页已经进入了后台,但你会发现,声音又出现了,这是因为,当你进入该网页,嵌在网页的视频或音乐播放控件是需要一定时间加载的,在还没加载出来的时候点击了分享使其处于不可见状态后,控件才加载好,音乐声也就出来了.那有如何解决这个问题呢?
         网上查了许多资料 ,也给出了一些解决办法:
    web.pauseTimers();    
    web.stopLoading();    
    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()后会又回到第一页.这也不是我们想要的,我们要的是,滑动到那个页面,最后还回到那个页面.
    现在我们该真正的解决这个问题了,而常见的几种情况,我们也都说了,也解释了
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        initView();
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        mWebView.reload();
    }
    @Override
    protected void onResume() {
        super.onResume();
        isPause = false;
        hideKeyBoard();
    }
    @Override
    protected void onPause() {
        super.onPause();
        isPause = true;
        requestAudioFocus();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mWebView.destroy();
        mAudioManager.abandonAudioFocus(audioFocusChangeListener);
    private void requestAudioFocus() {
    int result = mAudioManager.requestAudioFocus(audioFocusChangeListener,
    AudioManager.STREAM_MUSIC,
    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
      if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        Log.e(TAG, "audio focus been granted");
      }
    }
    private OnAudioFocusChangeListener audioFocusChangeListener = new OnAudioFocusChangeListener() {
    @Override
    public void onAudioFocusChange(int focusChange) {
    Log.e(TAG, "focusChange: " + focusChange);
      if (isPause && focusChange == AudioManager.AUDIOFOCUS_LOSS) {
         requestAudioFocus();
      }
     }
    };

    好了,这样我们就可以解决问题了,是不是很简单?重要的地方就是在焦点改变的监听时进行该操作

    if (isPause && focusChange == AudioManager.AUDIOFOCUS_LOSS) {
        requestAudioFocus();
    }

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

     
  • 相关阅读:
    查找大文件 & 索引节点(inode)爆满 解决办法
    技术领导力 —— 左耳听风 专栏读后感
    左耳朵耗子关于技术变现一文读后感
    html--前端jquery初识
    html--JavaScript之DOM (文档对象模型)
    html--前端JavaScript基本内容
    html--前端javascript初识
    html--前端css常用属性
    html--前端css样式初识
    html--前端基本标签内容讲解
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7886488.html
Copyright © 2011-2022 走看看