目录
idea端更新
安卓端更新
本篇完成内容:
1)key热键操作
2)安卓端大量优化与升级
3)细节bug的修复与改进
Operator.java增加key命令操作
if (cmdHead.equals("key")) {
msgBackList = new KEY().exe(cmdBody); // 待实现的打开文件命令
return msgBackList;
}
增加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实现
OPN.java除了更改继承还要在返回结果添加如图
添加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
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
至此实验指导中的一到七章中的内容已经基本实现,建议大家可以在原有基础上理解后可以添加多种功能,进行修改优化,创新,以上为个人根据实验内容以实现功能为主不断尝试,改写,优化升级后的代码分享,与原实验内容有所偏差。
断更提醒~~ 本次安卓课设系列更新估计是假期前的最后一更了,感谢浏览,祝学业有成。