上一篇: 安卓socket实例(五)安卓端界面设计优化,实现服务设置和动态返回
本更内容:
实现KEY操作,即热键操作,本更以实现PC端幻灯片控制以及常用快捷键为例。
虚拟机不方便展示功能,这里建议使用真机调试,下图为虚拟机调试
服务端更新
增加了key操作,即解析来自安卓端发出的key命令并执行功能
新增KEY.java
实现pc端按下指定按键的方法类
package lrz.data;
import lrz.base.BaseOperator;
import lrz.tool.VisualKeyMap;
import java.awt.*;
import java.util.ArrayList;
public class KEY extends BaseOperator {
private Robot robot;
@Override
public ArrayList<String> exe(String cmdBody) throws Exception {
ArrayList<String> ackMsg = new ArrayList<String>();
robot=new Robot();
int splitIdx = cmdBody.indexOf(",");
if (splitIdx < 1) {
int splitIdx2 = cmdBody.indexOf("+");
if(splitIdx2<1){
singleKeyPress(cmdBody);
}else{
simpleComboKeyPress(cmdBody);//组合键
}
}else{
String keyPressStr=cmdBody.substring(0, splitIdx);
String keyReleaseStr=cmdBody.substring(splitIdx+1);
comboKeyPress(keyPressStr,keyReleaseStr);
}
ackMsg.add("成功运行热键命令 key:"+cmdBody);
return ackMsg;
}
private void simpleComboKeyPress(String keyPressStr){
String[] keyPressArray = keyPressStr.split("\\+");
//split里的字符符合正则表达式规则, "+”是正则表达式的关键词,不能直接用,需要转义,而\本身是转义,所以需要\\来表示
for(int i=0;i<keyPressArray.length;i++){
int keycode = VisualKeyMap.getVisualKey(keyPressArray[i]);
robot.keyPress(keycode);
}
for(int i=keyPressArray.length-1;i>=0;i--){//反序释放按键
int keycode = VisualKeyMap.getVisualKey(keyPressArray[i]);
robot.keyRelease(keycode);
}
}
private void comboKeyPress(String keyPressStr, String keyReleaseStr) {
// TODO Auto-generated method stub
String[] keyPressArray = keyPressStr.split("\\+");
String[] keyReleaseArray = keyReleaseStr.split("\\+");
for(int i=0;i<keyPressArray.length;i++){
int keycode = VisualKeyMap.getVisualKey(keyPressArray[i]);
robot.keyPress(keycode);
}
for(int i=0;i<keyReleaseArray.length;i++){
int keycode = VisualKeyMap.getVisualKey(keyReleaseArray[i]);
robot.keyRelease(keycode);
}
}
private void singleKeyPress(String cmdBody) {
// TODO Auto-generated method stub
int keycode = VisualKeyMap.getVisualKey(cmdBody);
robot.keyPress(keycode);
robot.keyRelease(keycode);
}
}
复制代码
新增VisualKeyMap.java
存放我们要使用到的快捷键,在这里设立在使用时直接调用
package lrz.tool;
import java.awt.event.KeyEvent;
import java.util.HashMap;
public class VisualKeyMap {
private static HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
private static final VisualKeyMap VISUAL_KEY_MAP = new VisualKeyMap();
private VisualKeyMap() {
hashMap.put("VK_0", KeyEvent.VK_0);//大写的Key,以方便录入,客户端发送大小写不区分
hashMap.put("VK_TAB", KeyEvent.VK_TAB);
hashMap.put("VK_ALT", KeyEvent.VK_ALT);
hashMap.put("VK_ESCAPE", KeyEvent.VK_ESCAPE);
hashMap.put("VK_LEFT", KeyEvent.VK_LEFT);
hashMap.put("VK_RIGHT", KeyEvent.VK_RIGHT);
hashMap.put("VK_F5", KeyEvent.VK_F5);
hashMap.put("VK_F4", KeyEvent.VK_F4);
hashMap.put("LEFT", KeyEvent.BUTTON1_MASK);
hashMap.put("RIGHT", KeyEvent.BUTTON3_MASK);
hashMap.put("WIN", KeyEvent.VK_WINDOWS);
hashMap.put("VK_D", KeyEvent.VK_D);
hashMap.put("VK_CTRL", KeyEvent.VK_CONTROL);
hashMap.put("VK_V", KeyEvent.VK_V);
// 此处省略需要增加的映射操作
}
public static int getVisualKey(String key) {
//调用时只需VisualKeyMap.getVisualKey(String key)即可
return hashMap.get(key.toUpperCase());//把key转为大写
}
}
复制代码
Operator.java
新增key命令解析后的操作调用
if (cmdHead.equals("key")) {
msgBackList = new KEY().exe(cmdBody); // 待实现的打开文件命令
msgBackList.add(0,"key");//增加正常执行返回的代码"ok"
return msgBackList;
}
复制代码
安卓端更新
增添热键操作、幻灯片控制面板,触发事件时生成key操作命令,通过SocketClient提交服务端
新增布局dialog_view_opt_do.xml
热键操作面板布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_alt_tab"
android:text="ALT+TAB 切换"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_f5"
android:text="F5 刷新"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_win_d"
android:text="WIN+D 显示/隐藏桌面" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_ctrl_f4"
android:text="Ctrl+F4 关闭"/>
</LinearLayout>
复制代码
新增布局dialog_view_opt_show.xml
幻灯片控制面板布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_f5"
android:text="放映"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_right"
android:text="下一张"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_left"
android:text="上一张"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/vk_esc"
android:text="退出播放"/>
</LinearLayout>
复制代码
更新opt_menu.xml
增加热键面板和幻灯片控制面板的选择
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/to_do"
android:title="热键操作"/>
<item
android:id="@+id/to_show"
android:title="幻灯片控制"/>
<item
android:id="@+id/to_set"
android:title="设置"/>
</menu>
复制代码
更新SocketClient.java
新增对key命令返回的识别
public static int SERVER_MSG_KEY=4;//表示KEY操作返回
else if(status.equalsIgnoreCase("KEY")){
msgType=SERVER_MSG_KEY;
}
复制代码
更新MainActivity.java
增加功能选择中的热键、幻灯片控制选项
case R.id.to_do:
showDialog_opt_do(MainActivity.this);
break;
case R.id.to_show:
show_Dialog_opt_show(MainActivity.this);
break;
复制代码
增添相应的showDialog_opt_do,showDialog_opt_show方法,实现相应面板弹出
public void showDialog_opt_do(final Context context){
AlertDialog.Builder bl = new AlertDialog.Builder(context);
bl.setTitle("控制面板");
View v = LayoutInflater.from(context).inflate(R.layout.dialog_view_opt_do, null, false);
final Button bt1=v.findViewById(R.id.vk_alt_tab);
final Button bt2=v.findViewById(R.id.vk_f5);
final Button bt3=v.findViewById(R.id.vk_win_d);
final Button bt4=v.findViewById(R.id.vk_ctrl_f4);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_alt+vk_tab,vk_tab+vk_alt");
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_f5");
}
});
bt3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:win+vk_d,vk_d+win");
}
});
bt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_ctrl+vk_f4,vk_f4+vk_ctrl");
}
});
bl.setView(v);
bl.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String s = "快捷键模式已关闭";
Toast.makeText(context,s,Toast.LENGTH_SHORT).show();
}
});
bl.create().show();
}
public void show_Dialog_opt_show(final Context context){
AlertDialog.Builder bl = new AlertDialog.Builder(context);
bl.setTitle("幻灯片控制");
View v = LayoutInflater.from(context).inflate(R.layout.dialog_view_opt_show, null, false);
final Button bt1=v.findViewById(R.id.vk_f5);
final Button bt2=v.findViewById(R.id.vk_right);
final Button bt3=v.findViewById(R.id.vk_left);
final Button bt4=v.findViewById(R.id.vk_esc);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_f5,vk_f5");
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_right,vk_right");
}
});
bt3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_left,vk_left");
}
});
bt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
socketClient=new SocketClient(ip,Integer.parseInt(port),handler);
socketClient.work("key:vk_escape,vk_escape");
}
});
bl.setView(v);
bl.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String s = "幻灯片控制模式已关闭";
Toast.makeText(context,s,Toast.LENGTH_SHORT).show();
}
});
bl.create().show();
}
复制代码
增加handler中key命令返回的监听
else if(fp==SocketClient.SERVER_MSG_KEY){
show_msg.setText("成功执行KEY操作");
}
复制代码
至此实现key热键操作。
有用有收获 ==> 点赞点赞!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END