安卓socket实例(六)实现KEY操作,即热键操作

上一篇: 安卓socket实例(五)安卓端界面设计优化,实现服务设置和动态返回

本更内容:

实现KEY操作,即热键操作,本更以实现PC端幻灯片控制以及常用快捷键为例。

虚拟机不方便展示功能,这里建议使用真机调试,下图为虚拟机调试

安卓Socket6.gif

服务端更新

增加了key操作,即解析来自安卓端发出的key命令并执行功能

image.png

新增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提交服务端

image.png

新增布局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操作返回

image.png

        else if(status.equalsIgnoreCase("KEY")){
            msgType=SERVER_MSG_KEY;
        }
复制代码

image.png

更新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;
复制代码

image.png

增添相应的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操作");
                }
复制代码

image.png

至此实现key热键操作。

有用有收获 ==> 点赞点赞!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享