安卓&socket学习分享(四)

上一篇:安卓&socket学习分享(三)

 

 

目录

idea端更新

安卓端更新


 

 

本篇完成内容:

1)key热键操作

2)安卓端大量优化与升级

3)细节bug的修复与改进

 

 

 

idea端更新内容

安卓&socket学习分享(四)_第1张图片

Operator.java增加key命令操作

if (cmdHead.equals("key")) {
            msgBackList = new KEY().exe(cmdBody); // 待实现的打开文件命令
            return msgBackList;
        }

安卓&socket学习分享(四)_第2张图片

 增加VisualKeyMao.java

package lrz.tool;

import java.awt.event.KeyEvent;
import java.util.HashMap;

public class VisualKeyMap {
    private static HashMap hashMap = new HashMap();
    private static final VisualKeyMap VISUAL_KEY_MAP = new VisualKeyMap();

    private VisualKeyMap() {// 在私有的构造函数中对hashVisualKeyMap赋值,完成映射对象的赋值,该构造函数只在
        // private static final VisualKeyMap VISUAL_KEY_MAP=new  VisualKeyMap()静态变量中new出一次
        // 无论调用多少次VisualKeyMap.getInstance()方法只返回VISUAL_KEY_MAP对象,而不会再调用构造函数new出对象
        // 若要取客户端发送的"vk_space"对应的java.awt.event.KeyEvent.VK_SPACE值,则可通过VisualKeyMap.getVisualKey("vk_space")实现

        hashMap.put("VK_0", KeyEvent.VK_0);//大写的Key,以方便录入,客户端发送大小写不区分
        hashMap.put("VK_TAB", KeyEvent.VK_TAB);
        hashMap.put("VK_ALT", KeyEvent.VK_ALT);
        // 此处省略需要增加的映射操作
    }
    public static int getVisualKey(String key) {
        //调用时只需VisualKeyMap.getVisualKey(String key)即可
        return hashMap.get(key.toUpperCase());//把key转为大写
    }

}

参考实验说明后,将之前使用接口DataTool实现的效果通过继承BaseOperator实现

安卓&socket学习分享(四)_第3张图片

安卓&socket学习分享(四)_第4张图片

OPN.java除了更改继承还要在返回结果添加如图

安卓&socket学习分享(四)_第5张图片

