diff --git a/HybridFileXfer-Android/app/build.gradle b/HybridFileXfer-Android/app/build.gradle index 7c9b1ef..6d5e14c 100644 --- a/HybridFileXfer-Android/app/build.gradle +++ b/HybridFileXfer-Android/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "top.weixiansen574.hybridfilexfer" minSdk 24 targetSdk 34 - versionCode 1 - versionName "1.0" + versionCode 11 + versionName "1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/HybridFileXfer-Android/app/debug/app-debug.apk b/HybridFileXfer-Android/app/debug/app-debug.apk index 016ee51..93b08cf 100644 Binary files a/HybridFileXfer-Android/app/debug/app-debug.apk and b/HybridFileXfer-Android/app/debug/app-debug.apk differ diff --git a/HybridFileXfer-Android/app/debug/output-metadata.json b/HybridFileXfer-Android/app/debug/output-metadata.json index 08c6e68..9fe76ca 100644 --- a/HybridFileXfer-Android/app/debug/output-metadata.json +++ b/HybridFileXfer-Android/app/debug/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 1, - "versionName": "1.0_1711385041641", + "versionName": "1.0", "outputFile": "app-debug.apk" } ], diff --git a/HybridFileXfer-Android/app/release/app-release.apk b/HybridFileXfer-Android/app/release/app-release.apk index 03fc05b..a6d6fda 100644 Binary files a/HybridFileXfer-Android/app/release/app-release.apk and b/HybridFileXfer-Android/app/release/app-release.apk differ diff --git a/HybridFileXfer-Android/app/release/output-metadata.json b/HybridFileXfer-Android/app/release/output-metadata.json index 878330b..1e89d50 100644 --- a/HybridFileXfer-Android/app/release/output-metadata.json +++ b/HybridFileXfer-Android/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 1, - "versionName": "1.0", + "versionCode": 11, + "versionName": "1.1", "outputFile": "app-release.apk" } ], diff --git a/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/TransferServiceBinder.java b/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/TransferServiceBinder.java index c61b1e3..a691f8f 100644 --- a/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/TransferServiceBinder.java +++ b/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/TransferServiceBinder.java @@ -106,7 +106,9 @@ public ArrayList listClientFiles(String path) throws Remot try { ArrayList remoteFiles = fileTransferServer.listClientFiles(path); ArrayList parcelableRemoteFiles = new ArrayList<>(); + System.out.println("获取到电脑端文件,size:"+remoteFiles.size()); for (RemoteFile remoteFile : remoteFiles) { + System.out.println(remoteFile.getName()); parcelableRemoteFiles.add(new ParcelableRemoteFile(remoteFile)); } return parcelableRemoteFiles; diff --git a/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java b/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java index b77925f..ab312b7 100644 --- a/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java +++ b/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java @@ -117,15 +117,34 @@ private void waitPCConnect() throws IOException { wifiReceiveThread.setOnExceptionListener(this); wifiReceiveThread.start(); - - - - } public ArrayList listClientFiles(String path) throws IOException { dos.writeShort(ControllerIdentifiers.LIST_FILES); dos.writeUTF(path); + //这里不用json了,导入json库会让服务端jar膨胀250kb,直接用字节流传输 + int listSize = dis.readInt(); + ArrayList remoteFiles = new ArrayList<>(listSize); + //| name | path | lastModified | size | isDirectory | + //| ---------- | ---------- | ------------ | ------- | ----------- | + //| String:UTF | String:UTF | long:8b | long:8b | boolean | + for (int i = 0; i < listSize; i++) { + RemoteFile remoteFile = new RemoteFile( + dis.readUTF(),//name + dis.readUTF(),//path + dis.readLong(),//lastModified + dis.readLong(),//size + dis.readBoolean()//isDirectory + ); + remoteFiles.add(remoteFile); + } + return remoteFiles; + + /* + 因为安卓release版会删减无用代码,导致RemoteFile序列化ID不一致 + objectInputStream.readObject方法将出现异常,导致电脑端目录显示是空白 + 再就是服务端不支持夸语言,仅限于java + 已弃用以下代码 int contentLength = dis.readInt(); byte[] content = new byte[contentLength]; @@ -139,21 +158,26 @@ public ArrayList listClientFiles(String path) throws IOException { throw new IOException(e); } finally { byteArrayInputStream.close(); - } + }*/ } public void transferToMe(List files, String remoteDir, String localDir) throws IOException { dos.writeShort(ControllerIdentifiers.TRANSPORT_FILES);//标识,传输文件到服务端 dos.writeUTF(localDir);//服务端路径(手机) dos.writeUTF(remoteDir);//客户端路径(电脑) - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + dos.writeInt(files.size());//文件数量 + for (String file : files) { + dos.writeUTF(file);//文件路径 + } + //ObjectInputStream可能会出现序列化不一致相关问题,已弃用 + /*ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(files); objectOutputStream.flush(); byte[] bytes = outputStream.toByteArray(); outputStream.close(); dos.writeInt(bytes.length);//content length - dos.write(bytes);//要传输到服务端的文件列表 + dos.write(bytes);//要传输到服务端的文件列表*/ } public void transferToClient(List files, File localDir, String remoteDir) { diff --git a/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java b/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java index 90d267e..278b3f2 100644 --- a/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java +++ b/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java @@ -52,11 +52,11 @@ public void run() { InetAddress serverWifiAddress; try { serverWifiAddress = getServerWifiAddress(); - } catch (IOException e){ + } catch (IOException e) { System.out.println("连接手机失败,因为服务端未运行!请在手机上启动服务器并等待连接!"); return; } - if (Arrays.equals(serverWifiAddress.getAddress(),new byte[4])){ + if (Arrays.equals(serverWifiAddress.getAddress(), new byte[4])) { System.out.println("连接手机失败,因为手机没有连接WIFI!"); return; } @@ -65,24 +65,24 @@ public void run() { Socket usbSocket = new Socket(InetAddress.getLoopbackAddress(), ServerInfo.PORT_USB);//USB-ADB forward的端口是本地127.0.0.1 //接收线程只管接收 - usbReceiveThread = new ReceiveThread(fileTransferEvents,ReceiveThread.DEVICE_USB,usbSocket.getInputStream()); + usbReceiveThread = new ReceiveThread(fileTransferEvents, ReceiveThread.DEVICE_USB, usbSocket.getInputStream()); usbReceiveThread.setName("usbReceive"); usbReceiveThread.setOnExceptionListener(this); usbReceiveThread.start(); - wifiReceiveThread = new ReceiveThread(fileTransferEvents,ReceiveThread.DEVICE_WIFI,wifiSocket.getInputStream()); + wifiReceiveThread = new ReceiveThread(fileTransferEvents, ReceiveThread.DEVICE_WIFI, wifiSocket.getInputStream()); wifiReceiveThread.setName("wifiReceive"); wifiReceiveThread.setOnExceptionListener(this); wifiReceiveThread.start(); - usbSendThread = new SendThread(fileTransferEvents,SendThread.DEVICE_USB,jobPublisher,usbSocket.getOutputStream()); + usbSendThread = new SendThread(fileTransferEvents, SendThread.DEVICE_USB, jobPublisher, usbSocket.getOutputStream()); usbSendThread.setName("usbSend"); usbSendThread.setOnExceptionListener(this); usbSendThread.start(); - wifiSendThread = new SendThread(fileTransferEvents,SendThread.DEVICE_WIFI,jobPublisher,wifiSocket.getOutputStream()); + wifiSendThread = new SendThread(fileTransferEvents, SendThread.DEVICE_WIFI, jobPublisher, wifiSocket.getOutputStream()); wifiSendThread.setName("wifiSend"); wifiSendThread.setOnExceptionListener(this); wifiSendThread.start(); - System.out.println("已连接至手机!WLAN IP:"+serverWifiAddress.getHostAddress()); + System.out.println("已连接至手机!WLAN IP:" + serverWifiAddress.getHostAddress()); waitingForRequest(); } catch (IOException | ClassNotFoundException e) { @@ -101,25 +101,32 @@ private InetAddress getServerWifiAddress() throws IOException { } private void waitingForRequest() throws IOException, ClassNotFoundException { - w:while (true) { + w: + while (true) { short identifiers = dis.readShort(); switch (identifiers) { case ControllerIdentifiers.LIST_FILES: String path = dis.readUTF(); - System.out.println("获取文件列表 "+path); + System.out.println("获取文件列表 " + path); handleListFiles(path); break; case ControllerIdentifiers.TRANSPORT_FILES: String serverDir = dis.readUTF();//服务器(手机)路径 String dir = dis.readUTF();//客户端(电脑)的路径 - int contentLength = dis.readInt();//内容长度(文件列表) + int listSize = dis.readInt();//文件路径列表大小 + List toTransferFilePaths = new ArrayList<>(listSize); + for (int i = 0; i < listSize; i++) { + toTransferFilePaths.add(dis.readUTF()); + } + //ObjectInputStream可能会出现序列化不一致相关问题,已弃用 + /*int contentLength = dis.readInt();//内容长度(文件列表) byte[] bytes = new byte[contentLength]; dis.readFully(bytes); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); List remoteFiles = (List) objectInputStream.readObject(); - inputStream.close(); - handleTransferFileToServer(serverDir,dir,remoteFiles); + inputStream.close();*/ + handleTransferFileToServer(serverDir, dir, toTransferFilePaths); break; case ControllerIdentifiers.SHUTDOWN: System.out.println("收到关闭指令,准备关闭连接……"); @@ -140,38 +147,53 @@ private void waitingForRequest() throws IOException, ClassNotFoundException { } private void handleListFiles(String path) throws IOException { - - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); - ArrayList files = new ArrayList<>(); - if (!path.equals("/")) { - File file = new File(path); - File[] list = file.listFiles(); - if (list != null) { - for (File file1 : list) { - files.add(new RemoteFile(file1)); - } + ArrayList files = new ArrayList<>(); + if (!path.equals("/")) { + File file = new File(path); + File[] list = file.listFiles(); + if (list != null) { + for (File file1 : list) { + files.add(new RemoteFile(file1)); + } + } + } else { + File[] roots = File.listRoots(); + //判断是否是Linux的目录结构,Windows的根目录是C:\\,而不是所有盘符,Linux的根目录是“/”没有盘符概念 + if (roots.length == 1 && roots[0].getAbsolutePath().equals("/")){ + roots = roots[0].listFiles(); + if (roots == null){ + throw new RuntimeException("无法获取根目录下的文件列表,请检查运行时权限"); + } + for (File root : roots) { + files.add(new RemoteFile(root.getName(), root.getPath(), root.lastModified(), root.length(), root.isDirectory())); } } else { - File[] roots = File.listRoots(); for (File root : roots) { - files.add(new RemoteFile(root.getPath(),root.getPath(),root.lastModified(),root.length(),root.isDirectory())); + files.add(new RemoteFile(root.getPath(), root.getPath(), root.lastModified(), root.length(), root.isDirectory())); } } - objectOutputStream.writeObject(files); - objectOutputStream.flush(); - byte[] bytes = byteArrayOutputStream.toByteArray(); - dos.writeInt(bytes.length); - dos.write(bytes); + } + //已弃用ObjectOutputStream + //| name | path | lastModified | size | isDirectory | + //| ---------- | ---------- | ------------ | ------- | ----------- | + //| String:UTF | String:UTF | long:8b | long:8b | boolean | + dos.writeInt(files.size());//listSize + for (RemoteFile file : files) { + dos.writeUTF(file.getName()); + dos.writeUTF(file.getPath()); + dos.writeLong(file.getLastModified()); + dos.writeLong(file.getSize()); + dos.writeBoolean(file.isDirectory()); + } } - private void handleTransferFileToServer(String serverDir,String dir,List remoteFiles){ + private void handleTransferFileToServer(String serverDir, String dir, List remoteFiles) { File localDir = new File(dir); List transferFiles = new ArrayList<>(); for (String remoteFile : remoteFiles) { transferFiles.add(new File(remoteFile)); } - jobPublisher.addJob(new TransferJob(localDir,serverDir,transferFiles)); + jobPublisher.addJob(new TransferJob(localDir, serverDir, transferFiles)); } diff --git a/HybridFileXfer-PC/.idea/misc.xml b/HybridFileXfer-PC/.idea/misc.xml index 07115cd..0548357 100644 --- a/HybridFileXfer-PC/.idea/misc.xml +++ b/HybridFileXfer-PC/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/HybridFileXfer-PC/out/artifacts/HybridFileXfer_jar/HybridFileXfer.jar b/HybridFileXfer-PC/out/artifacts/HybridFileXfer_jar/HybridFileXfer.jar index 511cc4d..f0fe32b 100644 Binary files a/HybridFileXfer-PC/out/artifacts/HybridFileXfer_jar/HybridFileXfer.jar and b/HybridFileXfer-PC/out/artifacts/HybridFileXfer_jar/HybridFileXfer.jar differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/Main.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/Main.class index e7be775..a4f1fed 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/Main.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/Main.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.class index 466dd21..1c8039c 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferClient.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferClient.class index 9f83695..0308605 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferClient.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferClient.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferServer.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferServer.class index 6e90f80..9d610c8 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferServer.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/FileTransferServer.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/JobPublisher.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/JobPublisher.class index 72875f0..7e9eac1 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/JobPublisher.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/JobPublisher.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ServerInfo.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ServerInfo.class index 15c46f7..0cad533 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ServerInfo.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/ServerInfo.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.class index 36e8972..08ddf8a 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/Utils.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/Utils.class index 774b761..4233ffd 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/Utils.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/Utils.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/DevicesInterface.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/DevicesInterface.class index 4dad76a..ef5e790 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/DevicesInterface.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/DevicesInterface.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.class index 0eef7c0..a2b96d6 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferJob.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferJob.class index ba98962..736ab40 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferJob.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/FileTransferJob.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.class index 5d04191..5aa2d06 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferJob.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferJob.class index 6319157..aac6619 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferJob.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferJob.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferredBytesInfo.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferredBytesInfo.class index 34ae677..6e31357 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferredBytesInfo.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/bean/TransferredBytesInfo.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.class index 3622dec..5cd9a2f 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/OnErrorListener.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/OnErrorListener.class index 920177c..4dfe40c 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/OnErrorListener.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/OnErrorListener.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ReceiveThread.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ReceiveThread.class index 9cacdfd..2b32e7c 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ReceiveThread.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/ReceiveThread.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/SendThread.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/SendThread.class index 7bd8c73..794e442 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/SendThread.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/SendThread.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread$OnExceptionListener.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread$OnExceptionListener.class index 7b5ad1b..dfa5574 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread$OnExceptionListener.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread$OnExceptionListener.class differ diff --git a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread.class b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread.class index 36d2341..e454517 100644 Binary files a/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread.class and b/HybridFileXfer-PC/out/production/HybridFileXfer/top/weixiansen574/hybridfilexfer/core/threads/TransferThread.class differ diff --git a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/Main.java b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/Main.java index 1ae01c4..8c2db50 100644 --- a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/Main.java +++ b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/Main.java @@ -8,13 +8,13 @@ public class Main { public static void main(String[] args) { - if (executeAdbForwardCommand(5740)){ + if (executeAdbForwardCommand(5740,args)){ System.out.println("USB : 5740 端口转发成功!"); } else { System.out.println("USB : 5740 端口转发失败,请检查是否开启USB调试和授权此电脑!"); return; } - if (executeAdbForwardCommand(5741)) { + if (executeAdbForwardCommand(5741,args)) { System.out.println("USB : 5741 端口转发成功!"); } else { System.out.println("USB : 5741 端口转发失败,请检查是否开启USB调试和授权此电脑!"); @@ -23,27 +23,36 @@ public static void main(String[] args) { new FileTransferClient().startUp(); } - public static boolean executeAdbForwardCommand(int port) { + public static boolean executeAdbForwardCommand(int port,String[] args) { try { // 获取当前jar包所在的目录 String jarDirectory = System.getProperty("user.dir"); + StringBuilder adbCommand = new StringBuilder(); + adbCommand.append("./adb"); + for (String arg : args) { + adbCommand.append(" ").append(arg); + } + adbCommand.append(" forward tcp:"); + adbCommand.append(port); + adbCommand.append(" tcp:"); + adbCommand.append(port); // 构建adb forward命令 - String adbForwardCommand = "adb.exe forward tcp:" + port + " tcp:" + port; + String adbForwardCommand = adbCommand.toString(); // 执行adb forward命令 Process process = Runtime.getRuntime().exec(adbForwardCommand, null, new java.io.File(jarDirectory)); - - BufferedReader bufferedReader = process.errorReader(); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + //BufferedReader errorReader = process.errorReader(); String l; - while ((l = bufferedReader.readLine()) != null){ + while ((l = errorReader.readLine()) != null){ System.err.println(l); } // 读取adb forward命令执行的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { - System.out.println("adb.exe:"+line); + System.out.println("adb:"+line); } // 等待命令执行完成 diff --git a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java index 6411672..ab312b7 100644 --- a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java +++ b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/FileTransferServer.java @@ -40,7 +40,7 @@ public class FileTransferServer implements ServerInfo, TransferThread.OnExceptio ReceiveThread usbReceiveThread; SendThread wifiSendThread; ReceiveThread wifiReceiveThread; - BlockingDeque fileTransferEvents; + public final BlockingDeque fileTransferEvents; ServerSocket controllerSocket; ServerSocket usbServerSocket; ServerSocket wifiServerSocket; @@ -117,15 +117,34 @@ private void waitPCConnect() throws IOException { wifiReceiveThread.setOnExceptionListener(this); wifiReceiveThread.start(); - - - - } public ArrayList listClientFiles(String path) throws IOException { dos.writeShort(ControllerIdentifiers.LIST_FILES); dos.writeUTF(path); + //这里不用json了,导入json库会让服务端jar膨胀250kb,直接用字节流传输 + int listSize = dis.readInt(); + ArrayList remoteFiles = new ArrayList<>(listSize); + //| name | path | lastModified | size | isDirectory | + //| ---------- | ---------- | ------------ | ------- | ----------- | + //| String:UTF | String:UTF | long:8b | long:8b | boolean | + for (int i = 0; i < listSize; i++) { + RemoteFile remoteFile = new RemoteFile( + dis.readUTF(),//name + dis.readUTF(),//path + dis.readLong(),//lastModified + dis.readLong(),//size + dis.readBoolean()//isDirectory + ); + remoteFiles.add(remoteFile); + } + return remoteFiles; + + /* + 因为安卓release版会删减无用代码,导致RemoteFile序列化ID不一致 + objectInputStream.readObject方法将出现异常,导致电脑端目录显示是空白 + 再就是服务端不支持夸语言,仅限于java + 已弃用以下代码 int contentLength = dis.readInt(); byte[] content = new byte[contentLength]; @@ -139,21 +158,26 @@ public ArrayList listClientFiles(String path) throws IOException { throw new IOException(e); } finally { byteArrayInputStream.close(); - } + }*/ } public void transferToMe(List files, String remoteDir, String localDir) throws IOException { dos.writeShort(ControllerIdentifiers.TRANSPORT_FILES);//标识,传输文件到服务端 dos.writeUTF(localDir);//服务端路径(手机) dos.writeUTF(remoteDir);//客户端路径(电脑) - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + dos.writeInt(files.size());//文件数量 + for (String file : files) { + dos.writeUTF(file);//文件路径 + } + //ObjectInputStream可能会出现序列化不一致相关问题,已弃用 + /*ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(files); objectOutputStream.flush(); byte[] bytes = outputStream.toByteArray(); outputStream.close(); dos.writeInt(bytes.length);//content length - dos.write(bytes);//要传输到服务端的文件列表 + dos.write(bytes);//要传输到服务端的文件列表*/ } public void transferToClient(List files, File localDir, String remoteDir) { diff --git a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.java b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.java index 912c7a4..207a001 100644 --- a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.java +++ b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/FileTransferEvent.java @@ -13,6 +13,9 @@ public FileTransferEvent(int state, int device, String desc) { this.desc = desc; } + public FileTransferEvent() { + } + public int getState() { return state; } diff --git a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java index 90d267e..278b3f2 100644 --- a/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java +++ b/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/threads/ClientControllerThread.java @@ -52,11 +52,11 @@ public void run() { InetAddress serverWifiAddress; try { serverWifiAddress = getServerWifiAddress(); - } catch (IOException e){ + } catch (IOException e) { System.out.println("连接手机失败,因为服务端未运行!请在手机上启动服务器并等待连接!"); return; } - if (Arrays.equals(serverWifiAddress.getAddress(),new byte[4])){ + if (Arrays.equals(serverWifiAddress.getAddress(), new byte[4])) { System.out.println("连接手机失败,因为手机没有连接WIFI!"); return; } @@ -65,24 +65,24 @@ public void run() { Socket usbSocket = new Socket(InetAddress.getLoopbackAddress(), ServerInfo.PORT_USB);//USB-ADB forward的端口是本地127.0.0.1 //接收线程只管接收 - usbReceiveThread = new ReceiveThread(fileTransferEvents,ReceiveThread.DEVICE_USB,usbSocket.getInputStream()); + usbReceiveThread = new ReceiveThread(fileTransferEvents, ReceiveThread.DEVICE_USB, usbSocket.getInputStream()); usbReceiveThread.setName("usbReceive"); usbReceiveThread.setOnExceptionListener(this); usbReceiveThread.start(); - wifiReceiveThread = new ReceiveThread(fileTransferEvents,ReceiveThread.DEVICE_WIFI,wifiSocket.getInputStream()); + wifiReceiveThread = new ReceiveThread(fileTransferEvents, ReceiveThread.DEVICE_WIFI, wifiSocket.getInputStream()); wifiReceiveThread.setName("wifiReceive"); wifiReceiveThread.setOnExceptionListener(this); wifiReceiveThread.start(); - usbSendThread = new SendThread(fileTransferEvents,SendThread.DEVICE_USB,jobPublisher,usbSocket.getOutputStream()); + usbSendThread = new SendThread(fileTransferEvents, SendThread.DEVICE_USB, jobPublisher, usbSocket.getOutputStream()); usbSendThread.setName("usbSend"); usbSendThread.setOnExceptionListener(this); usbSendThread.start(); - wifiSendThread = new SendThread(fileTransferEvents,SendThread.DEVICE_WIFI,jobPublisher,wifiSocket.getOutputStream()); + wifiSendThread = new SendThread(fileTransferEvents, SendThread.DEVICE_WIFI, jobPublisher, wifiSocket.getOutputStream()); wifiSendThread.setName("wifiSend"); wifiSendThread.setOnExceptionListener(this); wifiSendThread.start(); - System.out.println("已连接至手机!WLAN IP:"+serverWifiAddress.getHostAddress()); + System.out.println("已连接至手机!WLAN IP:" + serverWifiAddress.getHostAddress()); waitingForRequest(); } catch (IOException | ClassNotFoundException e) { @@ -101,25 +101,32 @@ private InetAddress getServerWifiAddress() throws IOException { } private void waitingForRequest() throws IOException, ClassNotFoundException { - w:while (true) { + w: + while (true) { short identifiers = dis.readShort(); switch (identifiers) { case ControllerIdentifiers.LIST_FILES: String path = dis.readUTF(); - System.out.println("获取文件列表 "+path); + System.out.println("获取文件列表 " + path); handleListFiles(path); break; case ControllerIdentifiers.TRANSPORT_FILES: String serverDir = dis.readUTF();//服务器(手机)路径 String dir = dis.readUTF();//客户端(电脑)的路径 - int contentLength = dis.readInt();//内容长度(文件列表) + int listSize = dis.readInt();//文件路径列表大小 + List toTransferFilePaths = new ArrayList<>(listSize); + for (int i = 0; i < listSize; i++) { + toTransferFilePaths.add(dis.readUTF()); + } + //ObjectInputStream可能会出现序列化不一致相关问题,已弃用 + /*int contentLength = dis.readInt();//内容长度(文件列表) byte[] bytes = new byte[contentLength]; dis.readFully(bytes); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); List remoteFiles = (List) objectInputStream.readObject(); - inputStream.close(); - handleTransferFileToServer(serverDir,dir,remoteFiles); + inputStream.close();*/ + handleTransferFileToServer(serverDir, dir, toTransferFilePaths); break; case ControllerIdentifiers.SHUTDOWN: System.out.println("收到关闭指令,准备关闭连接……"); @@ -140,38 +147,53 @@ private void waitingForRequest() throws IOException, ClassNotFoundException { } private void handleListFiles(String path) throws IOException { - - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); - ArrayList files = new ArrayList<>(); - if (!path.equals("/")) { - File file = new File(path); - File[] list = file.listFiles(); - if (list != null) { - for (File file1 : list) { - files.add(new RemoteFile(file1)); - } + ArrayList files = new ArrayList<>(); + if (!path.equals("/")) { + File file = new File(path); + File[] list = file.listFiles(); + if (list != null) { + for (File file1 : list) { + files.add(new RemoteFile(file1)); + } + } + } else { + File[] roots = File.listRoots(); + //判断是否是Linux的目录结构,Windows的根目录是C:\\,而不是所有盘符,Linux的根目录是“/”没有盘符概念 + if (roots.length == 1 && roots[0].getAbsolutePath().equals("/")){ + roots = roots[0].listFiles(); + if (roots == null){ + throw new RuntimeException("无法获取根目录下的文件列表,请检查运行时权限"); + } + for (File root : roots) { + files.add(new RemoteFile(root.getName(), root.getPath(), root.lastModified(), root.length(), root.isDirectory())); } } else { - File[] roots = File.listRoots(); for (File root : roots) { - files.add(new RemoteFile(root.getPath(),root.getPath(),root.lastModified(),root.length(),root.isDirectory())); + files.add(new RemoteFile(root.getPath(), root.getPath(), root.lastModified(), root.length(), root.isDirectory())); } } - objectOutputStream.writeObject(files); - objectOutputStream.flush(); - byte[] bytes = byteArrayOutputStream.toByteArray(); - dos.writeInt(bytes.length); - dos.write(bytes); + } + //已弃用ObjectOutputStream + //| name | path | lastModified | size | isDirectory | + //| ---------- | ---------- | ------------ | ------- | ----------- | + //| String:UTF | String:UTF | long:8b | long:8b | boolean | + dos.writeInt(files.size());//listSize + for (RemoteFile file : files) { + dos.writeUTF(file.getName()); + dos.writeUTF(file.getPath()); + dos.writeLong(file.getLastModified()); + dos.writeLong(file.getSize()); + dos.writeBoolean(file.isDirectory()); + } } - private void handleTransferFileToServer(String serverDir,String dir,List remoteFiles){ + private void handleTransferFileToServer(String serverDir, String dir, List remoteFiles) { File localDir = new File(dir); List transferFiles = new ArrayList<>(); for (String remoteFile : remoteFiles) { transferFiles.add(new File(remoteFile)); } - jobPublisher.addJob(new TransferJob(localDir,serverDir,transferFiles)); + jobPublisher.addJob(new TransferJob(localDir, serverDir, transferFiles)); } diff --git a/README.md b/README.md index bfe6469..50cb57d 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,37 @@ Root模式需要安装[Sui模块](https://github.com/RikkaApps/Sui/releases), IMG_20240326_195758 +### adb指定设备 + +v1.1版本新增,用命令行运行jar或者修改启动脚本,程序会在末尾添加adb参数 + +```shell +java -jar HybridFileXfer.jar +#示例 +adb devices +#List of devices attached +#1234abcd device +#4321dcba device + +java -jar HybridFileXfer.jar -s 1234abcd +#程序附加后 +adb -s 1234abcd forward tcp:5740 tcp:5740 +``` + +### Linux电脑 + +v1.1新增对Linux的支持,下载对应的电脑客户端即可,解压后执行 + +```shell +java -jar HybridFileXfer.jar +``` + +或者双击start.bat + +目前仅支持x86 CPU的电脑,虽然Java是夸平台的,但是adb对处理器架构有要求。如果你需要在ARM,RISC-V,龙芯等CPU架构下运行,可以寻找对应处理器架构的adb程序,复制到jar包的同一目录 + +~~可以试试termux-adb+Java运行环境两台手机对拷🤣~~ + ## 传输 连接成功后,点击传输文件按钮,即可开始选择文件进行传输。