ハードウェアキープレスを聴くAndroidサービスを作成することは可能ですか?
質問
ホーム画面からキーリストナーとして機能するAndroidバックグラウンドサービスを実行したいのですが、電話が眠っているときです。これは可能ですか?
オンラインで半関連の例から、次のサービスをまとめましたが、「OnKeyDownはタイプサービスのために定義されていない」エラーを取得します。これは、ランチャーを書き直さなければそれができないことを意味しますか、それとも私が欠けている明らかな何かがありますか?
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は、キーを押すユーザーへのインターフェイスであるため、アクティビティによってのみ処理できます。サービスはバックグラウンドで実行され、ユーザー入力で反応することを意図していません。これが、「OnKeyDownがタイプサービスのために定義されていない」とコンパイラに警告する理由でもあります。サービスまたはそのいずれかのスーパークラスは、KeyEvent.Callbackインターフェイスを実装していません。回避策として、アクティビティを登録できます AndroidManifest.xml
次のような特定のシステム通知で反応する android.intent.action.SCREEN_ON
. 。電源ボタンを押して画面をオンにすると、アクティビティを開始し、何らかのサービスを初期化して背景に戻ります。それがあなたがやろうとしていることなら。見る 意図ドキュメント 可能なアクションのために。
それが助けてくれることを願っています...
他のヒント
これには、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();
}
}
}
ハードウェアキープレスをサービスで直接聞くことはできませんが、これらのキープレスの効果を聞くことができます。例えば、 この答え メディアボリュームの変更からボリュームキープレスを推測する方法について説明します。