├── 1706328825823.jpg
├── HybridFileXfer-Android
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── .name
│ ├── compiler.xml
│ ├── deploymentTargetSelector.xml
│ ├── gradle.xml
│ ├── misc.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── top
│ │ │ └── weixiansen574
│ │ │ └── hybridfilexfer2
│ │ │ └── ExampleInstrumentedTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── aidl
│ │ │ └── top
│ │ │ │ └── weixiansen574
│ │ │ │ └── hybridfilexfer
│ │ │ │ └── aidl
│ │ │ │ ├── IIOService.aidl
│ │ │ │ └── ParcelableRemoteFile.aidl
│ │ ├── cpp
│ │ │ ├── CMakeLists.txt
│ │ │ └── native-memory.cpp
│ │ ├── java
│ │ │ └── top
│ │ │ │ └── weixiansen574
│ │ │ │ ├── async
│ │ │ │ ├── BackstageTask.java
│ │ │ │ └── TaskManger.java
│ │ │ │ ├── hybridfilexfer
│ │ │ │ ├── ClientActivity.java
│ │ │ │ ├── Config.java
│ │ │ │ ├── ConfigDB.java
│ │ │ │ ├── IOService.java
│ │ │ │ ├── IOServiceImpl.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── NativeMemory.java
│ │ │ │ ├── NetCardIcon.java
│ │ │ │ ├── TransferActivity.java
│ │ │ │ ├── TransferDialog.java
│ │ │ │ ├── aidl
│ │ │ │ │ └── ParcelableRemoteFile.java
│ │ │ │ ├── bean
│ │ │ │ │ └── BookMark.java
│ │ │ │ ├── core
│ │ │ │ │ ├── ControllerIdentifiers.java
│ │ │ │ │ ├── FileBlock.java
│ │ │ │ │ ├── HFXClient.java
│ │ │ │ │ ├── HFXService.java
│ │ │ │ │ ├── ReadFileCall.java
│ │ │ │ │ ├── ReceiveFileCall.java
│ │ │ │ │ ├── SendFileCall.java
│ │ │ │ │ ├── SpeedMonitorThread.java
│ │ │ │ │ ├── TransferConnection.java
│ │ │ │ │ ├── TransferIdentifiers.java
│ │ │ │ │ ├── Utils.java
│ │ │ │ │ ├── WriteFileCall.java
│ │ │ │ │ ├── bean
│ │ │ │ │ │ ├── Directory.java
│ │ │ │ │ │ ├── RemoteFile.java
│ │ │ │ │ │ ├── ServerNetInterface.java
│ │ │ │ │ │ └── TrafficInfo.java
│ │ │ │ │ └── callback
│ │ │ │ │ │ ├── ClientCallBack.java
│ │ │ │ │ │ ├── ConnectServerCallback.java
│ │ │ │ │ │ └── TransferFileCallback.java
│ │ │ │ ├── droidcore
│ │ │ │ │ ├── DisconnectTask.java
│ │ │ │ │ ├── DroidHFXClient.java
│ │ │ │ │ ├── DroidReadFileCall.java
│ │ │ │ │ ├── DroidWriteFileCall.java
│ │ │ │ │ ├── HFXServer.java
│ │ │ │ │ ├── StartServerTask.java
│ │ │ │ │ └── callback
│ │ │ │ │ │ └── StartServerCallback.java
│ │ │ │ ├── listadapter
│ │ │ │ │ ├── BookmarkAdapter.java
│ │ │ │ │ ├── FileSelectAdapter.java
│ │ │ │ │ ├── LocalFileSelectAdapter.java
│ │ │ │ │ ├── NetCardsAdapter.java
│ │ │ │ │ └── RemoteFileSelectAdapter.java
│ │ │ │ └── tasks
│ │ │ │ │ ├── BTransferFileCallback.java
│ │ │ │ │ ├── ClientTask.java
│ │ │ │ │ ├── ConnectServerTask.java
│ │ │ │ │ ├── DeleteFilesTask.java
│ │ │ │ │ ├── ListFilesTask.java
│ │ │ │ │ ├── SendFilesToRemoteTask.java
│ │ │ │ │ └── SendFilesToShelfTask.java
│ │ │ │ └── nio
│ │ │ │ └── DataByteChannel.java
│ │ └── res
│ │ │ ├── anim
│ │ │ └── list_anim.xml
│ │ │ ├── drawable
│ │ │ ├── baseline_add_24.xml
│ │ │ ├── baseline_arrow_outward_24.xml
│ │ │ ├── baseline_bookmark_add_24.xml
│ │ │ ├── baseline_bookmarks_24.xml
│ │ │ ├── baseline_check_circle_24.xml
│ │ │ ├── baseline_delete_24.xml
│ │ │ ├── baseline_file_download_24.xml
│ │ │ ├── baseline_grid_view_24.xml
│ │ │ ├── baseline_more_vert_24.xml
│ │ │ ├── baseline_phonelink_ring_24.xml
│ │ │ ├── baseline_refresh_24.xml
│ │ │ ├── baseline_select_all_24.xml
│ │ │ ├── baseline_speed_24.xml
│ │ │ ├── baseline_update_24.xml
│ │ │ ├── baseline_upload_24.xml
│ │ │ ├── bt.xml
│ │ │ ├── ethernet.xml
│ │ │ ├── file.xml
│ │ │ ├── folder.xml
│ │ │ ├── github.xml
│ │ │ ├── ic_close.xml
│ │ │ ├── logo.png
│ │ │ ├── shadow_bottom.xml
│ │ │ ├── shadow_left.xml
│ │ │ ├── shadow_right.xml
│ │ │ ├── shadow_top.xml
│ │ │ ├── usb.xml
│ │ │ └── wifi.xml
│ │ │ ├── layout
│ │ │ ├── activity_client.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_transfer.xml
│ │ │ ├── dialog_bookmarks.xml
│ │ │ ├── dialog_buffer_settings.xml
│ │ │ ├── dialog_connect_server.xml
│ │ │ ├── dialog_transfer.xml
│ │ │ ├── edit_text.xml
│ │ │ ├── item_bookmark.xml
│ │ │ ├── item_file.xml
│ │ │ ├── item_net_card_info.xml
│ │ │ ├── item_net_interface_status.xml
│ │ │ └── toolbar_select.xml
│ │ │ ├── menu
│ │ │ ├── main_menu.xml
│ │ │ ├── select_toolbar_menu.xml
│ │ │ └── toolbar_menu.xml
│ │ │ ├── values-ja-rJP
│ │ │ └── strings.xml
│ │ │ ├── values-ko
│ │ │ └── strings.xml
│ │ │ ├── values-night
│ │ │ └── colors.xml
│ │ │ ├── values-zh-rTW
│ │ │ └── strings.xml
│ │ │ ├── values-zh
│ │ │ └── strings.xml
│ │ │ ├── values
│ │ │ ├── arrays.xml
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ │ └── xml
│ │ │ ├── backup_rules.xml
│ │ │ └── data_extraction_rules.xml
│ │ └── test
│ │ └── java
│ │ └── top
│ │ └── weixiansen574
│ │ └── hybridfilexfer2
│ │ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── HybridFileXfer-PC
├── .idea
│ ├── .gitignore
│ ├── HybridFileXfer-PC.iml
│ ├── artifacts
│ │ └── HybridFileXfer_PC_jar.xml
│ ├── encodings.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── uiDesigner.xml
│ └── vcs.xml
├── AdbWinApi.dll
├── AdbWinUsbApi.dll
├── HybridFileXfer-PC.iml
├── adb.exe
├── out
│ ├── artifacts
│ │ └── HybridFileXfer_PC_jar
│ │ │ └── HybridFileXfer-PC.jar
│ └── production
│ │ └── HybridFileXfer-PC
│ │ ├── META-INF
│ │ └── MANIFEST.MF
│ │ ├── messages_en.properties
│ │ ├── messages_ja.properties
│ │ ├── messages_ko.properties
│ │ ├── messages_zh_CN.properties
│ │ ├── messages_zh_TW.properties
│ │ └── top
│ │ └── weixiansen574
│ │ ├── hybridfilexfer
│ │ ├── Main$1.class
│ │ ├── Main$2.class
│ │ ├── Main.class
│ │ ├── Strings$1.class
│ │ ├── Strings.class
│ │ ├── core
│ │ │ ├── ControllerIdentifiers.class
│ │ │ ├── FileBlock.class
│ │ │ ├── HFXClient.class
│ │ │ ├── HFXService.class
│ │ │ ├── ReadFileCall.class
│ │ │ ├── ReceiveFileCall.class
│ │ │ ├── SendFileCall.class
│ │ │ ├── SpeedMonitorThread.class
│ │ │ ├── TransferConnection.class
│ │ │ ├── TransferIdentifiers.class
│ │ │ ├── Utils.class
│ │ │ ├── WriteFileCall.class
│ │ │ ├── bean
│ │ │ │ ├── Directory.class
│ │ │ │ ├── RemoteFile.class
│ │ │ │ ├── ServerNetInterface.class
│ │ │ │ └── TrafficInfo.class
│ │ │ └── callback
│ │ │ │ ├── ClientCallBack.class
│ │ │ │ ├── ConnectServerCallback.class
│ │ │ │ └── TransferFileCallback.class
│ │ └── jdkcore
│ │ │ ├── JdkHFXClient.class
│ │ │ ├── JdkReadFileCall.class
│ │ │ └── JdkWriteFileCall.class
│ │ └── nio
│ │ └── DataByteChannel.class
├── src
│ ├── META-INF
│ │ └── MANIFEST.MF
│ ├── messages_en.properties
│ ├── messages_ja.properties
│ ├── messages_ko.properties
│ ├── messages_zh_CN.properties
│ ├── messages_zh_TW.properties
│ └── top
│ │ └── weixiansen574
│ │ ├── hybridfilexfer
│ │ ├── Main.java
│ │ ├── Strings.java
│ │ ├── core
│ │ │ ├── ControllerIdentifiers.java
│ │ │ ├── FileBlock.java
│ │ │ ├── HFXClient.java
│ │ │ ├── HFXService.java
│ │ │ ├── ReadFileCall.java
│ │ │ ├── ReceiveFileCall.java
│ │ │ ├── SendFileCall.java
│ │ │ ├── SpeedMonitorThread.java
│ │ │ ├── TransferConnection.java
│ │ │ ├── TransferIdentifiers.java
│ │ │ ├── Utils.java
│ │ │ ├── WriteFileCall.java
│ │ │ ├── bean
│ │ │ │ ├── Directory.java
│ │ │ │ ├── RemoteFile.java
│ │ │ │ ├── ServerNetInterface.java
│ │ │ │ └── TrafficInfo.java
│ │ │ └── callback
│ │ │ │ ├── ClientCallBack.java
│ │ │ │ ├── ConnectServerCallback.java
│ │ │ │ └── TransferFileCallback.java
│ │ └── jdkcore
│ │ │ ├── JdkHFXClient.java
│ │ │ ├── JdkReadFileCall.java
│ │ │ └── JdkWriteFileCall.java
│ │ └── nio
│ │ └── DataByteChannel.java
├── start.c
└── start.exe
├── IMG_20241125_235527.jpg
├── LICENSE.txt
├── PixPin_2024-04-15_20-42-19.png
├── PixPin_2024-04-15_20-45-49.png
├── README.md
├── Screenshot_2024-10-13-13-20-59-747_top.weixiansen574.hybridfilexfer.jpg
├── Screenshot_2024-10-13-13-21-20-325_top.weixiansen574.hybridfilexfer.jpg
├── Screenshot_2024-10-13-13-59-51-358_top.weixiansen574.hybridfilexfer.jpg
├── Screenshot_2024-10-13-14-00-12-221_top.weixiansen574.hybridfilexfer.jpg
├── Screenshot_2024-10-13-14-16-19-518_top.weixiansen574.hybridfilexfer.jpg
├── Screenshot_2024-10-13-14-16-22-997_top.weixiansen574.hybridfilexfer.jpg
├── Screenshot_2024-10-13-14-20-12-558_top.weixiansen574.hybridfilexfer.jpg
├── script
├── USB-forward.bat
├── USB-forward.sh
├── USB-forward_中文.bat
├── launch-android-app.bat
├── start-by-adb.bat
└── start-by-network.bat
├── 手机对传.jpg
├── 赞助名单.md
└── 飞机杯社区(迫真).svg
/1706328825823.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/1706328825823.jpg
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/.name:
--------------------------------------------------------------------------------
1 | HybridFileXfer
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /release
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | namespace 'top.weixiansen574.hybridfilexfer'
7 | compileSdk 34
8 |
9 | defaultConfig {
10 | //applicationId "com.antutu.ABenchMark" //改成此包名提升传输速度😆
11 | applicationId "top.weixiansen574.hybridfilexfer"
12 | minSdk 24
13 | targetSdk 34
14 | versionCode 300
15 | versionName "3.0.0 - beta"
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | ndk {
18 | abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"// 指定目标 CPU 架构
19 | }
20 | }
21 |
22 | externalNativeBuild {
23 | cmake {
24 | path "src/main/cpp/CMakeLists.txt" // 指定 CMakeLists.txt 位置
25 | }
26 | }
27 |
28 | buildFeatures {
29 | viewBinding true
30 | buildConfig = true
31 | aidl = true
32 | }
33 |
34 | buildTypes {
35 | release {
36 | minifyEnabled true
37 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
38 | }
39 | }
40 | compileOptions {
41 | sourceCompatibility JavaVersion.VERSION_1_8
42 | targetCompatibility JavaVersion.VERSION_1_8
43 | }
44 | }
45 |
46 | dependencies {
47 | /*implementation 'androidx.appcompat:appcompat:1.7.0'*/
48 | implementation 'com.google.android.material:material:1.12.0'
49 | implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
50 | implementation 'androidx.appcompat:appcompat:1.7.0'
51 | testImplementation 'junit:junit:4.13.2'
52 | androidTestImplementation 'androidx.test.ext:junit:1.2.1'
53 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
54 | implementation "dev.rikka.shizuku:api:13.1.5"
55 | implementation "dev.rikka.shizuku:provider:13.1.5"
56 | implementation "io.github.l4digital:fastscroll:2.1.0"
57 | }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 | -dontobfuscate
23 | -keep class top.weixiansen574.** { *; }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/androidTest/java/top/weixiansen574/hybridfilexfer2/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer2;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("top.weixainsen574.hybridfilexfer2", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
24 |
27 |
28 |
32 |
33 |
34 |
41 |
42 |
46 |
52 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/aidl/top/weixiansen574/hybridfilexfer/aidl/IIOService.aidl:
--------------------------------------------------------------------------------
1 | // IIOService.aidl
2 | package top.weixiansen574.hybridfilexfer.aidl;
3 |
4 | import top.weixiansen574.hybridfilexfer.aidl.ParcelableRemoteFile;
5 |
6 | interface IIOService {
7 | ParcelFileDescriptor createAndOpenWriteableFile(String path, long length) = 1;
8 | String createParentDirIfNotExists(String path) = 12;
9 | boolean setFileLastModified(String path, long time) = 5;
10 | ParcelFileDescriptor openReadableFile(String path) = 2;
11 | String tryMkdirs(String path) = 13;
12 | int[] listFiles(String path) = 3;
13 | List getAndRemoveFileListSlice(int sliceId) = 4;
14 | boolean deleteFile(String path) = 6;
15 | boolean fileExists(String path) = 7;
16 | boolean appendAndMkdirs(String parent, String child) = 8;
17 | boolean mkdirs(String path) = 9;
18 | boolean isFile(String path) = 10;
19 | String getFileParent(String path) = 11;
20 | void destroy() = 16777114;
21 | }
22 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/aidl/top/weixiansen574/hybridfilexfer/aidl/ParcelableRemoteFile.aidl:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.aidl;
2 |
3 | parcelable ParcelableRemoteFile;
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | project("hybridfilexfer")
4 |
5 | add_library(native-memory SHARED native-memory.cpp)
6 |
7 | find_library(log-lib log)
8 |
9 | target_link_libraries(native-memory
10 | android
11 | log)
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/cpp/native-memory.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #define LOG_TAG "JNI_MEMORY"
6 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
7 | //我不会c++,代码由ChatGPT生成
8 | extern "C"
9 | JNIEXPORT jobject JNICALL
10 | Java_top_weixiansen574_hybridfilexfer_NativeMemory_allocateLargeBuffer(JNIEnv *env, jclass clazz,
11 | jint size) {
12 | void *buffer = malloc(size);
13 | if (!buffer) {
14 | LOGE("malloc failed! Requested size: %d", size);
15 | return nullptr;
16 | }
17 | return env->NewDirectByteBuffer(buffer, size);
18 | }
19 |
20 | extern "C"
21 | JNIEXPORT void JNICALL
22 | Java_top_weixiansen574_hybridfilexfer_NativeMemory_freeBuffer(JNIEnv *env, jclass clazz,
23 | jobject byteBuffer) {
24 | void *buffer = env->GetDirectBufferAddress(byteBuffer);
25 | if (buffer) {
26 | free(buffer);
27 | //LOGE("Buffer freed successfully");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/async/BackstageTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.async;
2 |
3 | import java.lang.reflect.InvocationHandler;
4 | import java.lang.reflect.InvocationTargetException;
5 | import java.lang.reflect.Method;
6 | import java.lang.reflect.Proxy;
7 | import java.util.ArrayList;
8 | import java.util.Arrays;
9 | import java.util.LinkedList;
10 | import java.util.List;
11 |
12 |
13 | public abstract class BackstageTask implements Runnable{
14 | private final T uiHandler;
15 | private boolean executed = false;
16 | private boolean isComplete = false;
17 | public BackstageTask(T uiHandler) {
18 | this.uiHandler = uiHandler;
19 | }
20 |
21 | protected abstract void onStart(T eventHandlerProxy) throws Throwable;
22 |
23 | protected void onError(Throwable th){}
24 |
25 | protected void onComplete(){}
26 |
27 | @SuppressWarnings("unchecked")
28 | @Override
29 | public void run() {
30 | List> interfaces = new LinkedList<>();
31 | Class> clazz = uiHandler.getClass();
32 | while (clazz != null && clazz != Object.class) {
33 | interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
34 | clazz = clazz.getSuperclass();
35 | }
36 | T proxyInstance = (T) Proxy.newProxyInstance(uiHandler.getClass().getClassLoader(),
37 | interfaces.toArray(new Class[0]),
38 | new EvProxyHandler(uiHandler));
39 | try {
40 | onStart(proxyInstance);
41 | onComplete();
42 | TaskManger.postOnUiThread(uiHandler::onComplete);
43 | isComplete = true;
44 | } catch (Throwable e) {
45 | e.printStackTrace();
46 | onError(e);
47 | TaskManger.postOnUiThread(() -> uiHandler.onError(e));
48 | }
49 | }
50 |
51 |
52 | public synchronized void execute() {
53 | if (executed){
54 | throw new RuntimeException("Task has been executed");
55 | }
56 | executed = true;
57 | TaskManger.start(this);
58 | }
59 |
60 | public boolean isExecuted() {
61 | return executed;
62 | }
63 |
64 | public boolean isComplete() {
65 | return isComplete;
66 | }
67 |
68 | public static class EvProxyHandler implements InvocationHandler {
69 | Object evHandler;
70 |
71 | public EvProxyHandler(Object evHandler) {
72 | this.evHandler = evHandler;
73 | }
74 |
75 | @Override
76 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
77 | if (method.getDeclaringClass() == Object.class){
78 | return method.invoke(proxy,args);
79 | }
80 | TaskManger.postOnUiThread(() -> {
81 | try {
82 | method.invoke(evHandler,args);
83 | } catch (IllegalAccessException | InvocationTargetException e) {
84 | throw new RuntimeException(e);
85 | }
86 | });
87 | return null;
88 | }
89 | }
90 |
91 | public interface BaseEventHandler{
92 | default void onError(Throwable th) {
93 | throw new RuntimeException(th);
94 | }
95 |
96 | default void onComplete() {
97 | }
98 | }
99 |
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/async/TaskManger.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.async;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | public class TaskManger {
7 | private static volatile Handler mainThreadHandler;
8 | private static Handler getUiThreadHandler() {
9 | if (mainThreadHandler == null) {
10 | synchronized (TaskManger.class) {
11 | if (mainThreadHandler == null) {
12 | mainThreadHandler = new Handler(Looper.getMainLooper());
13 | }
14 | }
15 | }
16 | return mainThreadHandler;
17 | }
18 |
19 | public static void postOnUiThread(Runnable runnable) {
20 | getUiThreadHandler().post(runnable);
21 | }
22 | public static void start(Runnable runnable){
23 | Thread thread = new Thread(runnable);
24 | thread.setName(runnable.getClass().getSimpleName());
25 | thread.start();
26 | }
27 | public static void execute(BackstageTask> backstageTask){
28 | start(backstageTask);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/Config.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | public class Config {
7 | public static final int MODE_NORMAL = 0;
8 | public static final int MODE_ROOT = 1;
9 | private static Config instance;
10 | SharedPreferences preferences;
11 |
12 | public Config(SharedPreferences preferences) {
13 | this.preferences = preferences;
14 | }
15 |
16 | public static synchronized Config getInstance(Context context) {
17 | if (instance == null){
18 | instance = new Config(context.getApplicationContext().getSharedPreferences("config",Context.MODE_PRIVATE));
19 | }
20 | return instance;
21 | }
22 |
23 | public int getMode(){
24 | return preferences.getInt("mode",MODE_NORMAL);
25 | }
26 |
27 | public void setMode(int mode){
28 | preferences.edit().putInt("mode",mode).apply();
29 | }
30 |
31 | public int getServerPort() {
32 | return 5740;
33 | }
34 |
35 | public int getLocalBufferCount() {
36 | return preferences.getInt("local_buffer_count",256);
37 | }
38 |
39 | public void setLocalBufferCount(int count){
40 | preferences.edit().putInt("local_buffer_count",count).apply();
41 | }
42 |
43 | public int getRemoteBufferCount() {
44 | return preferences.getInt("remote_buffer_count",512);
45 | }
46 |
47 | public void setRemoteBufferCount(int count){
48 | preferences.edit().putInt("remote_buffer_count",count).apply();
49 | }
50 |
51 | public void setClientIOMode(int mode){
52 | preferences.edit().putInt("client_io_mode",mode).apply();
53 | }
54 |
55 | public int getClientIOMode(){
56 | return preferences.getInt("client_io_mode", MODE_NORMAL);
57 | }
58 |
59 | public void setConnectServerControllerIp(String ip){
60 | preferences.edit().putString("connect_server_controller_ip",ip).apply();
61 | }
62 |
63 | public String getConnectServerControllerIp(){
64 | return preferences.getString("connect_server_controller_ip","");
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/ConfigDB.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.ContentValues;
5 | import android.content.Context;
6 | import android.database.Cursor;
7 | import android.database.sqlite.SQLiteDatabase;
8 | import android.database.sqlite.SQLiteOpenHelper;
9 |
10 | import androidx.annotation.Nullable;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | import top.weixiansen574.hybridfilexfer.bean.BookMark;
16 |
17 | @SuppressLint("Range")
18 | public class ConfigDB extends SQLiteOpenHelper {
19 | public static final int VERSION = 1;
20 | private static ConfigDB instance;
21 | private ConfigDB(@Nullable Context context) {
22 | super(context, "config", null, VERSION);
23 | }
24 |
25 | public synchronized static ConfigDB getInstance(Context context){
26 | if (instance == null){
27 | instance = new ConfigDB(context.getApplicationContext());
28 | }
29 | return instance;
30 | }
31 |
32 | @Override
33 | public void onCreate(SQLiteDatabase db) {
34 | db.execSQL("CREATE TABLE local_dir_bookmarks (\n" +
35 | " id INTEGER PRIMARY KEY AUTOINCREMENT\n" +
36 | " NOT NULL,\n" +
37 | " path TEXT NOT NULL\n" +
38 | " UNIQUE\n" +
39 | ");");
40 | db.execSQL("CREATE TABLE remote_dir_bookmarks (\n" +
41 | " id INTEGER PRIMARY KEY AUTOINCREMENT\n" +
42 | " NOT NULL,\n" +
43 | " path TEXT UNIQUE\n" +
44 | " NOT NULL\n" +
45 | ");");
46 | }
47 |
48 | @Override
49 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
50 |
51 | }
52 |
53 | public long addLocalBookmark(String path) {
54 | ContentValues cv = new ContentValues();
55 | cv.put("path", path);
56 | return getWritableDatabase()
57 | .insert("local_dir_bookmarks", null, cv);
58 |
59 | }
60 |
61 | public long addRemoteBookmark(String path) {
62 | ContentValues cv = new ContentValues();
63 | cv.put("path", path);
64 | return getWritableDatabase()
65 | .insert("remote_dir_bookmarks", null, cv);
66 | }
67 |
68 | public boolean checkLocalBookmarkExists(String path) {
69 | Cursor cursor = getReadableDatabase()
70 | .rawQuery("SELECT * FROM local_dir_bookmarks WHERE path = ?", new String[]{path});
71 | boolean exists = cursor.moveToFirst();
72 | cursor.close();
73 | return exists;
74 | }
75 |
76 | public boolean checkRemoteBookmarkExists(String path) {
77 | Cursor cursor = getReadableDatabase()
78 | .rawQuery("SELECT * FROM remote_dir_bookmarks WHERE path = ?", new String[]{path});
79 | boolean exists = cursor.moveToFirst();
80 | cursor.close();
81 | return exists;
82 | }
83 |
84 |
85 | public long removeLocalBookmark(int id) {
86 | return getWritableDatabase()
87 | .delete("local_dir_bookmarks", "id = ?", new String[]{String.valueOf(id)});
88 | }
89 |
90 | public long removeRemoteBookmark(int id) {
91 | return getWritableDatabase()
92 | .delete("remote_dir_bookmarks", "id = ?", new String[]{String.valueOf(id)});
93 | }
94 |
95 |
96 | public List getAllLocalBookmark() {
97 | return getAllBookmarks("local_dir_bookmarks");
98 | }
99 |
100 | public List getAllRemoteBookmark() {
101 | return getAllBookmarks("remote_dir_bookmarks");
102 | }
103 |
104 | private List getAllBookmarks(String tableName){
105 | Cursor cursor = getReadableDatabase().rawQuery("SELECT * FROM "+tableName, null);
106 | List bookmarks = new ArrayList<>(cursor.getCount());
107 | while (cursor.moveToNext()) {
108 | bookmarks.add(
109 | new BookMark(
110 | cursor.getInt(cursor.getColumnIndex("id")),
111 | cursor.getString(cursor.getColumnIndex("path"))
112 | ));
113 | }
114 | cursor.close();
115 | return bookmarks;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/IOService.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer;
2 |
3 | import android.app.Service;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.IBinder;
8 |
9 | import rikka.shizuku.Shizuku;
10 |
11 | public class IOService extends Service {
12 | private IOServiceImpl service;
13 | private static Shizuku.UserServiceArgs userServiceArgs;
14 | public IOService() {
15 | }
16 |
17 | @Override
18 | public IBinder onBind(Intent intent) {
19 | service = new IOServiceImpl();
20 | return service;
21 | }
22 |
23 | @Override
24 | public void onDestroy() {
25 | service.destroy();
26 | }
27 |
28 | public static synchronized Shizuku.UserServiceArgs getUserServiceArgs(Context context){
29 | if (userServiceArgs == null) {
30 | userServiceArgs = new Shizuku.UserServiceArgs(new ComponentName(context, IOServiceImpl.class))
31 | .daemon(true)
32 | .processNameSuffix("IOService")
33 | .debuggable(false)
34 | .version(1);
35 | }
36 | return userServiceArgs;
37 | }
38 | }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/NativeMemory.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer;
2 |
3 | import java.nio.ByteBuffer;
4 |
5 | /**
6 | * 由于Java层有256M或512M的堆内存大小限制
7 | * ByteBuffer.allocate() 和 ByteBuffer.allocateDirect()
8 | * 都不可以获取共计超过256M或512M的内存。故用JNI分配内存并生成对应ByteBuffer。
9 | */
10 | public class NativeMemory {
11 | static {
12 | System.loadLibrary("native-memory"); // 加载 JNI 库
13 | }
14 |
15 | public static native ByteBuffer allocateLargeBuffer(int size);
16 | public static native void freeBuffer(ByteBuffer buffer);
17 | }
18 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/NetCardIcon.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer;
2 |
3 | public class NetCardIcon {
4 | public static int matchIdForIName(String iName){
5 | if (iName.startsWith("wlan")) {
6 | return R.drawable.wifi;
7 | } else if (iName.equals("USB_ADB")) {
8 | return R.drawable.usb;
9 | } else if (iName.startsWith("rndis")) {
10 | return R.drawable.usb;
11 | } else if (iName.startsWith("bt")) {
12 | return R.drawable.bt;
13 | } else if (iName.startsWith("tun")) {//VPN开的虚拟网卡
14 | return R.drawable.ethernet;
15 | } else {
16 | return R.drawable.ethernet;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/aidl/ParcelableRemoteFile.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.aidl;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import java.io.File;
7 |
8 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
9 |
10 | public class ParcelableRemoteFile extends RemoteFile implements Parcelable {
11 | protected ParcelableRemoteFile(Parcel in) {
12 | super(in.readString(), in.readString(), in.readLong(), in.readLong(), in.readByte() != 0);
13 | }
14 |
15 | public ParcelableRemoteFile(File file) {
16 | super(file);
17 | }
18 |
19 | @Override
20 | public int describeContents() {
21 | return 0;
22 | }
23 |
24 | @Override
25 | public void writeToParcel(Parcel dest, int flags) {
26 | dest.writeString(this.name);
27 | dest.writeString(this.path);
28 | dest.writeLong(this.lastModified);
29 | dest.writeLong(this.size);
30 | dest.writeByte(this.isDirectory ? (byte) 1 : (byte) 0);
31 | }
32 |
33 | public static final Creator CREATOR = new Creator() {
34 | @Override
35 | public ParcelableRemoteFile createFromParcel(Parcel source) {
36 | return new ParcelableRemoteFile(source);
37 | }
38 |
39 | @Override
40 | public ParcelableRemoteFile[] newArray(int size) {
41 | return new ParcelableRemoteFile[size];
42 | }
43 | };
44 | }
45 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/bean/BookMark.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.bean;
2 |
3 | public class BookMark {
4 | public final int id;
5 | public final String path;
6 |
7 | public BookMark(int id, String path) {
8 | this.id = id;
9 | this.path = path;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | public class ControllerIdentifiers {
4 | public static final short SHUTDOWN = 0;
5 | public static final short LIST_FILES = 1;
6 | public static final short DELETE_FILE = 2;
7 | public static final short MKDIR = 3;
8 | public static final short REQUEST_RECEIVE = 10;
9 | public static final short REQUEST_SEND = 11;
10 |
11 | //就让魔法打败魔法吧!
12 | /**
13 | * 禁止转载应用到酷安
14 | * 不许未经授权将本项目爬取到国内平台,点名GitCode,除非你的平台容得下下面的数字😁
15 | */
16 | private static final int 酷安飞机杯 = 8964;
17 | /**
18 | * 你号没了!
19 | * 当然,如果你看到了有人在酷安分享本软件,请拿此内容进行举报攻击,让他狠狠的享受以下内容!
20 | * 你的账号【___】,存在发布涉政信息的违规行为,已禁止访问
21 | */
22 | private static final String 威武小姐姐 = "学“习”通😋";
23 |
24 | }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/FileBlock.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.io.File;
4 | import java.nio.ByteBuffer;
5 |
6 | public class FileBlock implements Comparable {
7 | public static final int BLOCK_SIZE = 1024*1024;//1MB
8 |
9 | public final boolean isFile;
10 | public final int fileIndex;
11 | public final String path;
12 | public final long lastModified;
13 | public final long totalSize;
14 | public final int index;
15 | public final ByteBuffer data;
16 |
17 | public FileBlock(boolean isFile, int fileIndex, String path, long lastModified, long totalSize, int index, ByteBuffer data) {
18 | this.isFile = isFile;
19 | this.fileIndex = fileIndex;
20 | this.path = path;
21 | this.lastModified = lastModified;
22 | this.totalSize = totalSize;
23 | this.index = index;
24 | this.data = data;
25 | }
26 |
27 | public long getStartPosition(){
28 | return BLOCK_SIZE * ((long) index);
29 | }
30 |
31 | public long calcBlockCount(){
32 | return totalSize / BLOCK_SIZE + 1;
33 | }
34 |
35 | public boolean isFile(){
36 | return isFile;
37 | }
38 |
39 | public boolean isDirectory(){
40 | return !isFile;
41 | }
42 |
43 | public int getLength(){
44 | if (data == null){
45 | return -1;
46 | }
47 | return data.position();
48 | }
49 |
50 | @Override
51 | public int compareTo(FileBlock other) {
52 | if (this.fileIndex != other.fileIndex) {
53 | return Integer.compare(this.fileIndex, other.fileIndex);
54 | }
55 | // 如果 nameIndex 相同,比较 index
56 | return Integer.compare(this.index, other.index);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/SendFileCall.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.util.concurrent.Callable;
4 |
5 | import top.weixiansen574.hybridfilexfer.core.callback.TransferFileCallback;
6 | import top.weixiansen574.nio.DataByteChannel;
7 |
8 | public class SendFileCall implements Callable {
9 | private final ReadFileCall readFileCall;
10 | private final DataByteChannel channel;
11 | private final TransferConnection connection;
12 | private final TransferFileCallback callback;
13 |
14 | public SendFileCall(ReadFileCall readFileCall, TransferConnection connection, TransferFileCallback callback) {
15 | this.readFileCall = readFileCall;
16 | this.connection = connection;
17 | this.channel = connection.channel;
18 | this.callback = callback;
19 | connection.resetTotalTrafficInfo();
20 | }
21 |
22 | @Override
23 | public Void call() throws Exception {
24 | FileBlock fileBlock = null;
25 | try {
26 | long startTime = System.currentTimeMillis();
27 | while (true) {
28 | fileBlock = readFileCall.takeBlock();
29 | //-1为特殊块
30 | if (fileBlock.fileIndex == -1) {
31 | if (fileBlock == ReadFileCall.END_POINT) {
32 | channel.writeShort(TransferIdentifiers.EOF);
33 | callback.onChannelComplete(connection.iName,
34 | connection.getTotalTraffic().uploadTraffic,
35 | System.currentTimeMillis() - startTime);
36 | } else if (fileBlock == ReadFileCall.INTERRUPT) {
37 | channel.writeShort(TransferIdentifiers.END_OF_INTERRUPTED);
38 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_INTERRUPT, null);
39 | } else if (fileBlock == ReadFileCall.READ_ERROR) {
40 | channel.writeShort(TransferIdentifiers.END_OF_READ_ERROR);
41 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_READ_ERROR, null);
42 | } else if (fileBlock == ReadFileCall.WRITE_ERROR) {
43 | channel.writeShort(TransferIdentifiers.END_OF_WRITE_ERROR);
44 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_WRITE_ERROR, null);
45 | }
46 | break;
47 | }
48 | channel.writeShort(fileBlock.isFile ? TransferIdentifiers.FILE :
49 | TransferIdentifiers.FOLDER);//是否文件夹
50 | channel.writeInt(fileBlock.fileIndex);
51 | channel.writeUTF(fileBlock.path);//路径
52 | channel.writeLong(fileBlock.lastModified);//修改日期
53 | if (!fileBlock.isFile) continue;
54 | channel.writeLong(fileBlock.totalSize);//总大小
55 | channel.writeInt(fileBlock.index);//索引
56 | channel.writeInt(fileBlock.getLength());//单块的长度
57 |
58 | callback.onFileUploading(connection.iName, fileBlock.path,
59 | fileBlock.getStartPosition() + fileBlock.getLength(),
60 | fileBlock.totalSize);
61 |
62 | fileBlock.data.flip();
63 | channel.write(fileBlock.data);
64 | readFileCall.recycleBuffer(fileBlock.data);
65 | connection.addUploadedBytes(fileBlock.getLength());
66 | }
67 | } catch (Exception e) {
68 | //若发生异常,通知其他传输通道,停止传输
69 | if (fileBlock != null){
70 | //回收文件分块的ByteBuffer,否则导致这个Buffer免费了
71 | readFileCall.recycleBuffer(fileBlock.data);
72 | }
73 | readFileCall.shutdownByConnectionBreak();
74 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_EXCEPTION, e.toString());
75 | throw e;
76 | }
77 | return null;
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/SpeedMonitorThread.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import top.weixiansen574.hybridfilexfer.core.TransferConnection;
7 | import top.weixiansen574.hybridfilexfer.core.bean.TrafficInfo;
8 | import top.weixiansen574.hybridfilexfer.core.callback.TransferFileCallback;
9 |
10 | public class SpeedMonitorThread extends Thread {
11 | private boolean isRun = true;
12 | private final List connections;
13 | private final TransferFileCallback callback;
14 |
15 | public SpeedMonitorThread(List connections, TransferFileCallback callback) {
16 | this.connections = connections;
17 | this.callback = callback;
18 | }
19 |
20 | @Override
21 | @SuppressWarnings("BusyWait")
22 | public void run() {
23 | while (isRun){
24 | try {
25 | Thread.sleep(1000);
26 | } catch (InterruptedException e) {
27 | break;
28 | }
29 | List trafficInfoList = new ArrayList<>();
30 | for (TransferConnection channel : connections) {
31 | trafficInfoList.add(channel.resetCurrentTrafficInfo());
32 | }
33 | callback.onSpeedInfo(trafficInfoList);
34 | }
35 | }
36 |
37 | public void cancel(){
38 | isRun = false;
39 | interrupt();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/TransferConnection.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.io.IOException;
4 |
5 | import top.weixiansen574.hybridfilexfer.core.bean.TrafficInfo;
6 | import top.weixiansen574.nio.DataByteChannel;
7 |
8 | public class TransferConnection {
9 | public final String iName;
10 | private TrafficInfo currentTraffic;
11 | private TrafficInfo totalTraffic;
12 | public final DataByteChannel channel;
13 |
14 | public TransferConnection(String iName, DataByteChannel channel) throws IOException {
15 | this.iName = iName;
16 | this.channel = channel;
17 | currentTraffic = new TrafficInfo();
18 | totalTraffic = new TrafficInfo();
19 | }
20 |
21 | public synchronized void addUploadedBytes(long byteCount) {
22 | currentTraffic.uploadTraffic += byteCount;
23 | totalTraffic.uploadTraffic += byteCount;
24 | }
25 |
26 | public synchronized void addDownloadedBytes(long byteCount) {
27 | currentTraffic.downloadTraffic += byteCount;
28 | totalTraffic.downloadTraffic += byteCount;
29 | }
30 |
31 | public synchronized TrafficInfo resetCurrentTrafficInfo() {
32 | TrafficInfo info = currentTraffic;
33 | currentTraffic = new TrafficInfo(iName);
34 | return info;
35 | }
36 |
37 | public synchronized TrafficInfo resetTotalTrafficInfo() {
38 | TrafficInfo info = totalTraffic;
39 | totalTraffic = new TrafficInfo(iName);
40 | return info;
41 | }
42 |
43 | public synchronized TrafficInfo getTotalTraffic(){
44 | return totalTraffic;
45 | }
46 |
47 | public void close() throws IOException {
48 | channel.close();
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | public class TransferIdentifiers {
4 | public static final short END_POINT = -1;
5 | public static final short FILE = 0;
6 | public static final short FOLDER = 1;
7 | public static final short FILE_SLICE = 2;
8 | public static final short EOF = 3;
9 | public static final short END_OF_INTERRUPTED = 4;
10 | public static final short END_OF_READ_ERROR = 5;
11 | public static final short END_OF_WRITE_ERROR = 6;
12 | }
13 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/Utils.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.io.File;
4 | import java.text.SimpleDateFormat;
5 | import java.util.ArrayList;
6 | import java.util.Date;
7 | import java.util.List;
8 | import java.util.Locale;
9 |
10 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
11 |
12 | public class Utils {
13 | public static final String ILLEGAL_CHARACTERS = "<>:\"/\\|?*";
14 |
15 | public static void sortFiles(List fileList) {
16 | // 使用Comparator自定义比较规则
17 | fileList.sort((f1, f2) -> {
18 | // 文件夹优先于文件
19 | if (f1.isDirectory() && !f2.isDirectory()) {
20 | return -1;
21 | } else if (!f1.isDirectory() && f2.isDirectory()) {
22 | return 1;
23 | } else {
24 | // 如果类型相同,则按名称排序
25 | return f1.getName().compareTo(f2.getName());
26 | }
27 | });
28 | }
29 |
30 | public static String formatSpeed(long bytesPerSecond) {
31 | if (bytesPerSecond < 1024) {
32 | return bytesPerSecond + "B/s";
33 | }
34 | if (bytesPerSecond < 1024 * 1024) {
35 | return String.format(Locale.getDefault(), "%.2fKB/s", bytesPerSecond / 1024.0);
36 | }
37 | return String.format(Locale.getDefault(), "%.2fMB/s", bytesPerSecond / (1024.0 * 1024.0));
38 | }
39 |
40 | public static String formatDateTime(long milliseconds) {
41 | //格式化为年-月-日 时:分
42 | return new SimpleDateFormat("yy-MM-dd HH:mm", Locale.getDefault()).format(new Date(milliseconds));
43 | }
44 |
45 | /**
46 | * 格式化毫秒数为指定的时间格式。
47 | *
48 | * @param milliseconds 输入的毫秒数
49 | * @return 格式化后的时间字符串
50 | */
51 | public static String formatTime(long milliseconds) {
52 | if (milliseconds < 0) {
53 | throw new IllegalArgumentException("毫秒数不能为负数");
54 | }
55 |
56 | if (milliseconds < 1000) {
57 | return milliseconds + "ms";
58 | }
59 |
60 | long totalSeconds = milliseconds / 1000;
61 | long hours = totalSeconds / 3600;
62 | long minutes = (totalSeconds % 3600) / 60;
63 | long seconds = totalSeconds % 60;
64 |
65 | if (hours == 0) {
66 | return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
67 | } else {
68 | return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
69 | }
70 | }
71 |
72 | public static String formatFileSize(long size) {
73 | if (size < 1024) {
74 | return size + "B";
75 | }
76 | if (size < 1024 * 1024) {
77 | return String.format(Locale.getDefault(), "%.2fKB", size / 1024.0);
78 | }
79 | if (size < 1024 * 1024 * 1024) {
80 | return String.format(Locale.getDefault(), "%.2fMB", size / (1024.0 * 1024.0));
81 | }
82 | return String.format(Locale.getDefault(), "%.2fGB", size / (1024.0 * 1024.0 * 1024.0));
83 | }
84 |
85 | public static boolean containsIllegalCharacters(String text) {
86 | for (char c : ILLEGAL_CHARACTERS.toCharArray()) {
87 | if (text.indexOf(c) >= 0) {
88 | return true; // 如果找到非法字符,返回 true
89 | }
90 | }
91 | return false; // 如果没有找到非法字符,返回 false
92 | }
93 |
94 | public static List listRemoteFiles(String path){
95 | File[] files = new File(path).listFiles();
96 | if (files == null) {
97 | return null;
98 | }
99 | ArrayList remoteFiles = new ArrayList<>(files.length);
100 | for (File file : files) {
101 | remoteFiles.add(new RemoteFile(file));
102 | }
103 | return remoteFiles;
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.bean;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import java.io.File;
6 |
7 | public class RemoteFile {
8 | protected final String name;
9 | protected final String path;
10 | protected final long lastModified;
11 | protected final long size;
12 | protected final boolean isDirectory;
13 | //public final String name;
14 | //public final String path;
15 | //public final long lastModified;
16 | //public final long size;
17 | //public final boolean isDirectory;
18 |
19 | public RemoteFile(File file) {
20 | this.path = file.getPath();
21 | this.isDirectory = file.isDirectory();
22 | this.name = file.getName();
23 | this.lastModified = file.lastModified();
24 | this.size = file.length();
25 | }
26 |
27 | public RemoteFile(String name, String path, long lastModified, long size, boolean isDirectory){
28 | this.name = name;
29 | this.path = path;
30 | this.lastModified = lastModified;
31 | this.size = size;
32 | this.isDirectory = isDirectory;
33 | }
34 |
35 | public RemoteFile(RemoteFile file){
36 | this.name = file.name;
37 | this.path = file.path;
38 | this.lastModified = file.lastModified;
39 | this.size = file.size;
40 | this.isDirectory = file.isDirectory;
41 | }
42 |
43 |
44 | @NotNull
45 | @Override
46 | public String toString() {
47 | return "RemoteFile{" +
48 | "path='" + path + '\'' +
49 | ", isDirectory=" + isDirectory +
50 | '}';
51 | }
52 |
53 | public String getPath() {
54 | return path;
55 | }
56 |
57 | public boolean isDirectory() {
58 | return isDirectory;
59 | }
60 |
61 | public String getName() {
62 | return name;
63 | }
64 |
65 | public long lastModified() {
66 | return lastModified;
67 | }
68 |
69 | public long getSize() {
70 | return size;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/bean/ServerNetInterface.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.bean;
2 |
3 |
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.net.InetAddress;
7 |
8 | public class ServerNetInterface{
9 | public final String name;
10 | public final InetAddress address;
11 | public final InetAddress clientBindAddress;
12 |
13 | public ServerNetInterface(String name, InetAddress address, InetAddress clientBindAddress) {
14 | this.name = name;
15 | this.address = address;
16 | this.clientBindAddress = clientBindAddress;
17 | }
18 |
19 |
20 | @NotNull
21 | @Override
22 | public String toString() {
23 | return "ServerNetInterface{" +
24 | "name='" + name + '\'' +
25 | ", address=" + address +
26 | ", clientBindAddress=" + clientBindAddress +
27 | '}';
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/bean/TrafficInfo.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.bean;
2 |
3 | public class TrafficInfo {
4 | public String iName;
5 | public long uploadTraffic;
6 | public long downloadTraffic;
7 |
8 | public TrafficInfo(String iName, long uploadTraffic, long downloadTraffic) {
9 | this.iName = iName;
10 | this.uploadTraffic = uploadTraffic;
11 | this.downloadTraffic = downloadTraffic;
12 | }
13 | public TrafficInfo() {
14 | }
15 | public TrafficInfo(String iName) {
16 | this.iName = iName;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/callback/ClientCallBack.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.callback;
2 |
3 | public interface ClientCallBack extends TransferFileCallback {
4 | void onReceiving();
5 | void onSending();
6 | void onExit();
7 | }
8 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/callback/ConnectServerCallback.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.callback;
2 |
3 | import java.net.InetAddress;
4 | import java.util.List;
5 |
6 | public interface ConnectServerCallback {
7 | void onConnectingControlChannel(String address, int port);
8 |
9 | void onVersionMismatch(int localVersion, int remoteVersion);
10 |
11 | void onConnectControlFailed();
12 |
13 | void onConnectingTransferChannel(
14 | String name,
15 | InetAddress inetAddress,
16 | InetAddress bindAddress);
17 |
18 | void onConnectTransferChannelFailed(String name, InetAddress inetAddress, Exception e);
19 |
20 | void onOOM(
21 | int createdBuffers,
22 | int requiredBuffers,
23 | long maxMemoryMB,
24 | String osArch);
25 |
26 | void onRemoteOOM();
27 |
28 | void onConnectSuccess(List channelNames);
29 | }
30 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/core/callback/TransferFileCallback.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.callback;
2 |
3 | import java.util.List;
4 |
5 | import top.weixiansen574.hybridfilexfer.core.bean.TrafficInfo;
6 |
7 | public interface TransferFileCallback {
8 | int ERROR_TYPE_EXCEPTION = 1;
9 | int ERROR_TYPE_INTERRUPT = 2;
10 | int ERROR_TYPE_READ_ERROR = 3;
11 | int ERROR_TYPE_WRITE_ERROR = 4;
12 |
13 | void onFileUploading(String iName, String path, long targetSize, long totalSize);
14 |
15 | void onFileDownloading(String iName, String path, long targetSize, long totalSize);
16 |
17 | void onSpeedInfo(List trafficInfoList);
18 |
19 | void onChannelComplete(String iName, long traffic, long time);
20 |
21 | void onChannelError(String iName, int errorType, String message);//异常信息 or 断开
22 |
23 | void onReadFileError(String message);
24 |
25 | void onWriteFileError(String message);
26 |
27 | void onComplete(boolean isUpload,long traffic, long time);
28 |
29 | //传输通道有其中一个断开时
30 | void onIncomplete();
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/droidcore/DisconnectTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.droidcore;
2 |
3 | import java.io.IOException;
4 | import java.nio.ByteBuffer;
5 |
6 | import top.weixiansen574.async.BackstageTask;
7 | import top.weixiansen574.hybridfilexfer.NativeMemory;
8 | import top.weixiansen574.hybridfilexfer.core.ControllerIdentifiers;
9 | import top.weixiansen574.hybridfilexfer.core.TransferConnection;
10 |
11 | public class DisconnectTask extends BackstageTask {
12 | private final HFXServer server;
13 | public DisconnectTask(BaseEventHandler uiHandler, HFXServer server) {
14 | super(uiHandler);
15 | this.server = server;
16 | }
17 |
18 | @Override
19 | protected void onStart(BaseEventHandler eventHandlerProxy) throws Throwable {
20 | server.disconnect();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/droidcore/DroidHFXClient.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.droidcore;
2 |
3 | import android.app.ActivityManager;
4 | import android.content.Context;
5 |
6 | import java.nio.ByteBuffer;
7 | import java.util.List;
8 | import java.util.concurrent.LinkedBlockingDeque;
9 |
10 | import top.weixiansen574.hybridfilexfer.NativeMemory;
11 | import top.weixiansen574.hybridfilexfer.aidl.IIOService;
12 | import top.weixiansen574.hybridfilexfer.core.HFXClient;
13 | import top.weixiansen574.hybridfilexfer.core.ReadFileCall;
14 | import top.weixiansen574.hybridfilexfer.core.WriteFileCall;
15 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
16 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
17 |
18 | public class DroidHFXClient extends HFXClient {
19 | private final IIOService iioService;
20 | private final Context context;
21 | public DroidHFXClient(String serverControllerAddress, int serverPort,String homeDir, IIOService iioService, Context context) {
22 | super(serverControllerAddress, serverPort,homeDir);
23 | this.iioService = iioService;
24 | this.context = context;
25 | }
26 |
27 | @Override
28 | public ByteBuffer createBuffer(int size) {
29 | return NativeMemory.allocateLargeBuffer(size);
30 | }
31 |
32 | @Override
33 | public long getAvailableMemoryMB() {
34 | ActivityManager activityManager = context.getSystemService(ActivityManager.class);
35 | ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
36 | activityManager.getMemoryInfo(memoryInfo);
37 |
38 | long totalMemory = memoryInfo.totalMem;
39 |
40 | long availableMemory = memoryInfo.availMem;
41 |
42 | long totalMemoryMB = totalMemory / (1024 * 1024);
43 | long availableMemoryMB = availableMemory / (1024 * 1024);
44 |
45 | return (long) (availableMemoryMB - (totalMemoryMB * 0.05));
46 | }
47 |
48 | @Override
49 | protected boolean deleteLocalFile(String path) throws Exception {
50 | return iioService.deleteFile(path);
51 | }
52 |
53 | @Override
54 | protected boolean mkdir(String parent, String child) throws Exception {
55 | return iioService.appendAndMkdirs(parent,child);
56 | }
57 |
58 | @Override
59 | protected List listFiles(String path) throws Exception {
60 | return HFXServer.listLocalFiles(iioService,path);
61 | }
62 |
63 | @Override
64 | protected WriteFileCall createWriteFileCall(LinkedBlockingDeque buffers, int dequeCount) {
65 | return new DroidWriteFileCall(buffers,dequeCount,iioService);
66 | }
67 |
68 | @Override
69 | protected ReadFileCall createReadFileCall(LinkedBlockingDeque buffers, List files, Directory localDir, Directory remoteDir, int operateThreadCount) {
70 | return new DroidReadFileCall(iioService,buffers,files,localDir,remoteDir,operateThreadCount);
71 | }
72 |
73 | public void freeBuffers(){
74 | for (ByteBuffer buffer : buffers) {
75 | NativeMemory.freeBuffer(buffer);
76 | }
77 | buffers.clear();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/droidcore/DroidReadFileCall.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.droidcore;
2 |
3 | import android.os.ParcelFileDescriptor;
4 |
5 | import java.io.FileInputStream;
6 | import java.nio.ByteBuffer;
7 | import java.nio.channels.FileChannel;
8 | import java.util.List;
9 | import java.util.concurrent.LinkedBlockingDeque;
10 |
11 | import top.weixiansen574.hybridfilexfer.aidl.IIOService;
12 | import top.weixiansen574.hybridfilexfer.core.ReadFileCall;
13 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
14 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
15 |
16 | public class DroidReadFileCall extends ReadFileCall {
17 | private final IIOService ioService;
18 |
19 | private ParcelFileDescriptor pfd;
20 | private FileInputStream fileInputStream;
21 | private FileChannel channel;
22 |
23 | public DroidReadFileCall(IIOService ioService,LinkedBlockingDeque buffers, List files, Directory localDir, Directory remoteDir, int operateThreadCount) {
24 | super(buffers, files, localDir, remoteDir, operateThreadCount);
25 | this.ioService = ioService;
26 | }
27 |
28 | @Override
29 | protected boolean fileExists(String path) throws Exception {
30 | return ioService.fileExists(path);
31 | }
32 |
33 | @Override
34 | protected List listFiles(String path) throws Exception {
35 | return HFXServer.listLocalFiles(ioService,path);
36 | }
37 |
38 | @Override
39 | protected FileChannel openFile(String path) throws Exception {
40 | pfd = ioService.openReadableFile(path);
41 | fileInputStream = new FileInputStream(pfd.getFileDescriptor());
42 | channel = fileInputStream.getChannel();
43 | return channel;
44 | }
45 |
46 | @Override
47 | protected void closeFile() throws Exception {
48 | channel.close();
49 | fileInputStream.close();
50 | pfd.close();
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/droidcore/DroidWriteFileCall.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.droidcore;
2 |
3 | import android.os.ParcelFileDescriptor;
4 |
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.nio.ByteBuffer;
8 | import java.nio.channels.FileChannel;
9 | import java.util.concurrent.LinkedBlockingDeque;
10 |
11 | import top.weixiansen574.hybridfilexfer.aidl.IIOService;
12 | import top.weixiansen574.hybridfilexfer.core.WriteFileCall;
13 |
14 | public class DroidWriteFileCall extends WriteFileCall {
15 | private final IIOService ioService;
16 | private ParcelFileDescriptor pfd;
17 | private FileOutputStream fileOutputStream;
18 | private FileChannel channel;
19 | public DroidWriteFileCall(LinkedBlockingDeque buffers, int dequeCount, IIOService ioService) {
20 | super(buffers, dequeCount);
21 | this.ioService = ioService;
22 | }
23 |
24 | @Override
25 | protected void createParentDirIfNotExists(String path) throws Exception {
26 | String exception = ioService.createParentDirIfNotExists(path);
27 | if (exception != null){
28 | throw new IOException(exception);
29 | }
30 | }
31 |
32 | @Override
33 | protected void tryMkdirs(String path) throws Exception {
34 | String exception = ioService.tryMkdirs(path);
35 | if (exception != null){
36 | throw new IOException(exception);
37 | }
38 | }
39 |
40 | @Override
41 | protected FileChannel createAndOpenFile(String path, long length) throws Exception {
42 | pfd = ioService.createAndOpenWriteableFile(path, length);
43 | fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
44 | channel = fileOutputStream.getChannel();
45 | return channel;
46 | }
47 |
48 | @Override
49 | protected void closeFile() throws Exception {
50 | channel.close();
51 | fileOutputStream.close();
52 | pfd.close();
53 | }
54 |
55 | @Override
56 | protected boolean setFileLastModified(String path, long time) throws Exception {
57 | return ioService.setFileLastModified(path,time);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/droidcore/StartServerTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.droidcore;
2 |
3 | import java.io.IOException;
4 | import java.net.InetSocketAddress;
5 | import java.nio.ByteBuffer;
6 | import java.nio.channels.ServerSocketChannel;
7 | import java.nio.charset.StandardCharsets;
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.List;
11 | import java.util.concurrent.LinkedBlockingDeque;
12 |
13 | import top.weixiansen574.async.BackstageTask;
14 | import top.weixiansen574.hybridfilexfer.NativeMemory;
15 | import top.weixiansen574.hybridfilexfer.core.FileBlock;
16 | import top.weixiansen574.hybridfilexfer.core.TransferConnection;
17 | import top.weixiansen574.hybridfilexfer.core.bean.ServerNetInterface;
18 | import top.weixiansen574.hybridfilexfer.droidcore.callback.StartServerCallback;
19 | import top.weixiansen574.nio.DataByteChannel;
20 |
21 | public class StartServerTask extends BackstageTask {
22 | private final HFXServer server;
23 | private final int port;
24 | private final List interfaceList;
25 | private final int localBufferCount;
26 | private final int remoteBufferCount;
27 |
28 | public StartServerTask(StartServerCallback uiHandler, HFXServer server, int port, List interfaceList, int localBufferCount, int remoteBufferCount) {
29 | super(uiHandler);
30 | this.server = server;
31 | this.port = port;
32 | this.interfaceList = interfaceList;
33 | this.localBufferCount = localBufferCount;
34 | this.remoteBufferCount = remoteBufferCount;
35 | }
36 |
37 | @Override
38 | protected void onStart(StartServerCallback callback) throws Throwable {
39 | server.startServer(port,interfaceList,localBufferCount,remoteBufferCount,callback);
40 | }
41 |
42 | @Override
43 | protected void onError(Throwable th) {
44 | server.close();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/droidcore/callback/StartServerCallback.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.droidcore.callback;
2 |
3 | import top.weixiansen574.async.BackstageTask;
4 |
5 | public interface StartServerCallback extends BackstageTask.BaseEventHandler {
6 | void onBindFailed(int port);
7 | void onStatedServer();
8 | void onAccepted(String name);
9 | void onAcceptFailed(String name);
10 | void onPcOOM();
11 | void onMeOOM(int created, int localBufferCount);
12 | void onConnectSuccess();
13 | }
14 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/listadapter/BookmarkAdapter.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.listadapter;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import androidx.annotation.NonNull;
13 | import androidx.recyclerview.widget.RecyclerView;
14 |
15 | import java.util.List;
16 |
17 | import top.weixiansen574.hybridfilexfer.ConfigDB;
18 | import top.weixiansen574.hybridfilexfer.R;
19 | import top.weixiansen574.hybridfilexfer.bean.BookMark;
20 |
21 |
22 | public class BookmarkAdapter extends RecyclerView.Adapter {
23 | protected Context context;
24 | protected DialogInterface dialog;
25 | protected FileSelectAdapter adapter;
26 | protected List bookMarks;
27 | protected final ConfigDB db;
28 | protected final boolean isRemote;
29 |
30 | public BookmarkAdapter(Context context, DialogInterface dialog, FileSelectAdapter adapter,boolean isRemote) {
31 | this.context = context;
32 | this.dialog = dialog;
33 | this.adapter = adapter;
34 | this.db = ConfigDB.getInstance(context);
35 | this.isRemote = isRemote;
36 | if (isRemote){
37 | bookMarks = db.getAllRemoteBookmark();
38 | } else {
39 | bookMarks = db.getAllLocalBookmark();
40 | }
41 | }
42 |
43 | @NonNull
44 | @Override
45 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
46 | return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_bookmark, parent, false));
47 | }
48 |
49 | @Override
50 | public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
51 | BookMark item = bookMarks.get(position);
52 | holder.fileName.setText(item.path);
53 | holder.itemView.setOnClickListener(v -> {
54 | adapter.jump(item.path);
55 | dialog.dismiss();
56 | });
57 | holder.itemView.setOnLongClickListener(v -> {
58 | new AlertDialog.Builder(context)
59 | .setTitle(R.string.confirm_delete)
60 | .setMessage(context.getString(R.string.delete_the_bookmark,item.path))
61 | .setNegativeButton(R.string.cancel, null)
62 | .setPositiveButton(R.string.ok, (dialog, which) -> {
63 | if (onDelete(item)) {
64 | Toast.makeText(context, R.string.deleted_successfully, Toast.LENGTH_SHORT).show();
65 | bookMarks.remove(item);
66 | notifyItemRemoved(holder.getAdapterPosition());
67 | } else {
68 | Toast.makeText(context, R.string.deletion_failed, Toast.LENGTH_SHORT).show();
69 | }
70 | })
71 | .show();
72 | return true;
73 | });
74 | }
75 |
76 | @Override
77 | public int getItemCount() {
78 | return bookMarks.size();
79 | }
80 |
81 | private boolean onDelete(BookMark bookMark){
82 | if (isRemote){
83 | return db.removeRemoteBookmark(bookMark.id) > 0;
84 | } else {
85 | return db.removeLocalBookmark(bookMark.id) > 0;
86 | }
87 | }
88 |
89 | public static class MyViewHolder extends RecyclerView.ViewHolder {
90 | TextView fileName;
91 | public MyViewHolder(@NonNull View itemView) {
92 | super(itemView);
93 | fileName = itemView.findViewById(R.id.file_name);
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/listadapter/LocalFileSelectAdapter.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.listadapter;
2 |
3 | import android.app.Activity;
4 | import android.os.Environment;
5 | import android.os.RemoteException;
6 | import android.view.View;
7 | import android.widget.Toast;
8 |
9 | import androidx.appcompat.widget.Toolbar;
10 | import androidx.recyclerview.widget.LinearLayoutManager;
11 | import androidx.recyclerview.widget.RecyclerView;
12 |
13 | import java.util.List;
14 |
15 | import top.weixiansen574.hybridfilexfer.R;
16 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
17 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
18 | import top.weixiansen574.hybridfilexfer.droidcore.HFXServer;
19 |
20 | public class LocalFileSelectAdapter extends FileSelectAdapter {
21 | public LocalFileSelectAdapter(Activity context, View loadingView, RecyclerView recyclerView, LinearLayoutManager
22 | linearLayoutManager, Toolbar fileSelectToolbar, View.OnTouchListener onTouchListener, HFXServer server) {
23 | super(context, loadingView, recyclerView, linearLayoutManager, fileSelectToolbar, onTouchListener, server);
24 | }
25 |
26 | @Override
27 | public List listFiles(String path) throws RemoteException {
28 | return server.listLocalFiles(path);
29 | }
30 |
31 | @Override
32 | protected void handleListException(Throwable th) {
33 |
34 | }
35 |
36 | @Override
37 | protected String getDefaultDir(HFXServer server) {
38 | //return "/storage/emulated/0/";
39 | //改用方法获取内置存储目录,部分安卓设备的内部可能不是/storage/emulated/0/,导致读取目录失败
40 | String path = Environment.getExternalStorageDirectory().getAbsolutePath();
41 | System.out.println("ExternalStorageDirectory:"+path);
42 | return path;
43 | }
44 |
45 | @Override
46 | protected int getFileSystem(HFXServer server) {
47 | return Directory.getCurrentFileSystem();
48 | }
49 |
50 |
51 | @Override
52 | public boolean deleteFile(String file) throws RemoteException {
53 | return server.deleteLocalFile(file);
54 | }
55 |
56 | @Override
57 | public void mkdir(String parent, String child) {
58 | try {
59 | if (server.createLocalDir(parent,child)) {
60 | Toast.makeText(context, R.string.chuang_jian_cheng_gong, Toast.LENGTH_SHORT).show();
61 | refresh();
62 | } else {
63 | Toast.makeText(context, R.string.chuang_jian_shi_bai, Toast.LENGTH_SHORT).show();
64 | }
65 | } catch (RemoteException e) {
66 | throw new RuntimeException(e);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/listadapter/RemoteFileSelectAdapter.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.listadapter;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.view.View;
6 | import android.widget.Toast;
7 |
8 | import androidx.appcompat.widget.Toolbar;
9 | import androidx.recyclerview.widget.LinearLayoutManager;
10 | import androidx.recyclerview.widget.RecyclerView;
11 |
12 | import java.io.IOException;
13 | import java.util.List;
14 |
15 | import top.weixiansen574.hybridfilexfer.MainActivity;
16 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
17 | import top.weixiansen574.hybridfilexfer.R;
18 | import top.weixiansen574.hybridfilexfer.droidcore.HFXServer;
19 |
20 | public class RemoteFileSelectAdapter extends FileSelectAdapter {
21 |
22 | public RemoteFileSelectAdapter(Activity context, View loadingView, RecyclerView recyclerView, LinearLayoutManager
23 | linearLayoutManager, Toolbar fileSelectToolbar, View.OnTouchListener onTouchListener, HFXServer server) {
24 | super(context, loadingView, recyclerView, linearLayoutManager, fileSelectToolbar, onTouchListener, server);
25 | }
26 |
27 | @Override
28 | public List listFiles(String path) throws IOException {
29 | return server.listClientFiles(path);
30 | }
31 |
32 | @Override
33 | protected void handleListException(Throwable th) {
34 | onConnectionLost();
35 | }
36 |
37 | @Override
38 | protected String getDefaultDir(HFXServer server) {
39 | return server.getRemoteHomeDir();
40 | }
41 |
42 | @Override
43 | protected int getFileSystem(HFXServer server) {
44 | return server.getRemoteFileSystem();
45 | }
46 |
47 |
48 | @Override
49 | public boolean deleteFile(String file) throws IOException {
50 | return server.deleteRemoteFile(file);
51 | }
52 |
53 | @Override
54 | public void mkdir(String parent, String child) {
55 | new Thread(() -> {
56 | try {
57 | boolean success = server.createRemoteDir(parent, child);
58 | context.runOnUiThread(() -> {
59 | if (success) {
60 | Toast.makeText(context, R.string.chuang_jian_cheng_gong, Toast.LENGTH_SHORT).show();
61 | refresh();
62 | } else {
63 | Toast.makeText(context, R.string.chuang_jian_shi_bai, Toast.LENGTH_SHORT).show();
64 | }
65 | });
66 | } catch (IOException e) {
67 | onConnectionLost();
68 | }
69 | }).start();
70 | }
71 |
72 | private void onConnectionLost() {
73 | context.setResult(MainActivity.RESULT_CODE_SERVER_DISCONNECT);
74 | new AlertDialog.Builder(context)
75 | .setTitle(R.string.chuang_jian_shi_bai)
76 | .setMessage(R.string.kong_tong_dao_de_lian_jie_yi_duan_kai__)
77 | .setCancelable(false)
78 | .setPositiveButton(R.string.ok, (dialog, which) -> context.finish()).show();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/BTransferFileCallback.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import top.weixiansen574.async.BackstageTask;
4 | import top.weixiansen574.hybridfilexfer.core.callback.TransferFileCallback;
5 |
6 | public interface BTransferFileCallback extends BackstageTask.BaseEventHandler, TransferFileCallback {
7 | }
8 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/ClientTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import top.weixiansen574.async.BackstageTask;
4 | import top.weixiansen574.hybridfilexfer.core.callback.ClientCallBack;
5 | import top.weixiansen574.hybridfilexfer.droidcore.DroidHFXClient;
6 |
7 | public class ClientTask extends BackstageTask {
8 | private final DroidHFXClient client;
9 |
10 | public ClientTask(Callback uiHandler, DroidHFXClient client) {
11 | super(uiHandler);
12 | this.client = client;
13 | }
14 |
15 | @Override
16 | protected void onStart(Callback eventHandlerProxy) throws Throwable {
17 | client.start(eventHandlerProxy);
18 | }
19 |
20 | public interface Callback extends ClientCallBack,BackstageTask.BaseEventHandler{}
21 | }
22 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/ConnectServerTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import top.weixiansen574.async.BackstageTask;
4 | import top.weixiansen574.hybridfilexfer.core.HFXClient;
5 | import top.weixiansen574.hybridfilexfer.core.callback.ConnectServerCallback;
6 | import top.weixiansen574.hybridfilexfer.droidcore.DroidHFXClient;
7 |
8 | public class ConnectServerTask extends BackstageTask {
9 | private final DroidHFXClient client;
10 | public ConnectServerTask(Callback uiHandler, DroidHFXClient client) {
11 | super(uiHandler);
12 | this.client = client;
13 | }
14 |
15 | @Override
16 | protected void onStart(Callback callback) throws Throwable {
17 | if (!client.connect(callback)) {
18 | client.freeBuffers();
19 | }
20 | }
21 |
22 | @Override
23 | protected void onError(Throwable th) {
24 | client.freeBuffers();
25 | }
26 |
27 | public interface Callback extends ConnectServerCallback,BackstageTask.BaseEventHandler{
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/DeleteFilesTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import java.util.List;
4 |
5 | import top.weixiansen574.async.BackstageTask;
6 | import top.weixiansen574.hybridfilexfer.listadapter.FileSelectAdapter;
7 |
8 | public class DeleteFilesTask extends BackstageTask {
9 |
10 | final FileSelectAdapter adapter;
11 | final List files;
12 |
13 | public DeleteFilesTask(EventHandler uiHandler, FileSelectAdapter adapter, List files) {
14 | super(uiHandler);
15 | this.adapter = adapter;
16 | this.files = files;
17 | }
18 |
19 | @Override
20 | protected void onStart(EventHandler handler) throws Throwable {
21 | for (int i = 0; i < files.size(); i++) {
22 | String file = files.get(i);
23 | handler.onDeleting(i,file);
24 | if (!adapter.deleteFile(file)){
25 | handler.onFailed(i,file);
26 | return;
27 | }
28 | }
29 | handler.onSuccess();
30 | }
31 |
32 | public interface EventHandler extends BackstageTask.BaseEventHandler{
33 | void onDeleting(int index,String file);
34 | void onFailed(int index,String file);
35 | void onSuccess();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/ListFilesTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import java.util.List;
4 |
5 | import top.weixiansen574.async.BackstageTask;
6 | import top.weixiansen574.hybridfilexfer.core.Utils;
7 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
8 | import top.weixiansen574.hybridfilexfer.listadapter.FileSelectAdapter;
9 |
10 | public class ListFilesTask extends BackstageTask {
11 |
12 | public final String path;
13 | public final FileSelectAdapter adapter;
14 |
15 | public ListFilesTask(CallBack uiHandler, String path, FileSelectAdapter adapter) {
16 | super(uiHandler);
17 | this.path = path;
18 | this.adapter = adapter;
19 | }
20 |
21 | @Override
22 | protected void onStart(CallBack eventHandlerProxy) throws Throwable {
23 | List listFiles = adapter.listFiles(path);
24 | if (listFiles != null) {
25 | Utils.sortFiles(listFiles);
26 | listFiles.add(0,new RemoteFile("..", "", 0, 0, true));
27 | eventHandlerProxy.onResult(listFiles);
28 | } else {
29 | eventHandlerProxy.onResult(null);
30 | }
31 | }
32 |
33 | public interface CallBack extends BackstageTask.BaseEventHandler{
34 | void onResult(List files);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/SendFilesToRemoteTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import java.util.List;
4 |
5 | import top.weixiansen574.async.BackstageTask;
6 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
7 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
8 | import top.weixiansen574.hybridfilexfer.droidcore.HFXServer;
9 |
10 | public class SendFilesToRemoteTask extends BackstageTask {
11 | private final HFXServer server;
12 | private final List files;
13 | private final Directory localDir;
14 | private final Directory remoteDir;
15 | public SendFilesToRemoteTask(BTransferFileCallback uiHandler, HFXServer server, List files, Directory localDir, Directory remoteDir) {
16 | super(uiHandler);
17 | this.server = server;
18 | this.files = files;
19 | this.localDir = localDir;
20 | this.remoteDir = remoteDir;
21 | }
22 |
23 | @Override
24 | protected void onStart(BTransferFileCallback callback) throws Throwable {
25 | server.sendFilesToRemote(files,localDir,remoteDir,callback);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/java/top/weixiansen574/hybridfilexfer/tasks/SendFilesToShelfTask.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.tasks;
2 |
3 | import java.util.List;
4 |
5 | import top.weixiansen574.async.BackstageTask;
6 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
7 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
8 | import top.weixiansen574.hybridfilexfer.droidcore.HFXServer;
9 |
10 | public class SendFilesToShelfTask extends BackstageTask {
11 | private final HFXServer server;
12 | private final List files;
13 | private final Directory localDir;
14 | private final Directory remoteDir;
15 | public SendFilesToShelfTask(BTransferFileCallback uiHandler, HFXServer server, List files, Directory localDir, Directory remoteDir) {
16 | super(uiHandler);
17 | this.server = server;
18 | this.files = files;
19 | this.localDir = localDir;
20 | this.remoteDir = remoteDir;
21 | }
22 |
23 | @Override
24 | protected void onStart(BTransferFileCallback callback) throws Throwable {
25 | server.sendFilesToShelf(files,localDir,remoteDir,callback);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/anim/list_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_add_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_arrow_outward_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_bookmark_add_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_bookmarks_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_check_circle_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_delete_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_file_download_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_grid_view_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_more_vert_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_phonelink_ring_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_refresh_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_select_all_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_speed_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_update_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/baseline_upload_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/bt.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/ethernet.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/file.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
14 |
17 |
20 |
21 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/folder.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/github.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/ic_close.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-Android/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/shadow_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/shadow_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/shadow_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/shadow_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/usb.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/drawable/wifi.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/activity_client.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
19 |
20 |
29 |
30 |
31 |
36 |
37 |
43 |
44 |
54 |
55 |
66 |
67 |
68 |
79 |
80 |
81 |
82 |
83 |
88 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/dialog_bookmarks.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/dialog_buffer_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
32 |
33 |
40 |
41 |
51 |
52 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/dialog_connect_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
23 |
24 |
30 |
31 |
32 |
33 |
41 |
42 |
53 |
54 |
62 |
63 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/dialog_transfer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/edit_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/item_bookmark.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
25 |
26 |
27 |
28 |
29 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/item_file.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
42 |
43 |
52 |
53 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/item_net_card_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
34 |
35 |
43 |
44 |
53 |
54 |
55 |
61 |
62 |
69 |
70 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/item_net_interface_status.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
16 |
17 |
22 |
23 |
33 |
34 |
44 |
45 |
46 |
56 |
98 |
99 |
100 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/layout/toolbar_select.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/menu/main_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/menu/select_toolbar_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/menu/toolbar_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
9 |
10 |
14 |
18 |
22 |
26 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @color/white
4 | #8AB4F8
5 | #394456
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @string/normal
5 | - Root
6 | - ADB
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF000000
4 | #FFFFFFFF
5 | #212121
6 | #1E88E5
7 | #E3F2FD
8 | @color/black
9 | #59000000
10 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/app/src/test/java/top/weixiansen574/hybridfilexfer2/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer2;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.application' version '8.1.3' apply false
4 | }
--------------------------------------------------------------------------------
/HybridFileXfer-Android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Enables namespacing of each library's R class so that its R class includes only the
19 | # resources declared in the library itself and none from the library's dependencies,
20 | # thereby reducing the size of the R class for that library
21 | android.nonTransitiveRClass=true
22 | android.enableResourceOptimizations=false
--------------------------------------------------------------------------------
/HybridFileXfer-Android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-Android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/HybridFileXfer-Android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Sep 21 16:38:51 CST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/HybridFileXfer-Android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | maven { url 'https://jitpack.io' }
7 | }
8 | }
9 | dependencyResolutionManagement {
10 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11 | repositories {
12 | google()
13 | mavenCentral()
14 | maven { url 'https://jitpack.io' }
15 | }
16 | }
17 |
18 | rootProject.name = "HybridFileXfer"
19 | include ':app'
20 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 | # 基于编辑器的 HTTP 客户端请求
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/HybridFileXfer-PC.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/artifacts/HybridFileXfer_PC_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | $PROJECT_DIR$/out/artifacts/HybridFileXfer_PC_jar
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/AdbWinApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/AdbWinApi.dll
--------------------------------------------------------------------------------
/HybridFileXfer-PC/AdbWinUsbApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/AdbWinUsbApi.dll
--------------------------------------------------------------------------------
/HybridFileXfer-PC/HybridFileXfer-PC.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/adb.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/adb.exe
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/artifacts/HybridFileXfer_PC_jar/HybridFileXfer-PC.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/artifacts/HybridFileXfer_PC_jar/HybridFileXfer-PC.jar
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: top.weixiansen574.hybridfilexfer.Main
3 |
4 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/messages_en.properties:
--------------------------------------------------------------------------------
1 | usage=Control channel connection method not specified\nParameter description:\n-c Connection method: \"adb\" or network IP\n-s Specify the device for adb mode (when multiple devices are connected via adb). You can use the \"adb devices\" command to check the device list.\nExample:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB: Port 5740 forwarding successful!
3 | connecting_control_channel=Connecting to control channel: %s
4 | version_mismatch=Protocol version mismatch. Your version: %d, Remote version: %d
5 | connect_control_failed=Failed to connect to the control channel. Please check if the mobile server is running.
6 | connecting_transfer_channel=Connecting... Network Interface: %s, Remote Address: %s, Bind Address: %s
7 | connect_transfer_failed=Transfer channel connection failed! Interface: %s, Address: %s, Error: %s
8 | out_of_memory=Out of memory! Failed to create buffer blocks. Created: %d, Required: %d. Max available memory: %dMB
9 | java_32bit_warning=Detected 32-bit Java. Memory is limited. Consider using 64-bit Java.
10 | remote_out_of_memory=Connection failed. Insufficient memory on the mobile side. Please follow the mobile device instructions.
11 | connect_success=Connection complete.
12 | receiving_files=Receiving files...
13 | sending_files=Sending files...
14 | client_exit=Received stop command. Client has shut down successfully.
15 | channel_complete=%s transfer complete! Average speed: %s
16 | channel_error_exception=Exception occurred during %s transfer: %s
17 | channel_error_interrupt=%s transfer interrupted due to an error in another channel.
18 | channel_error_read=Read error while transferring %s
19 | channel_error_write=Write error while transferring %s
20 | file_read_error=Error reading file: %s
21 | file_write_error=Error writing file: %s
22 | upload_complete=File upload complete. Avg speed: %s, Time: %s, Data transferred: %s
23 | download_complete=File download complete. Avg speed: %s, Time: %s, Data transferred: %s
24 | transfer_failed=Transfer failed.
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/messages_ja.properties:
--------------------------------------------------------------------------------
1 | usage=制御チャンネルの接続方法が指定されていません\nパラメータの説明:\n-c 制御チャンネルの接続方法 \"adb\" または ネットワークIP\n-s adbモードで指定するデバイス(adbに複数のデバイスが接続されている場合)。\"adb devices\" コマンドでデバイスを確認できます。\n例:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB: ポート 5740 の転送が成功しました!
3 | connecting_control_channel=制御チャンネルに接続中:%s
4 | version_mismatch=プロトコルバージョンの不一致。あなたのバージョン:%d、相手のバージョン:%d
5 | connect_control_failed=制御チャンネルへの接続に失敗しました。モバイルサーバーが起動しているか確認してください。
6 | connecting_transfer_channel=接続中... ネットワークインターフェース:%s、リモートアドレス:%s、バインドアドレス:%s
7 | connect_transfer_failed=転送チャンネルの接続に失敗しました! インターフェース:%s、アドレス:%s、エラー:%s
8 | out_of_memory=メモリ不足! バッファブロックの作成に失敗しました。作成済み:%d、必要数:%d。最大利用可能メモリ:%dMB
9 | java_32bit_warning=32ビットJavaが検出されました。メモリ制限があります。64ビットJavaの使用を推奨します。
10 | remote_out_of_memory=接続失敗。モバイル側のメモリ不足です。指示に従ってください。
11 | connect_success=接続完了。
12 | receiving_files=ファイルを受信中…
13 | sending_files=ファイルを送信中…
14 | client_exit=終了指示を受けました。クライアントが正常に終了しました。
15 | channel_complete=%s 転送完了! 平均速度:%s
16 | channel_error_exception=%s の転送中にエラーが発生しました:%s
17 | channel_error_interrupt=他のチャンネルのエラーにより %s の転送が中断されました。
18 | channel_error_read=%s の読み取りエラーが発生しました。
19 | channel_error_write=%s の書き込みエラーが発生しました。
20 | file_read_error=ファイルの読み取り中にエラーが発生しました:%s
21 | file_write_error=ファイルの書き込み中にエラーが発生しました:%s
22 | upload_complete=ファイルアップロード完了。平均速度:%s、時間:%s、転送量:%s
23 | download_complete=ファイルダウンロード完了。平均速度:%s、時間:%s、転送量:%s
24 | transfer_failed=転送に失敗しました。
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/messages_ko.properties:
--------------------------------------------------------------------------------
1 | usage=제어 채널 연결 방법이 지정되지 않았습니다\n매개변수 설명:\n-c 제어 채널 연결 방식 \"adb\" 또는 네트워크 IP\n-s adb 모드에서 특정 장치를 지정 (adb에 여러 장치가 연결된 경우). \"adb devices\" 명령어로 장치를 확인할 수 있습니다.\n예시:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB: 포트 5740 포워딩 성공!
3 | connecting_control_channel=제어 채널에 연결 중: %s
4 | version_mismatch=프로토콜 버전 불일치. 내 버전: %d, 상대 버전: %d
5 | connect_control_failed=제어 채널 연결 실패. 모바일 서버가 실행 중인지 확인하세요.
6 | connecting_transfer_channel=연결 중... 네트워크 인터페이스: %s, 원격 주소: %s, 바인드 주소: %s
7 | connect_transfer_failed=전송 채널 연결 실패! 인터페이스: %s, 주소: %s, 오류: %s
8 | out_of_memory=메모리 부족! 버퍼 블록 생성 실패. 생성된 블록: %d, 필요 블록: %d. 최대 사용 가능 메모리: %dMB
9 | java_32bit_warning=32비트 Java 감지됨. 메모리 제한이 있습니다. 64비트 Java 사용을 권장합니다.
10 | remote_out_of_memory=연결 실패. 모바일 장치의 메모리가 부족합니다. 안내를 따르세요.
11 | connect_success=연결 완료.
12 | receiving_files=파일 수신 중...
13 | sending_files=파일 전송 중...
14 | client_exit=종료 명령을 받았습니다. 클라이언트가 정상적으로 종료되었습니다.
15 | channel_complete=%s 전송 완료! 평균 속도: %s
16 | channel_error_exception=%s 전송 중 오류 발생: %s
17 | channel_error_interrupt=다른 채널 오류로 인해 %s 전송이 중단되었습니다.
18 | channel_error_read=%s 읽기 오류 발생.
19 | channel_error_write=%s 쓰기 오류 발생.
20 | file_read_error=파일 읽기 오류: %s
21 | file_write_error=파일 쓰기 오류: %s
22 | upload_complete=파일 업로드 완료. 평균 속도: %s, 시간: %s, 전송량: %s
23 | download_complete=파일 다운로드 완료. 평균 속도: %s, 시간: %s, 전송량: %s
24 | transfer_failed=전송 실패.
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/messages_zh_CN.properties:
--------------------------------------------------------------------------------
1 | usage=未指定控制通道连接方式\n参数说明:\n-c 控制通道连接方式 \"adb\" 或 网络ip\n-s adb连接方式下指定的设备(adb有多设备的情况),你可以用\"adb devices\"命令查看设备\n示例:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB : 5740 端口转发成功!
3 | connecting_control_channel=正在连接控制通道:%s
4 | version_mismatch=协议版本不一致,你的版本:%d,对方版本:%d
5 | connect_control_failed=控制通道连接到手机失败,请检查手机的服务端是否启动?
6 | connecting_transfer_channel=正在连接 网卡名:%s 远程地址:%s 绑定地址:%s
7 | connect_transfer_failed=传输通道连接失败!网卡名:%s 地址:%s 异常信息:%s
8 | out_of_memory=内存不足,创建缓冲区块失败!成功创建%d块,需要%d块。当前最大可用内存:%dMB
9 | java_32bit_warning=检测你正在使用32位Java,内存受限,建议使用64位Java
10 | remote_out_of_memory=连接失败,手机端内存不足,请按照手机端的提示操作
11 | connect_success=连接完毕
12 | receiving_files=正在接收文件……
13 | sending_files=正在发送文件……
14 | client_exit=收到停止指令,客户端已正常关闭!
15 | channel_complete=%s 传输完毕!平均速度:%s
16 | channel_error_exception=%s 传输时发生异常:%s
17 | channel_error_interrupt=%s 因其他通道发生了错误,传输已中断
18 | channel_error_read=%s 读取文件时出错
19 | channel_error_write=%s 写入文件时出错
20 | file_read_error=读取文件时发生错误:%s
21 | file_write_error=写入文件时发生错误:%s
22 | upload_complete=文件发送完毕 平均速度:%s 耗时:%s 传输量:%s
23 | download_complete=文件接收完毕 平均速度:%s 耗时:%s 传输量:%s
24 | transfer_failed=传输失败
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/messages_zh_TW.properties:
--------------------------------------------------------------------------------
1 | usage=未指定控制通道連接方式\n參數說明:\n-c 控制通道連接方式 \"adb\" 或 網路IP\n-s adb連接方式下指定的設備(當adb有多個設備時),你可以用 \"adb devices\" 指令查看設備\n示例:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB : 5740 端口轉發成功!
3 | connecting_control_channel=正在連接控制通道:%s
4 | version_mismatch=協議版本不一致,你的版本:%d,對方版本:%d
5 | connect_control_failed=控制通道連接到手機失敗,請檢查手機的服務端是否啟動?
6 | connecting_transfer_channel=正在連接 網卡名:%s 遠程地址:%s 綁定地址:%s
7 | connect_transfer_failed=傳輸通道連接失敗!網卡名:%s 地址:%s 異常信息:%s
8 | out_of_memory=記憶體不足,創建緩衝區塊失敗!成功創建%d塊,需要%d塊。當前最大可用記憶體:%dMB
9 | java_32bit_warning=偵測到您正在使用32位Java,記憶體受限,建議使用64位Java
10 | remote_out_of_memory=連接失敗,手機端記憶體不足,請按照手機端的提示操作
11 | connect_success=連接完畢
12 | receiving_files=正在接收檔案……
13 | sending_files=正在發送檔案……
14 | client_exit=收到停止指令,客戶端已正常關閉!
15 | channel_complete=%s 傳輸完畢!平均速度:%s
16 | channel_error_exception=%s 傳輸時發生異常:%s
17 | channel_error_interrupt=%s 因其他通道發生錯誤,傳輸已中斷
18 | channel_error_read=%s 讀取檔案時出錯
19 | channel_error_write=%s 寫入檔案時出錯
20 | file_read_error=讀取檔案時發生錯誤:%s
21 | file_write_error=寫入檔案時發生錯誤:%s
22 | upload_complete=檔案傳送完畢 平均速度:%s 耗時:%s 傳輸量:%s
23 | download_complete=檔案接收完畢 平均速度:%s 耗時:%s 傳輸量:%s
24 | transfer_failed=傳輸失敗
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Main$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Main$1.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Main$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Main$2.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Main.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Main.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Strings$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Strings$1.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Strings.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/Strings.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/FileBlock.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/FileBlock.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/HFXClient.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/HFXClient.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/HFXService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/HFXService.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/ReadFileCall.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/ReadFileCall.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/ReceiveFileCall.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/ReceiveFileCall.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/SendFileCall.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/SendFileCall.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/SpeedMonitorThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/SpeedMonitorThread.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/TransferConnection.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/TransferConnection.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/Utils.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/Utils.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/WriteFileCall.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/WriteFileCall.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/Directory.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/Directory.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/ServerNetInterface.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/ServerNetInterface.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/TrafficInfo.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/bean/TrafficInfo.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/callback/ClientCallBack.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/callback/ClientCallBack.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/callback/ConnectServerCallback.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/callback/ConnectServerCallback.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/callback/TransferFileCallback.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/core/callback/TransferFileCallback.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/jdkcore/JdkHFXClient.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/jdkcore/JdkHFXClient.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/jdkcore/JdkReadFileCall.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/jdkcore/JdkReadFileCall.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/jdkcore/JdkWriteFileCall.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/hybridfilexfer/jdkcore/JdkWriteFileCall.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/nio/DataByteChannel.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/out/production/HybridFileXfer-PC/top/weixiansen574/nio/DataByteChannel.class
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: top.weixiansen574.hybridfilexfer.Main
3 |
4 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/messages_en.properties:
--------------------------------------------------------------------------------
1 | usage=Control channel connection method not specified\nParameter description:\n-c Connection method: \"adb\" or network IP\n-s Specify the device for adb mode (when multiple devices are connected via adb). You can use the \"adb devices\" command to check the device list.\nExample:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB: Port 5740 forwarding successful!
3 | connecting_control_channel=Connecting to control channel: %s
4 | version_mismatch=Protocol version mismatch. Your version: %d, Remote version: %d
5 | connect_control_failed=Failed to connect to the control channel. Please check if the mobile server is running.
6 | connecting_transfer_channel=Connecting... Network Interface: %s, Remote Address: %s, Bind Address: %s
7 | connect_transfer_failed=Transfer channel connection failed! Interface: %s, Address: %s, Error: %s
8 | out_of_memory=Out of memory! Failed to create buffer blocks. Created: %d, Required: %d. Max available memory: %dMB
9 | java_32bit_warning=Detected 32-bit Java. Memory is limited. Consider using 64-bit Java.
10 | remote_out_of_memory=Connection failed. Insufficient memory on the mobile side. Please follow the mobile device instructions.
11 | connect_success=Connection complete.
12 | receiving_files=Receiving files...
13 | sending_files=Sending files...
14 | client_exit=Received stop command. Client has shut down successfully.
15 | channel_complete=%s transfer complete! Average speed: %s
16 | channel_error_exception=Exception occurred during %s transfer: %s
17 | channel_error_interrupt=%s transfer interrupted due to an error in another channel.
18 | channel_error_read=Read error while transferring %s
19 | channel_error_write=Write error while transferring %s
20 | file_read_error=Error reading file: %s
21 | file_write_error=Error writing file: %s
22 | upload_complete=File upload complete. Avg speed: %s, Time: %s, Data transferred: %s
23 | download_complete=File download complete. Avg speed: %s, Time: %s, Data transferred: %s
24 | transfer_failed=Transfer failed.
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/messages_ja.properties:
--------------------------------------------------------------------------------
1 | usage=制御チャンネルの接続方法が指定されていません\nパラメータの説明:\n-c 制御チャンネルの接続方法 \"adb\" または ネットワークIP\n-s adbモードで指定するデバイス(adbに複数のデバイスが接続されている場合)。\"adb devices\" コマンドでデバイスを確認できます。\n例:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB: ポート 5740 の転送が成功しました!
3 | connecting_control_channel=制御チャンネルに接続中:%s
4 | version_mismatch=プロトコルバージョンの不一致。あなたのバージョン:%d、相手のバージョン:%d
5 | connect_control_failed=制御チャンネルへの接続に失敗しました。モバイルサーバーが起動しているか確認してください。
6 | connecting_transfer_channel=接続中... ネットワークインターフェース:%s、リモートアドレス:%s、バインドアドレス:%s
7 | connect_transfer_failed=転送チャンネルの接続に失敗しました! インターフェース:%s、アドレス:%s、エラー:%s
8 | out_of_memory=メモリ不足! バッファブロックの作成に失敗しました。作成済み:%d、必要数:%d。最大利用可能メモリ:%dMB
9 | java_32bit_warning=32ビットJavaが検出されました。メモリ制限があります。64ビットJavaの使用を推奨します。
10 | remote_out_of_memory=接続失敗。モバイル側のメモリ不足です。指示に従ってください。
11 | connect_success=接続完了。
12 | receiving_files=ファイルを受信中…
13 | sending_files=ファイルを送信中…
14 | client_exit=終了指示を受けました。クライアントが正常に終了しました。
15 | channel_complete=%s 転送完了! 平均速度:%s
16 | channel_error_exception=%s の転送中にエラーが発生しました:%s
17 | channel_error_interrupt=他のチャンネルのエラーにより %s の転送が中断されました。
18 | channel_error_read=%s の読み取りエラーが発生しました。
19 | channel_error_write=%s の書き込みエラーが発生しました。
20 | file_read_error=ファイルの読み取り中にエラーが発生しました:%s
21 | file_write_error=ファイルの書き込み中にエラーが発生しました:%s
22 | upload_complete=ファイルアップロード完了。平均速度:%s、時間:%s、転送量:%s
23 | download_complete=ファイルダウンロード完了。平均速度:%s、時間:%s、転送量:%s
24 | transfer_failed=転送に失敗しました。
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/messages_ko.properties:
--------------------------------------------------------------------------------
1 | usage=제어 채널 연결 방법이 지정되지 않았습니다\n매개변수 설명:\n-c 제어 채널 연결 방식 \"adb\" 또는 네트워크 IP\n-s adb 모드에서 특정 장치를 지정 (adb에 여러 장치가 연결된 경우). \"adb devices\" 명령어로 장치를 확인할 수 있습니다.\n예시:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB: 포트 5740 포워딩 성공!
3 | connecting_control_channel=제어 채널에 연결 중: %s
4 | version_mismatch=프로토콜 버전 불일치. 내 버전: %d, 상대 버전: %d
5 | connect_control_failed=제어 채널 연결 실패. 모바일 서버가 실행 중인지 확인하세요.
6 | connecting_transfer_channel=연결 중... 네트워크 인터페이스: %s, 원격 주소: %s, 바인드 주소: %s
7 | connect_transfer_failed=전송 채널 연결 실패! 인터페이스: %s, 주소: %s, 오류: %s
8 | out_of_memory=메모리 부족! 버퍼 블록 생성 실패. 생성된 블록: %d, 필요 블록: %d. 최대 사용 가능 메모리: %dMB
9 | java_32bit_warning=32비트 Java 감지됨. 메모리 제한이 있습니다. 64비트 Java 사용을 권장합니다.
10 | remote_out_of_memory=연결 실패. 모바일 장치의 메모리가 부족합니다. 안내를 따르세요.
11 | connect_success=연결 완료.
12 | receiving_files=파일 수신 중...
13 | sending_files=파일 전송 중...
14 | client_exit=종료 명령을 받았습니다. 클라이언트가 정상적으로 종료되었습니다.
15 | channel_complete=%s 전송 완료! 평균 속도: %s
16 | channel_error_exception=%s 전송 중 오류 발생: %s
17 | channel_error_interrupt=다른 채널 오류로 인해 %s 전송이 중단되었습니다.
18 | channel_error_read=%s 읽기 오류 발생.
19 | channel_error_write=%s 쓰기 오류 발생.
20 | file_read_error=파일 읽기 오류: %s
21 | file_write_error=파일 쓰기 오류: %s
22 | upload_complete=파일 업로드 완료. 평균 속도: %s, 시간: %s, 전송량: %s
23 | download_complete=파일 다운로드 완료. 평균 속도: %s, 시간: %s, 전송량: %s
24 | transfer_failed=전송 실패.
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/messages_zh_CN.properties:
--------------------------------------------------------------------------------
1 | usage=未指定控制通道连接方式\n参数说明:\n-c 控制通道连接方式 \"adb\" 或 网络ip\n-s adb连接方式下指定的设备(adb有多设备的情况),你可以用\"adb devices\"命令查看设备\n示例:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB : 5740 端口转发成功!
3 | connecting_control_channel=正在连接控制通道:%s
4 | version_mismatch=协议版本不一致,你的版本:%d,对方版本:%d
5 | connect_control_failed=控制通道连接到手机失败,请检查手机的服务端是否启动?
6 | connecting_transfer_channel=正在连接 网卡名:%s 远程地址:%s 绑定地址:%s
7 | connect_transfer_failed=传输通道连接失败!网卡名:%s 地址:%s 异常信息:%s
8 | out_of_memory=内存不足,创建缓冲区块失败!成功创建%d块,需要%d块。当前最大可用内存:%dMB
9 | java_32bit_warning=检测你正在使用32位Java,内存受限,建议使用64位Java
10 | remote_out_of_memory=连接失败,手机端内存不足,请按照手机端的提示操作
11 | connect_success=连接完毕
12 | receiving_files=正在接收文件……
13 | sending_files=正在发送文件……
14 | client_exit=收到停止指令,客户端已正常关闭!
15 | channel_complete=%s 传输完毕!平均速度:%s
16 | channel_error_exception=%s 传输时发生异常:%s
17 | channel_error_interrupt=%s 因其他通道发生了错误,传输已中断
18 | channel_error_read=%s 读取文件时出错
19 | channel_error_write=%s 写入文件时出错
20 | file_read_error=读取文件时发生错误:%s
21 | file_write_error=写入文件时发生错误:%s
22 | upload_complete=文件发送完毕 平均速度:%s 耗时:%s 传输量:%s
23 | download_complete=文件接收完毕 平均速度:%s 耗时:%s 传输量:%s
24 | transfer_failed=传输失败
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/messages_zh_TW.properties:
--------------------------------------------------------------------------------
1 | usage=未指定控制通道連接方式\n參數說明:\n-c 控制通道連接方式 \"adb\" 或 網路IP\n-s adb連接方式下指定的設備(當adb有多個設備時),你可以用 \"adb devices\" 指令查看設備\n示例:\n-c adb\n-c adb -s abcd1234\n-c 192.168.1.2
2 | adb_forward_succeed=USB_ADB : 5740 端口轉發成功!
3 | connecting_control_channel=正在連接控制通道:%s
4 | version_mismatch=協議版本不一致,你的版本:%d,對方版本:%d
5 | connect_control_failed=控制通道連接到手機失敗,請檢查手機的服務端是否啟動?
6 | connecting_transfer_channel=正在連接 網卡名:%s 遠程地址:%s 綁定地址:%s
7 | connect_transfer_failed=傳輸通道連接失敗!網卡名:%s 地址:%s 異常信息:%s
8 | out_of_memory=記憶體不足,創建緩衝區塊失敗!成功創建%d塊,需要%d塊。當前最大可用記憶體:%dMB
9 | java_32bit_warning=偵測到您正在使用32位Java,記憶體受限,建議使用64位Java
10 | remote_out_of_memory=連接失敗,手機端記憶體不足,請按照手機端的提示操作
11 | connect_success=連接完畢
12 | receiving_files=正在接收檔案……
13 | sending_files=正在發送檔案……
14 | client_exit=收到停止指令,客戶端已正常關閉!
15 | channel_complete=%s 傳輸完畢!平均速度:%s
16 | channel_error_exception=%s 傳輸時發生異常:%s
17 | channel_error_interrupt=%s 因其他通道發生錯誤,傳輸已中斷
18 | channel_error_read=%s 讀取檔案時出錯
19 | channel_error_write=%s 寫入檔案時出錯
20 | file_read_error=讀取檔案時發生錯誤:%s
21 | file_write_error=寫入檔案時發生錯誤:%s
22 | upload_complete=檔案傳送完畢 平均速度:%s 耗時:%s 傳輸量:%s
23 | download_complete=檔案接收完畢 平均速度:%s 耗時:%s 傳輸量:%s
24 | transfer_failed=傳輸失敗
25 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/Strings.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.InputStreamReader;
6 | import java.nio.charset.StandardCharsets;
7 | import java.util.*;
8 |
9 | public class Strings {
10 |
11 | private static final ResourceBundle messages;
12 |
13 | static {
14 | //由于Java读取properties文件用的是ISO-8859-1编码,这里加个Control让它用UTF-8编码来读
15 | messages = ResourceBundle.getBundle("messages", Locale.getDefault(), new ResourceBundle.Control() {
16 | @Override
17 | public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
18 | throws IOException {
19 | String bundleName = toBundleName(baseName, locale);
20 | String resourceName = toResourceName(bundleName, "properties");
21 | try (InputStream stream = loader.getResourceAsStream(resourceName)) {
22 | if (stream == null) {
23 | return null;
24 | }
25 | try (InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
26 | return new PropertyResourceBundle(reader);
27 | }
28 | }
29 | }
30 | });
31 | }
32 |
33 | public static String get(String key) {
34 | return messages.getString(key);
35 | }
36 |
37 | public static String get(String key, Object... args) {
38 | String message = messages.getString(key);
39 | return String.format(message, args); // 使用占位符替换
40 | }
41 |
42 | public static void printf(String key){
43 | System.out.println(get(key));
44 | }
45 |
46 | public static void printf(String key, Object... args){
47 | System.out.println(get(key, args));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/ControllerIdentifiers.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | public class ControllerIdentifiers {
4 | public static final short SHUTDOWN = 0;
5 | public static final short LIST_FILES = 1;
6 | public static final short DELETE_FILE = 2;
7 | public static final short MKDIR = 3;
8 | public static final short REQUEST_RECEIVE = 10;
9 | public static final short REQUEST_SEND = 11;
10 |
11 | //就让魔法打败魔法吧!
12 | /**
13 | * 禁止转载应用到酷安
14 | * 不许未经授权将本项目爬取到国内平台,点名GitCode,除非你的平台容得下下面的数字😁
15 | */
16 | private static final int 酷安飞机杯 = 8964;
17 | /**
18 | * 你号没了!
19 | * 当然,如果你看到了有人在酷安分享本软件,请拿此内容进行举报攻击,让他狠狠的享受以下内容!
20 | * 你的账号【___】,存在发布涉政信息的违规行为,已禁止访问
21 | */
22 | private static final String 威武小姐姐 = "学“习”通😋";
23 |
24 | }
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/FileBlock.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.io.File;
4 | import java.nio.ByteBuffer;
5 |
6 | public class FileBlock implements Comparable {
7 | public static final int BLOCK_SIZE = 1024*1024;//1MB
8 |
9 | public final boolean isFile;
10 | public final int fileIndex;
11 | public final String path;
12 | public final long lastModified;
13 | public final long totalSize;
14 | public final int index;
15 | public final ByteBuffer data;
16 |
17 | public FileBlock(boolean isFile, int fileIndex, String path, long lastModified, long totalSize, int index, ByteBuffer data) {
18 | this.isFile = isFile;
19 | this.fileIndex = fileIndex;
20 | this.path = path;
21 | this.lastModified = lastModified;
22 | this.totalSize = totalSize;
23 | this.index = index;
24 | this.data = data;
25 | }
26 |
27 | public long getStartPosition(){
28 | return BLOCK_SIZE * ((long) index);
29 | }
30 |
31 | public long calcBlockCount(){
32 | return totalSize / BLOCK_SIZE + 1;
33 | }
34 |
35 | public boolean isFile(){
36 | return isFile;
37 | }
38 |
39 | public boolean isDirectory(){
40 | return !isFile;
41 | }
42 |
43 | public int getLength(){
44 | if (data == null){
45 | return -1;
46 | }
47 | return data.position();
48 | }
49 |
50 | @Override
51 | public int compareTo(FileBlock other) {
52 | if (this.fileIndex != other.fileIndex) {
53 | return Integer.compare(this.fileIndex, other.fileIndex);
54 | }
55 | // 如果 nameIndex 相同,比较 index
56 | return Integer.compare(this.index, other.index);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/SendFileCall.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.util.concurrent.Callable;
4 |
5 | import top.weixiansen574.hybridfilexfer.core.callback.TransferFileCallback;
6 | import top.weixiansen574.nio.DataByteChannel;
7 |
8 | public class SendFileCall implements Callable {
9 | private final ReadFileCall readFileCall;
10 | private final DataByteChannel channel;
11 | private final TransferConnection connection;
12 | private final TransferFileCallback callback;
13 |
14 | public SendFileCall(ReadFileCall readFileCall, TransferConnection connection, TransferFileCallback callback) {
15 | this.readFileCall = readFileCall;
16 | this.connection = connection;
17 | this.channel = connection.channel;
18 | this.callback = callback;
19 | connection.resetTotalTrafficInfo();
20 | }
21 |
22 | @Override
23 | public Void call() throws Exception {
24 | FileBlock fileBlock = null;
25 | try {
26 | long startTime = System.currentTimeMillis();
27 | while (true) {
28 | fileBlock = readFileCall.takeBlock();
29 | //-1为特殊块
30 | if (fileBlock.fileIndex == -1) {
31 | if (fileBlock == ReadFileCall.END_POINT) {
32 | channel.writeShort(TransferIdentifiers.EOF);
33 | callback.onChannelComplete(connection.iName,
34 | connection.getTotalTraffic().uploadTraffic,
35 | System.currentTimeMillis() - startTime);
36 | } else if (fileBlock == ReadFileCall.INTERRUPT) {
37 | channel.writeShort(TransferIdentifiers.END_OF_INTERRUPTED);
38 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_INTERRUPT, null);
39 | } else if (fileBlock == ReadFileCall.READ_ERROR) {
40 | channel.writeShort(TransferIdentifiers.END_OF_READ_ERROR);
41 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_READ_ERROR, null);
42 | } else if (fileBlock == ReadFileCall.WRITE_ERROR) {
43 | channel.writeShort(TransferIdentifiers.END_OF_WRITE_ERROR);
44 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_WRITE_ERROR, null);
45 | }
46 | break;
47 | }
48 | channel.writeShort(fileBlock.isFile ? TransferIdentifiers.FILE :
49 | TransferIdentifiers.FOLDER);//是否文件夹
50 | channel.writeInt(fileBlock.fileIndex);
51 | channel.writeUTF(fileBlock.path);//路径
52 | channel.writeLong(fileBlock.lastModified);//修改日期
53 | if (!fileBlock.isFile) continue;
54 | channel.writeLong(fileBlock.totalSize);//总大小
55 | channel.writeInt(fileBlock.index);//索引
56 | channel.writeInt(fileBlock.getLength());//单块的长度
57 |
58 | callback.onFileUploading(connection.iName, fileBlock.path,
59 | fileBlock.getStartPosition() + fileBlock.getLength(),
60 | fileBlock.totalSize);
61 |
62 | fileBlock.data.flip();
63 | channel.write(fileBlock.data);
64 | readFileCall.recycleBuffer(fileBlock.data);
65 | connection.addUploadedBytes(fileBlock.getLength());
66 | }
67 | } catch (Exception e) {
68 | //若发生异常,通知其他传输通道,停止传输
69 | if (fileBlock != null){
70 | //回收文件分块的ByteBuffer,否则导致这个Buffer免费了
71 | readFileCall.recycleBuffer(fileBlock.data);
72 | }
73 | readFileCall.shutdownByConnectionBreak();
74 | callback.onChannelError(connection.iName,TransferFileCallback.ERROR_TYPE_EXCEPTION, e.toString());
75 | throw e;
76 | }
77 | return null;
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/SpeedMonitorThread.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import top.weixiansen574.hybridfilexfer.core.TransferConnection;
7 | import top.weixiansen574.hybridfilexfer.core.bean.TrafficInfo;
8 | import top.weixiansen574.hybridfilexfer.core.callback.TransferFileCallback;
9 |
10 | public class SpeedMonitorThread extends Thread {
11 | private boolean isRun = true;
12 | private final List connections;
13 | private final TransferFileCallback callback;
14 |
15 | public SpeedMonitorThread(List connections, TransferFileCallback callback) {
16 | this.connections = connections;
17 | this.callback = callback;
18 | }
19 |
20 | @Override
21 | @SuppressWarnings("BusyWait")
22 | public void run() {
23 | while (isRun){
24 | try {
25 | Thread.sleep(1000);
26 | } catch (InterruptedException e) {
27 | break;
28 | }
29 | List trafficInfoList = new ArrayList<>();
30 | for (TransferConnection channel : connections) {
31 | trafficInfoList.add(channel.resetCurrentTrafficInfo());
32 | }
33 | callback.onSpeedInfo(trafficInfoList);
34 | }
35 | }
36 |
37 | public void cancel(){
38 | isRun = false;
39 | interrupt();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/TransferConnection.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.io.IOException;
4 |
5 | import top.weixiansen574.hybridfilexfer.core.bean.TrafficInfo;
6 | import top.weixiansen574.nio.DataByteChannel;
7 |
8 | public class TransferConnection {
9 | public final String iName;
10 | private TrafficInfo currentTraffic;
11 | private TrafficInfo totalTraffic;
12 | public final DataByteChannel channel;
13 |
14 | public TransferConnection(String iName, DataByteChannel channel) throws IOException {
15 | this.iName = iName;
16 | this.channel = channel;
17 | currentTraffic = new TrafficInfo();
18 | totalTraffic = new TrafficInfo();
19 | }
20 |
21 | public synchronized void addUploadedBytes(long byteCount) {
22 | currentTraffic.uploadTraffic += byteCount;
23 | totalTraffic.uploadTraffic += byteCount;
24 | }
25 |
26 | public synchronized void addDownloadedBytes(long byteCount) {
27 | currentTraffic.downloadTraffic += byteCount;
28 | totalTraffic.downloadTraffic += byteCount;
29 | }
30 |
31 | public synchronized TrafficInfo resetCurrentTrafficInfo() {
32 | TrafficInfo info = currentTraffic;
33 | currentTraffic = new TrafficInfo(iName);
34 | return info;
35 | }
36 |
37 | public synchronized TrafficInfo resetTotalTrafficInfo() {
38 | TrafficInfo info = totalTraffic;
39 | totalTraffic = new TrafficInfo(iName);
40 | return info;
41 | }
42 |
43 | public synchronized TrafficInfo getTotalTraffic(){
44 | return totalTraffic;
45 | }
46 |
47 | public void close() throws IOException {
48 | channel.close();
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/TransferIdentifiers.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | public class TransferIdentifiers {
4 | public static final short END_POINT = -1;
5 | public static final short FILE = 0;
6 | public static final short FOLDER = 1;
7 | public static final short FILE_SLICE = 2;
8 | public static final short EOF = 3;
9 | public static final short END_OF_INTERRUPTED = 4;
10 | public static final short END_OF_READ_ERROR = 5;
11 | public static final short END_OF_WRITE_ERROR = 6;
12 | }
13 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/Utils.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core;
2 |
3 | import java.io.File;
4 | import java.text.SimpleDateFormat;
5 | import java.util.ArrayList;
6 | import java.util.Date;
7 | import java.util.List;
8 | import java.util.Locale;
9 |
10 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
11 |
12 | public class Utils {
13 | public static final String ILLEGAL_CHARACTERS = "<>:\"/\\|?*";
14 |
15 | public static void sortFiles(List fileList) {
16 | // 使用Comparator自定义比较规则
17 | fileList.sort((f1, f2) -> {
18 | // 文件夹优先于文件
19 | if (f1.isDirectory() && !f2.isDirectory()) {
20 | return -1;
21 | } else if (!f1.isDirectory() && f2.isDirectory()) {
22 | return 1;
23 | } else {
24 | // 如果类型相同,则按名称排序
25 | return f1.getName().compareTo(f2.getName());
26 | }
27 | });
28 | }
29 |
30 | public static String formatSpeed(long bytesPerSecond) {
31 | if (bytesPerSecond < 1024) {
32 | return bytesPerSecond + "B/s";
33 | }
34 | if (bytesPerSecond < 1024 * 1024) {
35 | return String.format(Locale.getDefault(), "%.2fKB/s", bytesPerSecond / 1024.0);
36 | }
37 | return String.format(Locale.getDefault(), "%.2fMB/s", bytesPerSecond / (1024.0 * 1024.0));
38 | }
39 |
40 | public static String formatDateTime(long milliseconds) {
41 | //格式化为年-月-日 时:分
42 | return new SimpleDateFormat("yy-MM-dd HH:mm", Locale.getDefault()).format(new Date(milliseconds));
43 | }
44 |
45 | /**
46 | * 格式化毫秒数为指定的时间格式。
47 | *
48 | * @param milliseconds 输入的毫秒数
49 | * @return 格式化后的时间字符串
50 | */
51 | public static String formatTime(long milliseconds) {
52 | if (milliseconds < 0) {
53 | throw new IllegalArgumentException("毫秒数不能为负数");
54 | }
55 |
56 | if (milliseconds < 1000) {
57 | return milliseconds + "ms";
58 | }
59 |
60 | long totalSeconds = milliseconds / 1000;
61 | long hours = totalSeconds / 3600;
62 | long minutes = (totalSeconds % 3600) / 60;
63 | long seconds = totalSeconds % 60;
64 |
65 | if (hours == 0) {
66 | return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
67 | } else {
68 | return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
69 | }
70 | }
71 |
72 | public static String formatFileSize(long size) {
73 | if (size < 1024) {
74 | return size + "B";
75 | }
76 | if (size < 1024 * 1024) {
77 | return String.format(Locale.getDefault(), "%.2fKB", size / 1024.0);
78 | }
79 | if (size < 1024 * 1024 * 1024) {
80 | return String.format(Locale.getDefault(), "%.2fMB", size / (1024.0 * 1024.0));
81 | }
82 | return String.format(Locale.getDefault(), "%.2fGB", size / (1024.0 * 1024.0 * 1024.0));
83 | }
84 |
85 | public static boolean containsIllegalCharacters(String text) {
86 | for (char c : ILLEGAL_CHARACTERS.toCharArray()) {
87 | if (text.indexOf(c) >= 0) {
88 | return true; // 如果找到非法字符,返回 true
89 | }
90 | }
91 | return false; // 如果没有找到非法字符,返回 false
92 | }
93 |
94 | public static List listRemoteFiles(String path){
95 | File[] files = new File(path).listFiles();
96 | if (files == null) {
97 | return null;
98 | }
99 | ArrayList remoteFiles = new ArrayList<>(files.length);
100 | for (File file : files) {
101 | remoteFiles.add(new RemoteFile(file));
102 | }
103 | return remoteFiles;
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/RemoteFile.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.bean;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import java.io.File;
6 |
7 | public class RemoteFile {
8 | protected final String name;
9 | protected final String path;
10 | protected final long lastModified;
11 | protected final long size;
12 | protected final boolean isDirectory;
13 | //public final String name;
14 | //public final String path;
15 | //public final long lastModified;
16 | //public final long size;
17 | //public final boolean isDirectory;
18 |
19 | public RemoteFile(File file) {
20 | this.path = file.getPath();
21 | this.isDirectory = file.isDirectory();
22 | this.name = file.getName();
23 | this.lastModified = file.lastModified();
24 | this.size = file.length();
25 | }
26 |
27 | public RemoteFile(String name, String path, long lastModified, long size, boolean isDirectory){
28 | this.name = name;
29 | this.path = path;
30 | this.lastModified = lastModified;
31 | this.size = size;
32 | this.isDirectory = isDirectory;
33 | }
34 |
35 | public RemoteFile(RemoteFile file){
36 | this.name = file.name;
37 | this.path = file.path;
38 | this.lastModified = file.lastModified;
39 | this.size = file.size;
40 | this.isDirectory = file.isDirectory;
41 | }
42 |
43 |
44 | @NotNull
45 | @Override
46 | public String toString() {
47 | return "RemoteFile{" +
48 | "path='" + path + '\'' +
49 | ", isDirectory=" + isDirectory +
50 | '}';
51 | }
52 |
53 | public String getPath() {
54 | return path;
55 | }
56 |
57 | public boolean isDirectory() {
58 | return isDirectory;
59 | }
60 |
61 | public String getName() {
62 | return name;
63 | }
64 |
65 | public long lastModified() {
66 | return lastModified;
67 | }
68 |
69 | public long getSize() {
70 | return size;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/ServerNetInterface.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.bean;
2 |
3 |
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.net.InetAddress;
7 |
8 | public class ServerNetInterface{
9 | public final String name;
10 | public final InetAddress address;
11 | public final InetAddress clientBindAddress;
12 |
13 | public ServerNetInterface(String name, InetAddress address, InetAddress clientBindAddress) {
14 | this.name = name;
15 | this.address = address;
16 | this.clientBindAddress = clientBindAddress;
17 | }
18 |
19 |
20 | @NotNull
21 | @Override
22 | public String toString() {
23 | return "ServerNetInterface{" +
24 | "name='" + name + '\'' +
25 | ", address=" + address +
26 | ", clientBindAddress=" + clientBindAddress +
27 | '}';
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/bean/TrafficInfo.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.bean;
2 |
3 | public class TrafficInfo {
4 | public String iName;
5 | public long uploadTraffic;
6 | public long downloadTraffic;
7 |
8 | public TrafficInfo(String iName, long uploadTraffic, long downloadTraffic) {
9 | this.iName = iName;
10 | this.uploadTraffic = uploadTraffic;
11 | this.downloadTraffic = downloadTraffic;
12 | }
13 | public TrafficInfo() {
14 | }
15 | public TrafficInfo(String iName) {
16 | this.iName = iName;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/callback/ClientCallBack.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.callback;
2 |
3 | public interface ClientCallBack extends TransferFileCallback {
4 | void onReceiving();
5 | void onSending();
6 | void onExit();
7 | }
8 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/callback/ConnectServerCallback.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.callback;
2 |
3 | import java.net.InetAddress;
4 | import java.util.List;
5 |
6 | public interface ConnectServerCallback {
7 | void onConnectingControlChannel(String address, int port);
8 |
9 | void onVersionMismatch(int localVersion, int remoteVersion);
10 |
11 | void onConnectControlFailed();
12 |
13 | void onConnectingTransferChannel(
14 | String name,
15 | InetAddress inetAddress,
16 | InetAddress bindAddress);
17 |
18 | void onConnectTransferChannelFailed(String name, InetAddress inetAddress, Exception e);
19 |
20 | void onOOM(
21 | int createdBuffers,
22 | int requiredBuffers,
23 | long maxMemoryMB,
24 | String osArch);
25 |
26 | void onRemoteOOM();
27 |
28 | void onConnectSuccess(List channelNames);
29 | }
30 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/core/callback/TransferFileCallback.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.core.callback;
2 |
3 | import java.util.List;
4 |
5 | import top.weixiansen574.hybridfilexfer.core.bean.TrafficInfo;
6 |
7 | public interface TransferFileCallback {
8 | int ERROR_TYPE_EXCEPTION = 1;
9 | int ERROR_TYPE_INTERRUPT = 2;
10 | int ERROR_TYPE_READ_ERROR = 3;
11 | int ERROR_TYPE_WRITE_ERROR = 4;
12 |
13 | void onFileUploading(String iName, String path, long targetSize, long totalSize);
14 |
15 | void onFileDownloading(String iName, String path, long targetSize, long totalSize);
16 |
17 | void onSpeedInfo(List trafficInfoList);
18 |
19 | void onChannelComplete(String iName, long traffic, long time);
20 |
21 | void onChannelError(String iName, int errorType, String message);//异常信息 or 断开
22 |
23 | void onReadFileError(String message);
24 |
25 | void onWriteFileError(String message);
26 |
27 | void onComplete(boolean isUpload,long traffic, long time);
28 |
29 | //传输通道有其中一个断开时
30 | void onIncomplete();
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/jdkcore/JdkHFXClient.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.jdkcore;
2 |
3 | import top.weixiansen574.hybridfilexfer.core.HFXClient;
4 | import top.weixiansen574.hybridfilexfer.core.ReadFileCall;
5 | import top.weixiansen574.hybridfilexfer.core.Utils;
6 | import top.weixiansen574.hybridfilexfer.core.WriteFileCall;
7 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
8 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
9 |
10 | import java.io.File;
11 | import java.nio.ByteBuffer;
12 | import java.util.List;
13 | import java.util.concurrent.LinkedBlockingDeque;
14 |
15 | public class JdkHFXClient extends HFXClient {
16 |
17 | public JdkHFXClient(String serverControllerAddress, int serverPort, String homeDir) {
18 | super(serverControllerAddress, serverPort, homeDir);
19 | }
20 |
21 | @Override
22 | public ByteBuffer createBuffer(int size) {
23 | return ByteBuffer.allocateDirect(size);
24 | }
25 |
26 | @Override
27 | public long getAvailableMemoryMB() {
28 | return Runtime.getRuntime().maxMemory() / (1024 * 1024);
29 | }
30 |
31 | @Override
32 | protected boolean deleteLocalFile(String path) throws Exception {
33 | File file = new File(path);
34 | if (!file.exists()) {
35 | System.out.println("文件或目录不存在: " + path);
36 | return false;
37 | }
38 |
39 | // 如果是目录,递归删除
40 | if (file.isDirectory()) {
41 | File[] files = file.listFiles();
42 | if (files != null) { // 检查是否为空
43 | for (File subFile : files) {
44 | deleteLocalFile(subFile.getAbsolutePath());
45 | }
46 | }
47 | }
48 |
49 | // 删除文件或空目录
50 | return file.delete();
51 | }
52 |
53 | @Override
54 | protected boolean mkdir(String parent, String child) throws Exception {
55 | return new File(parent,child).mkdirs();
56 | }
57 |
58 | @Override
59 | protected List listFiles(String path) throws Exception {
60 | return Utils.listRemoteFiles(path);
61 | }
62 |
63 | @Override
64 | protected WriteFileCall createWriteFileCall(LinkedBlockingDeque buffers, int dequeCount) {
65 | return new JdkWriteFileCall(buffers,dequeCount);
66 | }
67 |
68 | @Override
69 | protected ReadFileCall createReadFileCall(LinkedBlockingDeque buffers, List files, Directory localDir, Directory remoteDir, int operateThreadCount) {
70 | return new JdkReadFileCall(buffers,files,localDir,remoteDir,operateThreadCount);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/jdkcore/JdkReadFileCall.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.jdkcore;
2 |
3 | import top.weixiansen574.hybridfilexfer.core.ReadFileCall;
4 | import top.weixiansen574.hybridfilexfer.core.Utils;
5 | import top.weixiansen574.hybridfilexfer.core.bean.Directory;
6 | import top.weixiansen574.hybridfilexfer.core.bean.RemoteFile;
7 |
8 | import java.io.File;
9 | import java.io.RandomAccessFile;
10 | import java.nio.ByteBuffer;
11 | import java.nio.channels.FileChannel;
12 | import java.util.List;
13 | import java.util.concurrent.LinkedBlockingDeque;
14 |
15 | public class JdkReadFileCall extends ReadFileCall {
16 | private RandomAccessFile randomAccessFile;
17 | private FileChannel channel;
18 |
19 | public JdkReadFileCall(LinkedBlockingDeque buffers, List files, Directory localDir, Directory remoteDir, int operateThreadCount) {
20 | super(buffers, files, localDir, remoteDir, operateThreadCount);
21 | }
22 |
23 | @Override
24 | protected boolean fileExists(String path) throws Exception {
25 | return new File(path).exists();
26 | }
27 |
28 | @Override
29 | protected List listFiles(String path) throws Exception {
30 | return Utils.listRemoteFiles(path);
31 | }
32 |
33 | @Override
34 | protected FileChannel openFile(String path) throws Exception {
35 | randomAccessFile = new RandomAccessFile(path, "r");
36 | channel = randomAccessFile.getChannel();
37 | return channel;
38 | }
39 |
40 | @Override
41 | protected void closeFile() throws Exception {
42 | channel.close();
43 | randomAccessFile.close();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/src/top/weixiansen574/hybridfilexfer/jdkcore/JdkWriteFileCall.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.hybridfilexfer.jdkcore;
2 |
3 | import top.weixiansen574.hybridfilexfer.core.WriteFileCall;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 | import java.io.RandomAccessFile;
8 | import java.nio.ByteBuffer;
9 | import java.nio.channels.FileChannel;
10 | import java.util.concurrent.LinkedBlockingDeque;
11 |
12 | public class JdkWriteFileCall extends WriteFileCall {
13 | private RandomAccessFile file;
14 | private FileChannel channel;
15 |
16 | public JdkWriteFileCall(LinkedBlockingDeque buffers, int dequeCount) {
17 | super(buffers, dequeCount);
18 | }
19 |
20 | @Override
21 | protected void createParentDirIfNotExists(String path) throws Exception {
22 | File file = new File(path);
23 | File parentFile = file.getParentFile();
24 | //如果就是根目录的情况
25 | if (parentFile == null) {
26 | return;
27 | }
28 | mkdirOrThrow(parentFile);
29 | }
30 |
31 | @Override
32 | protected void tryMkdirs(String path) throws Exception {
33 | mkdirOrThrow(new File(path));
34 | }
35 |
36 | @Override
37 | protected FileChannel createAndOpenFile(String path, long length) throws Exception {
38 | file = new RandomAccessFile(path, "rw");
39 | file.setLength(length);
40 | channel = file.getChannel();
41 | return channel;
42 | }
43 |
44 | @Override
45 | protected void closeFile() throws Exception {
46 | channel.close();
47 | file.close();
48 | }
49 |
50 | @Override
51 | protected boolean setFileLastModified(String path, long time) throws Exception {
52 | return new File(path).setLastModified(time);
53 | }
54 |
55 | private void mkdirOrThrow(File file) throws IOException {
56 | if (file.exists()) {
57 | //如果存在且是一个文件则删除再创建成文件夹
58 | if (file.isFile()) {
59 | if (file.delete()) {
60 | if (!file.mkdirs()) {
61 | throw new IOException("cannot mkdirs " + file);
62 | }
63 | } else {
64 | throw new IOException("cannot delete file " + file);
65 | }
66 | }
67 | } else {
68 | if (!file.mkdirs()) {
69 | throw new IOException("cannot mkdirs " + file);
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/HybridFileXfer-PC/start.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/HybridFileXfer-PC/start.exe
--------------------------------------------------------------------------------
/IMG_20241125_235527.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/IMG_20241125_235527.jpg
--------------------------------------------------------------------------------
/PixPin_2024-04-15_20-42-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/PixPin_2024-04-15_20-42-19.png
--------------------------------------------------------------------------------
/PixPin_2024-04-15_20-45-49.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/PixPin_2024-04-15_20-45-49.png
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-13-20-59-747_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-13-20-59-747_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-13-21-20-325_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-13-21-20-325_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-13-59-51-358_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-13-59-51-358_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-14-00-12-221_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-14-00-12-221_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-14-16-19-518_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-14-16-19-518_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-14-16-22-997_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-14-16-22-997_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/Screenshot_2024-10-13-14-20-12-558_top.weixiansen574.hybridfilexfer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/Screenshot_2024-10-13-14-20-12-558_top.weixiansen574.hybridfilexfer.jpg
--------------------------------------------------------------------------------
/script/USB-forward.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | chcp 65001
3 | setlocal enabledelayedexpansion
4 |
5 | :: Constants
6 | set PORT=5740
7 |
8 | :: Get the list of devices (skip the header line)
9 | set deviceCount=0
10 | for /f "skip=1 tokens=1" %%a in ('adb devices') do (
11 | if not "%%a"=="" (
12 | :: Exclude empty lines
13 | set /a deviceCount+=1
14 | set "device[!deviceCount!]=%%a"
15 | )
16 | )
17 |
18 | :: Check if exactly two devices are connected
19 | if %deviceCount% neq 2 (
20 | echo Detected devices: %deviceCount%. Please connect exactly two phones!
21 | echo Connected devices:
22 | for /L %%i in (1,1,%deviceCount%) do (
23 | call :printDeviceName !device[%%i]!
24 | )
25 | pause
26 | exit /b
27 | )
28 |
29 | :: Get the display names of the two devices (format: DeviceName:DeviceID)
30 | call :getDeviceDisplay 1 deviceDisplay1
31 | call :getDeviceDisplay 2 deviceDisplay2
32 |
33 | echo.
34 | echo Please select the device to be Phone A (server):
35 | echo 1. %deviceDisplay1%
36 | echo 2. %deviceDisplay2%
37 | set /p choice=Enter a number (1 or 2):
38 |
39 | if "%choice%"=="1" (
40 | set "deviceA=%device[1]%"
41 | set "deviceB=%device[2]%"
42 | ) else if "%choice%"=="2" (
43 | set "deviceA=%device[2]%"
44 | set "deviceB=%device[1]%"
45 | ) else (
46 | echo Invalid selection, exiting.
47 | pause
48 | exit /b
49 | )
50 |
51 | echo.
52 | echo Selected Phone A: %deviceA%
53 | echo Selected Phone B: %deviceB%
54 |
55 | echo.
56 | echo Setting up port forwarding...
57 | adb -s %deviceA% forward tcp:%PORT% tcp:%PORT%
58 | adb -s %deviceB% reverse tcp:%PORT% tcp:%PORT%
59 |
60 | echo.
61 | echo Port forwarding setup complete!
62 | pause
63 | exit /b
64 |
65 | :printDeviceName
66 | :: Parameter: Device ID, output format: DeviceName:DeviceID
67 | setlocal
68 | set "devID=%1"
69 | for /f "delims=" %%n in ('adb -s %devID% shell settings get global device_name 2^>nul') do (
70 | set "devName=%%n"
71 | goto afterLoop2
72 | )
73 | :afterLoop2
74 | if "%devName%"=="" set "devName=Unknown"
75 | echo %devName%:%devID%
76 | endlocal
77 | goto :eof
78 |
79 | :getDeviceDisplay
80 | :: Parameter 1: Device index; Parameter 2: Output variable name
81 | setlocal
82 | set "devID="
83 | set "devID=!device[%1]!"
84 | for /f "delims=" %%n in ('adb -s !devID! shell settings get global device_name 2^>nul') do (
85 | set "devName=%%n"
86 | goto afterLoop
87 | )
88 | :afterLoop
89 | if "!devName!"=="" set "devName=Unknown"
90 | endlocal & set "%2=%devName%:!device[%1]!"
91 | goto :eof
92 |
--------------------------------------------------------------------------------
/script/USB-forward.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PORT=5740
4 |
5 | # 获取设备列表(跳过标题行)
6 | devices=($(adb devices | awk 'NR>1 {print $1}' | grep -v "^$"))
7 | device_count=${#devices[@]}
8 |
9 | # 检查是否连接了两个设备
10 | if [ $device_count -ne 2 ]; then
11 | echo "Detected devices: $device_count. Please connect exactly two phones!"
12 | echo "Connected devices:"
13 | for dev_id in "${devices[@]}"; do
14 | dev_name=$(adb -s "$dev_id" shell 'settings get global device_name 2>/dev/null' | tr -d '\r')
15 | echo "${dev_name:-Unknown}:$dev_id"
16 | done
17 | read -n1 -p "Press any key to exit..."
18 | exit 1
19 | fi
20 |
21 | # 获取设备显示名称
22 | get_device_display() {
23 | local dev_id=$1
24 | local dev_name=$(adb -s "$dev_id" shell 'settings get global device_name 2>/dev/null' | tr -d '\r')
25 | echo "${dev_name:-Unknown}:$dev_id"
26 | }
27 |
28 | # 显示设备选择菜单
29 | echo
30 | echo "Please select the device to be Phone A (server):"
31 | echo "1. $(get_device_display "${devices[0]}")"
32 | echo "2. $(get_device_display "${devices[1]}")"
33 | read -n1 -p "Enter a number (1 or 2): " choice
34 | echo
35 |
36 | # 处理用户选择
37 | case $choice in
38 | 1)
39 | deviceA=${devices[0]}
40 | deviceB=${devices[1]}
41 | ;;
42 | 2)
43 | deviceA=${devices[1]}
44 | deviceB=${devices[0]}
45 | ;;
46 | *)
47 | echo "Invalid selection, exiting."
48 | read -n1 -p "Press any key to exit..."
49 | exit 1
50 | ;;
51 | esac
52 |
53 | echo
54 | echo "Selected Phone A: $deviceA"
55 | echo "Selected Phone B: $deviceB"
56 |
57 | # 设置端口转发
58 | echo
59 | echo "Setting up port forwarding..."
60 | adb -s "$deviceA" forward tcp:$PORT tcp:$PORT
61 | adb -s "$deviceB" reverse tcp:$PORT tcp:$PORT
62 |
63 | echo
64 | echo "Port forwarding setup complete!"
65 | read -n1 -p "Press any key to exit..."
66 | exit 0
--------------------------------------------------------------------------------
/script/USB-forward_中文.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | :: 避免其他繁体中文的电脑乱码
3 | chcp 65001
4 | setlocal enabledelayedexpansion
5 |
6 | :: 常量设置
7 | set PORT=5740
8 |
9 | :: 获取设备列表(跳过标题行)
10 | set deviceCount=0
11 | for /f "skip=1 tokens=1" %%a in ('adb devices') do (
12 | if not "%%a"=="" (
13 | :: 排除空行
14 | set /a deviceCount+=1
15 | set "device[!deviceCount!]=%%a"
16 | )
17 | )
18 |
19 | :: 检查是否有两部设备
20 | if %deviceCount% neq 2 (
21 | echo 检测到的设备数量为 %deviceCount%,请同时连接两部手机!
22 | echo 已连接设备:
23 | for /L %%i in (1,1,%deviceCount%) do (
24 | call :printDeviceName !device[%%i]!
25 | )
26 | pause
27 | exit /b
28 | )
29 |
30 | :: 获取两个设备的显示名称(格式:设备名:设备ID)
31 | call :getDeviceDisplay 1 deviceDisplay1
32 | call :getDeviceDisplay 2 deviceDisplay2
33 |
34 | echo.
35 | echo 请选择作为A手机(服务端)的设备:
36 | echo 1. %deviceDisplay1%
37 | echo 2. %deviceDisplay2%
38 | set /p choice=请输入数字 (1或2):
39 |
40 | if "%choice%"=="1" (
41 | set "deviceA=%device[1]%"
42 | set "deviceB=%device[2]%"
43 | ) else if "%choice%"=="2" (
44 | set "deviceA=%device[2]%"
45 | set "deviceB=%device[1]%"
46 | ) else (
47 | echo 无效选择,退出.
48 | pause
49 | exit /b
50 | )
51 |
52 | echo.
53 | echo 选择的A手机: %deviceA%
54 | echo 选择的B手机: %deviceB%
55 |
56 | echo.
57 | echo 正在设置端口转发...
58 | adb -s %deviceA% forward tcp:%PORT% tcp:%PORT%
59 | adb -s %deviceB% reverse tcp:%PORT% tcp:%PORT%
60 |
61 | echo.
62 | echo 端口转发设置完成!
63 | pause
64 | exit /b
65 |
66 | :printDeviceName
67 | :: 参数:设备ID,输出格式为:设备名:设备ID
68 | setlocal
69 | set "devID=%1"
70 | for /f "delims=" %%n in ('adb -s %devID% shell settings get global device_name 2^>nul') do (
71 | set "devName=%%n"
72 | goto afterLoop2
73 | )
74 | :afterLoop2
75 | if "%devName%"=="" set "devName=Unknown"
76 | echo %devName%:%devID%
77 | endlocal
78 | goto :eof
79 |
80 | :getDeviceDisplay
81 | :: 参数1:设备序号;参数2:返回变量名称
82 | setlocal
83 | set "devID="
84 | set "devID=!device[%1]!"
85 | for /f "delims=" %%n in ('adb -s !devID! shell settings get global device_name 2^>nul') do (
86 | set "devName=%%n"
87 | goto afterLoop
88 | )
89 | :afterLoop
90 | if "!devName!"=="" set "devName=Unknown"
91 | endlocal & set "%2=%devName%:!device[%1]!"
92 | goto :eof
93 |
--------------------------------------------------------------------------------
/script/launch-android-app.bat:
--------------------------------------------------------------------------------
1 | adb shell am start -n top.weixiansen574.hybridfilexfer/.MainActivity
--------------------------------------------------------------------------------
/script/start-by-adb.bat:
--------------------------------------------------------------------------------
1 | chcp 65001
2 | java -jar -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 HybridFileXfer.jar -c adb
3 | pause
--------------------------------------------------------------------------------
/script/start-by-network.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | chcp 65001
3 | set /p IPAddress=Please enter the phone's IP address:
4 | echo The IP address you entered is: %IPAddress%
5 |
6 | java -jar -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 HybridFileXfer.jar -c %IPAddress%
7 | pause
8 |
--------------------------------------------------------------------------------
/手机对传.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/HybridFileXfer/fd0755c90c99f43a2eb2dc7f62d399072e04da73/手机对传.jpg
--------------------------------------------------------------------------------
/赞助名单.md:
--------------------------------------------------------------------------------
1 | # 赞助名单
2 |
3 | | Github账号 | 金额¥ | 日期 |
4 | | ------------------------------------------------------------ | ------ | ---------------------- |
5 | | [@long45343](https://github.com/long45343) | 10.00 | 2024-05-13 00:22:48 |
6 | | [匿名] | 2.00 | 2024年5月20日 06:55:08 |
7 | | [匿名] | 1.10 | 2024年6月8日 09:41:41 |
8 | | [无法识别的备注:双轨快传ID是[L07-31](https://github.com/L07-31)前有共15] | 14.37 | 2024年6月10日 01:28:51 |
9 | | [无法识别的备注:双轨快传ID是[L07-31](https://github.com/L07-31)前有共15] | 0.64 | 2024年6月10日 01:35:26 |
10 | | [@香菜和葱](https://github.com/825824004) | 6.66 | 2024-06-14 00:16:44 |
11 | | [匿名] | 10.00 | 2024-07-04 17:56:32 |
12 | | [@freemedom](https://github.com/freemedom) | 10.00 | 2024-07-25 16:18:52 |
13 | | [@freemedom](https://github.com/freemedom):希望解决issue35 36 | 10.00 | 2024-07-25 16:19:39 |
14 | | [@breathiness](https://github.com/breathiness) | 50.00 | 2024-07-28 14:21:47 |
15 | | [匿名] | 5.00 | 2024-09-07 00:35:07 |
16 | | [匿名] | 5.00 | 2024-09-22 20:55:57 |
17 | | [匿名] | 2.10 | 2025-01-02 13:31:51 |
18 | | [匿名] | 1.00 | 2025-01-20 13:50:07 |
19 | | [@cpp-deep-learning](https://github.com/cpp-deep-learning) | 10.00 | 2025-02-07 12:14:43 |
20 | | [@cpp-deep-learning](https://github.com/cpp-deep-learning) | 0.01 | 2025-02-07 12:15:24 |
21 |
22 |
--------------------------------------------------------------------------------