添加KEY.java来实现key热键操作

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 exe(String cmdBody) throws Exception {
        // TODO Auto-generated method stub
        // cmdBody,若有逗号,表示组合键,否则为单键
        // 组合键示例:VK_ALT+VK_TAB,VK_TAB+VK_ALT 表示先按下alt键,再按下tab键,再释放tab键,再释放alt键
        // 逗号前面的+表示按下键的顺序,逗号后面的+表示释放键的顺序
        ArrayList ackMsg = new ArrayList();
        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);//取0-(spisplitIdx-1)索引构成的子字符串
            String keyReleaseStr=cmdBody.substring(splitIdx+1);//取splitIdx+1到结尾的子字符串
            comboKeyPress(keyPressStr,keyReleaseStr);
        }

        ackMsg.add("成功运行热键命令 key:"+cmdBody+">1>1>1>1>");
        return ackMsg;
    }
    private void simpleComboKeyPress(String keyPressStr){
        String[] keyPressArray = keyPressStr.split("\\+");
        //split里的字符符合正则表达式规则, "+”是正则表达式的关键词,不能直接用,需要转义,而\本身是转义,所以需要\\来表示
        for(int i=0;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

安卓端更新

安卓&socket学习分享(四)_第6张图片

MainActivity.java较多改动

package com.example.sockettest.app;

import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.sockettest.R;
import com.example.sockettest.SocketClient;
import com.example.sockettest.data.CmdServerSetting;
import com.example.sockettest.data.NetFileData;
import com.example.sockettest.data.NetFileDataAdapter;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    SwipeRefreshLayout swipeRefreshLayout;
    public static final String KEY_SERVER_ACK_MSG = "KEY_SERVER_ACK_MSG";
    private  Handler handler = null;
    EditText dir;
    ListView lv;
    Button submit,back;
    SocketClient socketClient=null;
    String here;
    private static final String KEY_HERE="here";
    ArrayList data;
    ArrayList in_data;
    TextView here_tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dir=findViewById(R.id.dir);
        lv=findViewById(R.id.listview);
        submit=findViewById(R.id.submit);
        back=findViewById(R.id.back);
        here_tv=findViewById(R.id.here);

        initdata();

        handler=new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {

                Bundle data_bundle = msg.getData();
                in_data=data_bundle.getStringArrayList(KEY_SERVER_ACK_MSG);
                int fp=msg.arg2;
                if(fp==SocketClient.SERVER_MSG_OK){
                    data=dataMaker();
                    NetFileDataAdapter netFileDataAdapter=new NetFileDataAdapter(MainActivity.this,data);
                    lv.setAdapter(netFileDataAdapter);
                    savehereshow();

                } else {
                    String s=in_data.get(0);
                    int i=here.lastIndexOf("/");
                    here=here.substring(0,i);
                    Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show();
                }


                return false; }
        });

        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                here=dir.getText().toString();
                savedata();
                getdata();
            }
        });


        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                int i=here.lastIndexOf("/");
                int j=here.length();
                if (i6){
                    here=here.substring(0,i+1);
                    savedata();
                    getdata();
                    savehereshow();
                }else {
                    Toast.makeText(MainActivity.this,"已在最外层位置",Toast.LENGTH_SHORT).show();
                }

            }
        });

        registerForContextMenu(lv);
    }

    private void getdata() {
        socketClient=new SocketClient(CmdServerSetting.ip,CmdServerSetting.port,handler);
        socketClient.work(here);
    }

    private void savehereshow(){
        String s=here.substring(4);
        here_tv.setText("当前位置:"+s);
    }

    private void savedata() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(KEY_HERE,here);
        editor.apply();
    }

    private void initdata() {
        SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(this);
        here=sharedPreferences.getString(here,"d:/androidtest");
    }

    private ArrayList dataMaker() {
        ArrayList dataResult=new ArrayList<>();
        int i=in_data.size();
        for (int j = 0; j 

 

新增NetFileData.java

package com.example.sockettest.data;

public class NetFileData {
    private long fileSize = 0;// 文件长度应该long型数据,否则大于2GB的文件大小无法表达
    private String fileName = "$error";// 文件名称,不含目录信息,默认值用于表示文件出错
    private String filePath = ".\\";// 该文件对象所处的目录,默认值为当前相对目录
    private String fileSizeStr = "文件夹";// 文件的大小,用字符串表示,能智能地选择B、KB、MB、GB来表达
    private int fileType = 0;// fileType=0为文件,fileType=1为普通文件夹,fileType=2为盘符
    private String fileModifiedDate = "1970-01-01 00:00:00";// 文件最近修改日期,默认值为1970年基准时间

    public NetFileData(String fileInfo, String filePath2){
        String[] data=fileInfo.split(">");
        fileName=data[0];
        fileModifiedDate=data[1];
        fileSize=Long.parseLong(data[2]);
        fileType=Integer.parseInt(data[3]);
        if (fileSize>0){
            if (fileSize>=1024 ){
                long size_KB=fileSize/1024;
                if (size_KB>=1024){
                    long size_MB=size_KB/1024;
                    if (size_MB>=1024){
                        double a=1.0;
                        double size_GB=size_MB/a/1024;
                        fileSizeStr=size_GB+" GB";
                    }else {
                        fileSizeStr=size_MB+" MB";
                    }
                }else {
                    fileSizeStr=size_KB+" KB";
                }

            }else {
                fileSizeStr="1 KB";
            }
        }
        filePath=filePath2;

    }

//    public long getFileSize() {
//        return fileSize;
//    }

    public String getFileName() {
        return fileName;
    }

    public String getFilePath() {
        return filePath;
    }

    public String getFileSizeStr() {
        return fileSizeStr;
    }

    public int getFileType() {
        return fileType;
    }

    public String getFileModifiedDate() {
        return fileModifiedDate;
    }
}

新增NeFileDataAdapter.java

package com.example.sockettest.data;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.sockettest.R;

import java.util.ArrayList;

public class NetFileDataAdapter extends ArrayAdapter {
    private Context context;
    private ArrayList list;

    public NetFileDataAdapter(@NonNull Context context,  ArrayList list) {
        super(context, android.R.layout.simple_list_item_1,list);
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        View v;
        if(convertView==null){
            v= LayoutInflater.from(context).inflate(R.layout.row_view,null,false);
        }else{
            v=convertView;
        }

        TextView name=v.findViewById(R.id.row_name);
        TextView time=v.findViewById(R.id.row_time);
        TextView size=v.findViewById(R.id.row_size);
        final NetFileData data=list.get(position);
        name.setText(data.getFileName());
        time.setText(data.getFileModifiedDate());
        size.setText(data.getFileSizeStr());


        return v;
    }
}

CmdServerSetting.java与SocketClient.java无变动

activity_main.xml有所变动



    
        
        

新增dialog_view.xml



    

新增row_view.xml



    
    
    


新增opt_menu.xml



    
    
    

 

 

至此实验指导中的一到七章中的内容已经基本实现,建议大家可以在原有基础上理解后可以添加多种功能,进行修改优化,创新,以上为个人根据实验内容以实现功能为主不断尝试,改写,优化升级后的代码分享,与原实验内容有所偏差。

 

 

断更提醒~~   本次安卓课设系列更新估计是假期前的最后一更了,感谢浏览,祝学业有成。

 

 

 

你可能感兴趣的:(安卓课设socket,安卓)