33

ホーム画面から、またはスマートフォンがスリープ状態のときにキーリスナーとして機能するAndroidバックグラウンドサービスを実行したいと思います。これは可能ですか?

オンラインの半関連の例から、次のサービスをまとめましたが、「onKeyDownはタイプServiceに対して未定義です」というエラーが表示されます。これは、ランチャーを書き直さないとできないということですか、それとも私が見逃している明らかな何かがありますか?

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のデフォルトは検索バーになりますが、これは実際には非常に特殊な用途に使用されます。私以外の誰かがこれを望んでいるとは本当に期待していません。たとえば、カメラのボタンを使って電話をスリープ解除するといいと思います。

4

4 に答える 4

18

私の知る限り、KeyEvents はユーザーがキーを押すためのインターフェイスであるため、Activity によってのみ処理できます。サービスはバックグラウンドで実行され、ユーザー入力に反応することを意図していません。これは、「onKeyDown is undefined for the type Service」というコンパイラ警告の理由でもあります。サービスまたはそのスーパークラスは KeyEvent.Callback インターフェイスを実装していません。回避策として、アクティビティを に登録して、AndroidManifest.xmlなどの特定のシステム通知に反応することができますandroid.intent.action.SCREEN_ON。電源ボタンを押して画面をオンにすると、アクティビティが開始され、何らかのサービスが初期化され、バックグラウンドに戻ります。それがあなたの意図するものなら。可能なアクションについては、インテント ドキュメントを参照してください。

それが役に立ったことを願っています...

于 2010-11-16T13:10:03.967 に答える
6

これには 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();
        }
    }
}
于 2018-03-10T19:45:03.593 に答える
0

サービスでハードウェア キーの押下を直接リッスンすることはできませんが、これらのキーの押下の効果をリッスンできる場合があります。たとえば、この回答では、メディアの音量の変化から音量キーの押下を推測する方法について説明しています。

于 2015-05-22T13:21:20.530 に答える