请教高手,最近在调一个FM的activity,现在的想法是在此activity中的任何画面下,如果按音量侧键KEYCODE_VOLUME_UP和KEYCODE_VOLUME_DOWN时,都可以使得FM的音量发生改变。
但问题是,只有在主界面中得到了如期的效果,要是我按了“MENU”键或是跳转到FM中的其他界面下,再按音量键的话,就会导致调节的是系统的铃声音量而不是FM的音量了。实在是苦恼,试过了不少方法,网上的一些资料说按键事件只会传递给最顶层的view,那这个问题怎么处理呢?
请赐教,最好能给出比较关键的示例代码,谢谢!

解决方案 »

  1.   

    记得Activity中,切换window会调用
    public void onWindowFocusChanged(boolean hasFocus);当主窗口非焦点时, 系统会调用onWindowFocusChanged(false)
    再回来时,调用onWindowFocusChanged(true)你在activity中override一个看一下:@Override
    public void onWindowFocusChanged(boolean hasFocus) {
    setVolumeControlStream(AudioManager.STREAM_MUSIC);
    super.onWindowFocusChanged(hasFocus);
    }
      

  2.   

    我用loadPrefInt("volume", 70);得到了FM的音量。
    其实只要能够在onCreateOptionsMenu(Menu)或是跳转到FM的其它界面时能够截获到dispatchKeyEvent的音量侧键KEYCODE_VOLUME_UP和KEYCODE_VOLUME_DOWN就有办法修改FM的volume了。
    问题是现在从log来看,无论是用onKeyDown还是dispatchKeyEvent根本就进不到这两个被重写的函数里。难道android的机制会存在这么大的缺失吗?应该不会吧
      

  3.   

    答#2楼的,我试了一下,编译之后运行会报错的,而且STREAM_MUSIC应该android是对music播放的音频流控制吧?能用在FM上?
      

  4.   

    编译报错是你没import相关的包, 我一直在源码开发,不太清楚AudioManager有没有开放出来。
    import android.media.AudioManager;
    默认的streamtype是这些:
        public static final int STREAM_VOICE_CALL = 0;
        /* The audio stream for system sounds */
        public static final int STREAM_SYSTEM = 1;
        /* The audio stream for the phone ring and message alerts */
        public static final int STREAM_RING = 2;
        /* The audio stream for music playback */
        public static final int STREAM_MUSIC = 3;
        /* The audio stream for alarms */
        public static final int STREAM_ALARM = 4;
        /* The audio stream for notifications */
        public static final int STREAM_NOTIFICATION = 5;
        /* @hide The audio stream for phone calls when connected on bluetooth */
        public static final int STREAM_BLUETOOTH_SCO = 6;
    一般第三方,自己写的音频播放程序,99.9% 都用的是STREAM_MUSIC
    keyVolumeUp/Down
    以及 home/menu等, 你重载不了的,windowsManager那边直接截获处理掉了,压根就不再往下分发了,不要再在这块浪费精力了, 这是系统一致性的考量,人家不想让你用户去绑架这几个按键,造成系统操作习惯及处理流程等的问题。
      

  5.   

    编译的问题解决了,但没弄明白的是为什么在主界面下可以截取到keyEvent事件,而一旦主界面没有被focus的时候就截取不到了呢?或者说,在什么地方可以捕获到按键事件呢?因为对windowsManager不是很熟悉,怕乱改那块的代码到时解决了这个问题的话,又会引起一堆bug呀,在应用层不能解决吗?
      

  6.   

    刚才没有截获按键。通常: 一个Activity被创建时,会创建一个Window给他,但Activity内,不止一个window的, 比如弹出音量控制面板是一个window, 弹出警告窗口也是一个,这些window是attach在哪个activity上的。当Activity自身的window焦点失去或再获取的时候,你可以通过上面的函数知道这个事件
    你只要退出这个Activity时,设置
    setVolumeControlStream(USE_DEFAULT_STREAM_TYPE)
    应该不会对系统造成任何影响
      

  7.   

    每次activity的main窗口发生focus切换时,均会进入到onWindowFocusChanged()函数中。当然,我可以在这里设一个全局标志位什么的,但是即使是这样,main窗口一旦lose focus之后,按键事件被windowsManager消化掉了,而不会继续向下传递,也就是说按了按键之后,我的FM应用程序根本就不知道有keyEvent事件发生。那又怎么去截获音量侧键的按键事件呢?貌似这样也不能解决问题啊
      

  8.   

    没人让你去截获啊按键该干什么还是干什么。音量键按键,到底是调节哪个音量,要看当前的streamtype的, 你试试在focus change的时候将streamtype改掉看看可不可以。 如果不可以,需要再想别的辙。截获按键就别想了。
      

  9.   

    搜索到的关于按键事件流程说明,你可以看看Android事件传递机制【按键事件】