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();
    }

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

     
  • 相关阅读:
    Ubuntu 16 安装redis客户端
    crontab 参数详解
    PHP模拟登录发送闪存
    Nginx配置端口访问的网站
    Linux 增加对外开放的端口
    Linux 实用指令之查看端口开启情况
    无敌的极路由
    不同的域名可以指向同一个项目
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error
    Redis 创建多个端口
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7886488.html
Copyright © 2011-2022 走看看