博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实战Android:通过BroadcastReceiver监听Home,电源Power,和音量变化Volume键
阅读量:4182 次
发布时间:2019-05-26

本文共 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

另外我也上传的完整的代码,可以直接下载运行,

 

你可能感兴趣的文章
一个js的接口测试器源代码
查看>>
ASP.NET 2.0中上传文件的简单实现
查看>>
IEEE802标准
查看>>
OSI模型简单描述
查看>>
如何将 Office 应用程序配置为在交互式用户帐户下运行
查看>>
TCP,IP详解,卷一:协议学习笔记之第三章IP:网际协议
查看>>
Linux命令之chmod详解
查看>>
Linux 安装 Elasticsearch运行及问题解决
查看>>
Linux入门看着一篇就文章就够了
查看>>
微服务发展历程
查看>>
业务基础环境搭建及api网关
查看>>
Dubbo启动检查、负载均衡、多协议支持
查看>>
Dubbo的异步调用
查看>>
Dubbo特性结果缓存、并发与连接控制
查看>>
dubbo服务分组、限流措施以及服务熔断降级
查看>>
Dubbo特性之本地存根、本地伪装和隐式参数传递
查看>>
Oracle恢复某个时间之前的数据
查看>>
Spring Cloud Alibaba 教程 | 安装 Nacos(一)
查看>>
Mysql生成连续的日期统计,没有结果的补充为0
查看>>
Spring Cloud Alibaba 教程 | 将服务注册到 Nacos(二)
查看>>