studio - android toolbar




是否可以創建一個偵聽硬件按鍵的Android服務? (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 = mContext.getSystemService(Context.AUDIO_SERVICE);

        int STREAM_TYPE = AudioManager.STREAM_MUSIC;
        int currentVolume = audio.getStreamVolume(STREAM_TYPE);
        int maxVolume = audio.getStreamMaxVolume(STREAM_TYPE);
        final int VOLUME_UP = 1;
        final int VOLUME_DOWN = -1;

        return new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) {
            @Override
            public void onAdjustVolume(int direction) {
                // Up = 1, Down = -1, Release = 0
                // Replace with your action, if you don't want to adjust system volume
                if (direction == VOLUME_UP) {
                    audio.adjustStreamVolume(STREAM_TYPE,
                            AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                else if (direction == VOLUME_DOWN) {
                    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();
        }
    }
}

我想運行一個Android後台服務,它將從主屏幕或手機處於睡眠狀態時充當keylistener。 這可能嗎?

從在線的半相關示例中,我將以下服務放在一起,但得到錯誤,“對於類型服務未定義onKeyDown”。 這是否意味著如果不重寫Launcher就無法完成,或者是否有一些我不知道的東西?

public class ServiceName extends Service {

    @Override
    public void onCreate() {
        //Stuff
    }

    public IBinder onBind(Intent intent) {
        //Stuff
        return null;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(event.getAction() == KeyEvent.ACTION_DOWN) {
        switch(keyCode) {
        case KeyEvent.KEYCODE_A:
            //Stuff
            return true;
        case KeyEvent.KEYCODE_B:
            //Stuff
            return true;

            //etc.
        }
        }

        return super.onKeyDown(keyCode, event);
    }
}

當你從主屏幕輸入時我意識到Android默認為搜索欄,但這只是一個非常特殊的用途。 除了我,我真的不希望有人想要這個。 我認為,例如,使用相機按鈕喚醒手機會很不錯。


據我所知,KeyEvents只能由Activities處理,因為它們是用戶按鍵的界面。 服務在後台運行,並非旨在對用戶輸入做出反應。 這也是您的編譯器警告“onKeyDown未定義類型服務”的原因。 服務或其任何超類都不實現KeyEvent.Callback接口。 作為一種解決方法,您可以在AndroidManifest.xml註冊一個Activity,以響應某些系統通知,例如android.intent.action.SCREEN_ON 。 當按下電源按鈕打開屏幕時,您的活動可以啟動,初始化某種服務並返回到後台。 如果這是你打算做的。 有關可能的操作,請參閱Intent文檔

希望有幫助......





keyevent