本文共 15143 字,大约阅读时间需要 50 分钟。
上一个例子是采用AccessibilityService来实现按键的监听。这次我们采用BroadcastReceiver来完成按键的监听。
缺点:我尝试了一下,暂时还不知道如何停止按 键的默认行为,比如我确实监听到了电源按键,但却没法阻止此刻屏幕变黑的行为。先在这记下。以后找到解决办法再补充。
注意点:
1。监听Home键的相关字符串。
注意下边的注释,这几个字符串是Android系统已经内置好了的,必须是这样,比如你写成home_key,就不会反应。
final String SYSTEM_DIALOG_REASON_KEY = "reason";//按下Home键final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; // 系统内置字符串,表示home键 == 长按Home键final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; // 系统内置字符串,停止键
2。监听Volume键的字符串。
volume键的IntentFilter和Home,Power键不一样,没有相关ACTION,我只找到了这个,确实能监听到音量按键,但假设已经达到最大音量或最小音量,再往极限调,音量不会变化,就监听不到了。
mIntentFilter = new IntentFilter();mIntentFilter.addAction("android.media.VOLUME_CHANGED_ACTION");
好了,下面先看监听输出,我的手机大致如此,
源码如下,
AndroidManifest.xml
MainActivity.java
package com.spacesoftwares.spacecapture;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import com.spacesoftwares.spacecapture.service.WhiteService;public class MainActivity extends AppCompatActivity { private Button mBtnWhite, mBtnStopWhite, mBtnExit; private final static String TAG = MainActivity.class.getSimpleName(); private Intent whiteIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnWhite = findViewById(R.id.btn_white); mBtnStopWhite = findViewById(R.id.btn_stop_white); mBtnExit = findViewById(R.id.btn_exit); setListener(); } @Override protected void onDestroy() { super.onDestroy(); } class ExitReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { MainActivity.this.finish(); } } private void setListener(){ OnClick onClick = new OnClick(); mBtnWhite.setOnClickListener(onClick); mBtnStopWhite.setOnClickListener(onClick); mBtnExit.setOnClickListener(onClick); } private class OnClick implements View.OnClickListener{ @Override public void onClick(View view) { int viewId = view.getId(); switch(viewId){ case R.id.btn_white: Log.i(TAG, "MAIN: btn_white"); if(null == whiteIntent) whiteIntent = new Intent(MainActivity.this, WhiteService.class); startService(whiteIntent); break; case R.id.btn_stop_white: Log.i(TAG, "MAIN: btn_stop_white"); if(null != whiteIntent) stopService(whiteIntent); break; case R.id.btn_exit: Log.i(TAG, "MAIN: btn_exit"); if(null != whiteIntent) stopService(whiteIntent); finish(); break; } } }}
WhiteService.java
package com.spacesoftwares.spacecapture.service;import android.app.Notification;import android.app.NotificationChannel;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Context;import android.content.Intent;import android.graphics.Color;import android.os.Build;import android.os.IBinder;import android.provider.Settings;import android.support.annotation.Nullable;import android.support.v4.app.NotificationCompat;import android.util.Log;import com.spacesoftwares.spacecapture.MainActivity;import com.spacesoftwares.spacecapture.R;import com.spacesoftwares.spacecapture.key.HomeKeyObserver;import com.spacesoftwares.spacecapture.key.PowerKeyObserver;import com.spacesoftwares.spacecapture.key.VolumeKeyObserver;import java.io.IOException;import java.nio.channels.Channel;public class WhiteService extends Service { static public boolean isPowerKeyPressed = false; private final static String TAG = WhiteService.class.getSimpleName(); private final static int FOREGROUND_ID = 1000; private Notification mNotification; /** * 参考: * 1 https://blog.csdn.net/q445697127/article/details/8432513 * 2 https://blog.csdn.net/lfdfhl/article/details/9903693 */ private HomeKeyObserver mHomeKeyObserver; private PowerKeyObserver mPowerKeyObserver; private VolumeKeyObserver mVolumeKeyObserver; private void init() { mHomeKeyObserver = new HomeKeyObserver(this); mHomeKeyObserver.setHomeKeyListener(new HomeKeyObserver.OnHomeKeyListener() { @Override public void onHomeKeyPressed() { Log.i(TAG,"----> 按下Home键"); System.out.println("----> 按下Home键"); } @Override public void onHomeKeyLongPressed() { Log.i(TAG,"----> 长按Home键"); System.out.println("----> 长按Home键"); } }); mHomeKeyObserver.startListen(); // mPowerKeyObserver = new PowerKeyObserver(this); mPowerKeyObserver.setPowerKeyListener(new PowerKeyObserver.OnPowerKeyListener() { @Override public void onPowerKeyPressed() { Log.i(TAG,"----> 按下电源键"); System.out.println("----> 按下电源键"); isPowerKeyPressed = true; } }); mPowerKeyObserver.startListen(); // mVolumeKeyObserver = new VolumeKeyObserver(this); mVolumeKeyObserver.setVolumeKeyListener(new VolumeKeyObserver.OnVolumeKeyListener() { @Override public void onVolumeKeyPressed() { Log.i(TAG,"----> 按下电源键"); System.out.println("----> 按下电源键"); } }); mVolumeKeyObserver.startListen(); } public WhiteService(){} @Nullable @Override public IBinder onBind(Intent intent) { //return null; throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { Log.i(TAG, "WhiteService->onCreate"); super.onCreate(); init(); } @Override public void onDestroy() { Log.i(TAG, "WhiteService->onDestroy"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) //if(null !=mNotification) { stopForeground(Service.STOP_FOREGROUND_REMOVE); } mHomeKeyObserver.stopListen(); mPowerKeyObserver.stopListen(); mVolumeKeyObserver.stopListen(); super.onDestroy(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(null != mNotification){ Log.i(TAG, "WhiteService->onStartCommand->Notification exists"); return super.onStartCommand(intent, flags, startId); } Log.i(TAG, "WhiteService->onStartCommand->Create Notification"); //NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); //NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); String NOTIFICATION_CHANNEL_ID = "my_channel_id_01"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH); // Configure the notification channel. notificationChannel.setDescription("Channel description"); notificationChannel.enableLights(true); notificationChannel.setLightColor(Color.RED); notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000}); notificationChannel.enableVibration(true); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(notificationChannel); } NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setContentTitle("Foreground"); builder.setContentText("Text shown on notification bar"); builder.setContentInfo("Content Info"); builder.setWhen(System.currentTimeMillis()); Intent activityIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pendingIntent); mNotification = builder.build(); startForeground(FOREGROUND_ID, mNotification); return super.onStartCommand(intent, flags, startId); }}
HomeKeyOberver.java
package com.spacesoftwares.spacecapture.key;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import java.util.Objects;public class HomeKeyObserver { private Context mContext; private IntentFilter mIntentFilter; private OnHomeKeyListener mOnHomeKeyListener; private HomeKeyBroadcastReceiver mHomeKeyBroadcastReceiver; public HomeKeyObserver(Context context) { this.mContext = context; } //注册广播接收者 public void startListen(){ mIntentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); mHomeKeyBroadcastReceiver=new HomeKeyBroadcastReceiver(); mContext.registerReceiver(mHomeKeyBroadcastReceiver, mIntentFilter); System.out.println("HomeKey----> 开始监听"); } //取消广播接收者 public void stopListen(){ if (mHomeKeyBroadcastReceiver!=null) { mContext.unregisterReceiver(mHomeKeyBroadcastReceiver); System.out.println("HomeKey----> 停止监听"); } } // 对外暴露接口 public void setHomeKeyListener(OnHomeKeyListener homeKeyListener) { mOnHomeKeyListener = homeKeyListener; } // 回调接口 public interface OnHomeKeyListener { void onHomeKeyPressed(); void onHomeKeyLongPressed(); } //广播接收者 class HomeKeyBroadcastReceiver extends BroadcastReceiver{ final String SYSTEM_DIALOG_REASON_KEY = "reason"; //按下Home键 final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; // 系统内置字符串,表示home键 //长按Home键 final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; // 系统内置字符串,停止键 @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Objects.equals(action, Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); if (reason != null && mOnHomeKeyListener != null) { if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) { mOnHomeKeyListener.onHomeKeyPressed(); } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { mOnHomeKeyListener.onHomeKeyLongPressed(); } } } } }}
PowerKeyObserver.java
package com.spacesoftwares.spacecapture.key;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.util.Log;import java.util.Objects;public class PowerKeyObserver { private String TAG_POWER = "PowerKey"; private Context mContext; private IntentFilter mIntentFilter; private OnPowerKeyListener mOnPowerKeyListener; private PowerKeyBroadcastReceiver mPowerKeyBroadcastReceiver; public PowerKeyObserver(Context context) { this.mContext = context; } //注册广播接收者 public void startListen(){ mIntentFilter=new IntentFilter(Intent.ACTION_SCREEN_OFF); mPowerKeyBroadcastReceiver=new PowerKeyBroadcastReceiver(); mContext.registerReceiver(mPowerKeyBroadcastReceiver, mIntentFilter); Log.i(TAG_POWER, "PowerKey----> 开始监听"); System.out.println("PowerKey----> 开始监听"); } //取消广播接收者 public void stopListen(){ if (mPowerKeyBroadcastReceiver!=null) { mContext.unregisterReceiver(mPowerKeyBroadcastReceiver); Log.i(TAG_POWER, "PowerKey----> 停止监听"); System.out.println("PowerKey----> 停止监听"); } } // 对外暴露接口 public void setPowerKeyListener(OnPowerKeyListener powerKeyListener) { mOnPowerKeyListener = powerKeyListener; } // 回调接口 public interface OnPowerKeyListener { void onPowerKeyPressed(); } //广播接收者 class PowerKeyBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Objects.equals(action, Intent.ACTION_SCREEN_OFF)) { mOnPowerKeyListener.onPowerKeyPressed(); //abortBroadcast(); } } }}
VolumeKeyObserver.java
package com.spacesoftwares.spacecapture.key;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.util.Log;import java.util.Objects;public class VolumeKeyObserver { private String TAG_VOLUME = "VOLUME"; private Context mContext; private IntentFilter mIntentFilter; private VolumeKeyObserver.OnVolumeKeyListener mOnVolumeKeyListener; private VolumeKeyObserver.VolumeKeyBroadcastReceiver mVolumeKeyBroadcastReceiver; public VolumeKeyObserver(Context context) { this.mContext = context; } //注册广播接收者 public void startListen(){ //mIntentFilter = new IntentFilter(Intent.ACTION_VOICE_COMMAND); mIntentFilter = new IntentFilter(); mIntentFilter.addAction("android.media.VOLUME_CHANGED_ACTION"); mVolumeKeyBroadcastReceiver=new VolumeKeyObserver.VolumeKeyBroadcastReceiver(); mContext.registerReceiver(mVolumeKeyBroadcastReceiver, mIntentFilter); System.out.println("VolumeKey----> 开始监听"); } //取消广播接收者 public void stopListen(){ if (mVolumeKeyBroadcastReceiver!=null) { mContext.unregisterReceiver(mVolumeKeyBroadcastReceiver); System.out.println("VolumeKey----> 停止监听"); } } // 对外暴露接口 public void setVolumeKeyListener(VolumeKeyObserver.OnVolumeKeyListener VolumeKeyListener) { mOnVolumeKeyListener = VolumeKeyListener; } // 回调接口 public interface OnVolumeKeyListener { void onVolumeKeyPressed(); } //广播接收者 class VolumeKeyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Objects.equals(action, "android.media.VOLUME_CHANGED_ACTION")) { Log.i(TAG_VOLUME, "VolumeKey----> 监听到了音量调节"); System.out.println("VolumeKey----> 监听到了音量调节"); } } }}
activity_main.xml
另外我也上传的完整的代码,可以直接下载运行,