【问题标题】:onKeyDown in a service? (Global Hot Keys)onKeyDown 在服务中? (全局热键)
【发布时间】:2011-03-28 03:37:09
【问题描述】:

我基本上想要实现的是自定义全局热键,或者换句话说,“无论当前哪个程序在顶部,当我按下某些按钮时,事情都会发生”。
我认为需要一项服务。

我有一个快速而肮脏的测试,它只是告诉我按下了什么,如果它是活动窗口,它将起作用。

public boolean onKeyDown(int keyCode, KeyEvent event) {
    char pop;
    pop = (char)event.getUnicodeChar();
    Toast.makeText(this, Character.toString(pop) , Toast.LENGTH_SHORT).show();
    return super.onKeyDown(keyCode, event);
  }

但显然,如果我更改窗口或进入文本框,它就不起作用。如果我将它直接粘贴到服务(或 imputmethodservice)中并启动所述服务,则不会发生任何事情。 (可能需要一些权限?) 有什么建议我哪里出错了吗?还是捕捉按下哪个按钮的更好方法?

谢谢!

【问题讨论】:

标签: android onkeydown


【解决方案1】:

你不能这样做:)

【讨论】:

  • 即使在无障碍应用程序中?无法对服务中的按钮或软键按下做出反应?
  • @Romain Guy - 先生,如果按下主页时我想打开屏幕怎么办?三星note II 会怎么做?
  • @Romain Guy 为什么不先生?
  • @Romain 我的nexus 6p 上的牛轧糖如何在双击时听摄像头?
  • 嗯。我觉得'cannot'而不是can't,略带pass-ag的笑脸意思是“你可以,但你不应该。”。哈哈! :)
【解决方案2】:

这需要 Lollipop (v5.0/API 21) 或更高版本

我的目标是通过服务调整系统音量,因此这只会监听摇杆。不过,任何操作都可以在媒体上采取。

它将覆盖音量键操作,因此可能不需要全局使用它。

public class VolumeKeyController {

    private MediaSessionCompat mMediaSession;
    private final Context mContext;

    public VolumeKeyController(Context context) {
        mContext = context;
    }

    private void createMediaSession() {
        mMediaSession = new MediaSessionCompat(mContext, KeyUtil.log);

        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mMediaSession.setPlaybackState(new Builder()
                .setState(PlaybackStateCompat.STATE_PLAYING, 0, 0)
                .build());
        mMediaSession.setPlaybackToRemote(getVolumeProvider());
        mMediaSession.setActive(true);
    }

    private VolumeProviderCompat getVolumeProvider() {
        final AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

        int STREAM_TYPE = AudioManager.STREAM_MUSIC;
        int currentVolume = audio.getStreamVolume(STREAM_TYPE);
        int maxVolume = audio.getStreamMaxVolume(STREAM_TYPE);

        return new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) {
            @Override
            public void onAdjustVolume(int direction) {
                // Volume Up = AudioManager.ADJUST_LOWER, Volume Down = AudioManager.ADJUST_LOWER, Release = AudioManager.ADJUST_SAME
                // Replace with your action, if you don't want to adjust system volume
                if (direction == AudioManager.ADJUST_RAISE) {
                    audio.adjustStreamVolume(STREAM_TYPE,
                            AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                else if (direction == AudioManager.ADJUST_LOWER) {
                    audio.adjustStreamVolume(STREAM_TYPE,
                            AudioManager.ADJUST_LOWER, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                setCurrentVolume(audio.getStreamVolume(STREAM_TYPE));
            }
        };
    }

    // Call when control needed, add a call to constructor if needed immediately
    public void setActive(boolean active) {
        if (mMediaSession != null) {
            mMediaSession.setActive(active);
            return;
        }
        createMediaSession();
    }

    // Call from Service's onDestroy method
    public void destroy() {
        if (mMediaSession != null) {
            mMediaSession.release();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-28
    • 2023-03-03
    • 2021-05-17
    • 2016-12-03
    • 2010-11-19
    • 2016-02-28
    • 2010-12-12
    • 2019-12-07
    相关资源
    最近更新 更多