运行有问题或需要源码请点赞关注收藏后评论区留言~~~
一、检测软键盘
手机上的输入按键一般不另外处理,直接由系统按照默认情况操作,有时为了改善用户体验,需要让App拦截按键事件,并进行额外处理。监控按键事件之前,首先要指导每个按键的编码,这样才能根据不同的编码值进行相应的处理。监听器OnKeyListener只会检测控制键,不会检测文本键。
实际监控结果显示如下,每次按下控制键时,onKey方法都会收到两次重复编码的按键事件,这是因为该方法把每次按键都分成按下与松开两个动作,所以一次按键变成了两个按键动作,解决这个问题的办法就是只监控按下动作的按键事件,不监控松开动作的按键事件
代码如下
Java类
package com.example.event;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Looper;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.TextView;
@SuppressLint("DefaultLocale")
public class KeySoftActivity extends AppCompatActivity implements OnKeyListener {
private TextView tv_result; // 声明一个文本视图对象
private String desc = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_key_soft);
EditText et_soft = findViewById(R.id.et_soft);
et_soft.setOnKeyListener(this); // 设置编辑框的按键监听器
tv_result = findViewById(R.id.tv_result);
}
// 在发生按键动作时触发
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
desc = String.format("%s软按键编码是%d,动作是按下", desc, keyCode);
if (keyCode == KeyEvent.KEYCODE_ENTER) {
desc = String.format("%s,按键为回车键", desc);
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
desc = String.format("%s,按键为删除键", desc);
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
desc = String.format("%s,按键为搜索键", desc);
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
desc = String.format("%s,按键为返回键", desc);
// 延迟3秒后启动页面关闭任务
new Handler(Looper.myLooper()).postDelayed(() -> finish(), 3000);
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
desc = String.format("%s,按键为加大音量键", desc);
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
desc = String.format("%s,按键为减小音量键", desc);
}
desc = desc + "\n";
tv_result.setText(desc);
// 返回true表示处理完了不再输入该字符,返回false表示给你输入该字符吧
return true;
} else {
// 返回true表示处理完了不再输入该字符,返回false表示给你输入该字符吧
return false;
}
}
}
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/et_soft"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="@drawable/editext_selector"
android:hint="输入文字进行键盘检测"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:textColor="@color/black"
android:textSize="16sp" />
</LinearLayout>
二、检测物理按键
除了给控件注册按键监听器后,还可以在活动页面上检测物理按键,即重写Activity的onKeyDown方法,该方法与前面的onKey方法类似,同样拥有按键编码与按键事件KeyEvent两个参数,当然也有一点不同之处 此处不再赘述
效果如下
代码如下
Java类
package com.example.event;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Looper;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.widget.TextView;
import com.example.event.util.DateUtil;
@SuppressLint("DefaultLocale")
public class KeyHardActivity extends AppCompatActivity {
private TextView tv_result; // 声明一个文本视图对象
private String desc = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_key_hard);
tv_result = findViewById(R.id.tv_result);
initDesktopRecevier(); // 初始化桌面广播
}
// 在发生物理按键动作时触发
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
desc = String.format("%s物理按键的编码是%d", desc, keyCode);
if (keyCode == KeyEvent.KEYCODE_BACK) {
desc = String.format("%s,按键为返回键", desc);
// 延迟3秒后启动页面关闭任务
new Handler(Looper.myLooper()).postDelayed(() -> finish(), 3000);
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
desc = String.format("%s,按键为加大音量键", desc);
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
desc = String.format("%s,按键为减小音量键", desc);
}
desc = desc + "\n";
tv_result.setText(desc);
// 返回true表示不再响应系统动作,返回false表示继续响应系统动作
return true;
}
// 初始化桌面广播。用于监听按下主页键和任务键
private void initDesktopRecevier() {
// 创建一个返回桌面的广播接收器
mDesktopRecevier = new DesktopRecevier();
// 创建一个意图过滤器,只接收关闭系统对话框(即返回桌面)的广播
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mDesktopRecevier, intentFilter); // 注册广播接收器
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mDesktopRecevier); // 注销广播接收器
}
private DesktopRecevier mDesktopRecevier; // 声明一个返回桌面的广播接收器对象
// 定义一个返回到桌面的广播接收器
class DesktopRecevier extends BroadcastReceiver {
private String SYSTEM_DIALOG_REASON_KEY = "reason"; // 键名
private String SYSTEM_DIALOG_REASON_HOME = "homekey"; // 主页键
private String SYSTEM_DIALOG_REASON_TASK = "recentapps"; // 任务键
// 在收到返回桌面广播时触发
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (!TextUtils.isEmpty(reason)) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME)) { // 按下了主页键
desc = String.format("%s%s\t 按键为主页键\n", desc, DateUtil.getNowTime());
tv_result.setText(desc);
} else if (reason.equals(SYSTEM_DIALOG_REASON_TASK)) { // 按下了任务键
desc = String.format("%s%s\t 按键为任务键\n", desc, DateUtil.getNowTime());
tv_result.setText(desc);
}
}
}
}
}
}
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="@+id/tv_hard"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center"
android:text="请按设备上的物理键开始检测"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~