-
Notifications
You must be signed in to change notification settings - Fork 0
Español
Una aplicación nativa para Android en Java desarrollada de forma independiente para la transferencia de archivos en red local (LAN), cuyo objetivo es ofrecer compatibilidad con la detección de dispositivos y la API de carga de LocalSend Protocol v2.2 en sistemas antiguos (desde Android 2.3 hasta Android 6.0 / API 9 a API 23). El proyecto no referencia, importa ni compila directorios de código fuente de LocalSend.
Versión actual: 1.3 (versionCode 5).
Los archivos APK precompilados están disponibles para su descarga e instalación directa desde la página de GitHub Releases de este repositorio, por lo que no es necesario compilar manualmente. Las entregas incluyen firma v1 lista para su instalación directa en dispositivos legados (Android 2.3 a 6.0).
Si deseas compilar el proyecto manualmente, se requiere el siguiente entorno:
- JDK 17
- Gradle Wrapper 8.9
- Android Gradle Plugin 8.7.3
- Android SDK Platform 23 (Android 6.0 Marshmallow)
- Android SDK Build Tools 23.0.3 (o superior)
Comando de compilación y verificación:
./gradlew testDebugUnitTest lintDebug assembleDebug
Ruta de salida del APK compilado:
app/build/outputs/apk/debug/app-debug.apk
El proyecto establece un minSdkVersion de 9, un compileSdkVersion de 23 y un targetSdkVersion de 23 (Android 6.0 Marshmallow). Esto garantiza un entorno de compilación liviano y unificado, totalmente alineado con los permisos de almacenamiento y servicios de la era clásica de Android. Este proyecto está diseñado exclusivamente para hardware legado y no está destinado a publicarse en Google Play.
- Descubrimiento de dispositivos, anuncios y respuestas mediante multicast UDP.
- Interfaz de registro HTTP/HTTPS compatible con LocalSend v2 (v2.2).
- Soporte para codificación de transferencia por bloques (
Chunked Transfer Encoding). - Selección, envío y recepción de archivos individuales y múltiples.
- Confirmación (Aceptar / Rechazar) previa a la recepción.
- Verificación de tokens por archivo, ID de sesión, IP de origen y huella digital de certificado.
- Carga y guardado en flujo de datos (streaming) sin cargar archivos completos en memoria.
- Progreso general, notificaciones de fallo y cancelación por cualquiera de las partes.
- Renombrado automático con sufijos
(1),(2)para evitar sobrescrituras. - Compatibilidad con nombres de archivo con caracteres chinos, espacios y caracteres especiales.
- Servicio de recepción en primer plano; la recreación de la Activity no interrumpe la transferencia en curso.
- Interfaz de usuario traducida a chino simplificado.
app/src/main/java/com/blithe/legacysend/
├── LegacySendApp.java Estado a nivel de aplicación, tareas en segundo plano y eventos de UI
├── ReceiveService.java Servicio de recepción en primer plano
├── discovery/ Descubrimiento por multicast UDP
├── model/ Modelos de datos para dispositivos y archivos
├── protocol/ Formatos JSON de LocalSend (v2.2)
├── security/ Identidad autofirmada, BKS KeyStore, mTLS, fijado de certificados, SimpleX509Generator
├── server/ Endpoints HTTP/HTTPS (registro, preparación, carga, cancelación)
├── storage/ Manejo de almacenamiento con SAF, sistema de archivos legado y renombrado
├── transfer/ Cliente de envío HTTPS/HTTP, control de progreso y cancelación
├── ui/ Interfaz de usuario nativa en Android Views
└── util/ Utilidades para copiado en flujo y control de velocidad
El código fuente está escrito 100% en Java, sin dependencias de Kotlin, Jetpack Compose, Flutter, Dart o React Native. Se utiliza Groovy DSL para Gradle.
- Soporte para minSdk 9 (Android 2.3) hasta Android 6.0 (API 23): Cobertura completa enfocada en hardware y firmware antiguo.
-
Generación de certificados en API 9–17: Implementación de
SimpleX509Generatorpara resolver la ausencia deAndroidKeyStorey la estricta validación ASN.1/DER de OpenSSL / Conscrypt en Android 2.3–4.2. -
Formato BKS KeyStore: Uso de
BouncyCastle(BKS) en API 9–17 para almacenar claves y certificados privados, evitando fallos de serializaciónPKCS12en Android 2.3. -
Corrección de Estructura ASN.1 / DER: Envoltura
SEQUENCEagregada al parAttributeTypeAndValuedentro de la jerarquía de certificados y cambio explícito del tipo de cadena decommonName(2.5.4.3) aPrintableString(0x13), solucionando definitivamente la excepciónASN.1 encoding routines:OPENSSL_internal:WRONG_TAG. -
Mitigación del efecto Y2K38: Los certificados autofirmados en API 9–17 utilizan firmas
SHA1withRSAy un periodo de validez limitado a 10 años para evitar desbordamientos de tiempo de 32 bits. -
Acceso a Archivos Legado y SAF: Se utiliza
ACTION_OPEN_DOCUMENTcon SAF en API 19–23, mientras que API 9–18 recurre a un explorador de archivos interno para leer el almacenamiento externo directamente. -
Compatibilidad TLS en Recepción para Android 4.4.2 (API 19–20): El servidor TLS 1.2 de Kindle Android 4.4.2 solo soporta cifrados CBC, incompatibles con el cliente TLS en Rust de LocalSend 1.17.0. En API 19–20 se utiliza la modalidad oficial
protocol: "http", mientras que API 9–18 y API 21–23 mantienen HTTPS para recepción y envíos salientes. -
Rutas de Guardado: Almacenamiento en el directorio público
Download/LegacySenden todo el rango soportado (API 9–23). -
MulticastLock y Subprocesos: Escucha de multicast asegurada tras adquirir
MulticastLock; todas las operaciones de red e E/S de archivos se ejecutan en hilos secundarios. - Procesamiento de Flujo: Transferencia con búfer de 32 KiB compatible con Chunked Streaming, validando la coherencia entre el tamaño real recibido y los metadatos.
- Notificaciones: Servicio en primer plano con notificaciones tradicionales para todo el rango de API 9 a 23.
Sin dependencias de terceros en tiempo de ejecución. Únicamente utiliza el SDK de Android, la librería estándar de Java y org.json (incluido en el sistema operativo).
Dependencias de prueba:
- JUnit 4.13.2: Ejecutado únicamente en la JVM del host (no empaquetado en el APK).
-
org.json:json:20240303: Implementación para pruebas unitarias en la JVM (no empaquetado en el APK).
- 12 pruebas unitarias en host: serialización del protocolo, metadatos multiarchivo, caracteres especiales/chinos, confirmaciones/cancelaciones/tiempos de espera, renombrado, cálculo de hash SHA-256 y copiado en flujo.
- Compilación Gradle, inspección Lint y empaquetado de APK debug.
- Verificación del manifiesto APK validando
minSdkVersion=9,compileSdkVersion=23ytargetSdkVersion=23. - Validación de firmas APK v1/v2 (firma v1 lista para instalación en Android 2.3, 4.4.2 y hasta 6.0).
-
Prueba Real en Android 2.3.6 (API 9): Generación exitosa de certificados (sin excepción
WRONG_TAG), inicio del servicio HTTPS en el puerto 53317, descubrimiento correcto del cliente oficial de LocalSend, y recepción/escritura en disco por Chunked Upload con verificación SHA-256 idéntica. - Prueba Real en Kindle Android 4.4.2 (API 19): Inicio, selección interna de archivos, envío exitoso hacia Android 11 y recepción exitosa desde LocalSend 1.17.0 oficial con validación de hash SHA-256.
La aplicación DocumentsUI de la GPU de Kindle conserva registros de descargas eliminadas o movidas, arrojando excepciones FileNotFoundException al intentar abrir sus URIs content://. En API 9–20 se utiliza un explorador interno que lista directamente los archivos reales del almacenamiento; API 21–23 continúa usando el SAF del sistema.
- Cambios frecuentes de red Wi-Fi en hardware real, restricciones agresivas de batería de fabricantes y transferencias de archivos de gran tamaño en Android 5.0–6.0.
- LocalSend Reverse Download API (descargas web desde navegador); la API Upload principal de Android a LocalSend no depende de esto.
- Funciones secundarias como PIN, historial, portapapeles, temas, actualizaciones automáticas o cuentas.
- Escaneo alternativo por subred IP; actualmente se utiliza descubrimiento por multicast predeterminado y registro bidireccional mediante
/register.
- Android Emulator 36 en arquitectura Apple Silicon no soporta imágenes ARMv7 QEMU2 para API 9 o API 19.
Debido a la falta de cifrados en común entre el servidor TLS de Android 4.4 y el cliente Rust de LocalSend 1.17.0, la recepción en API 19–20 opera bajo el modo HTTP oficial del protocolo. En esta dirección, los archivos y metadatos no viajan cifrados por TLS, aunque se mantienen las verificaciones de IP de origen, ID de sesión y tokens únicos por archivo. Se recomienda su uso exclusivo en redes locales de confianza. Todos los envíos salientes desde LegacySend y la recepción en API 9–18 y API 21–23 mantienen cifrado HTTPS y fijado de certificados.
Para detalles adicionales sobre la especificación y los endpoints, consulta [docs/protocol.md](https://www.google.com/search?q=docs/protocol.md).
Los Issues y Pull Requests son bienvenidos. El objetivo principal de LegacySend es ofrecer una solución ligera, estable e interoperable con LocalSend (v2.2) en dispositivos legados (Android 2.3 a Android 6.0 / API 9 a API 23). Se priorizará la compatibilidad con sistemas antiguos sobre la adición de nuevas características.
- Mantener la implementación independiente sin copiar ni incluir código fuente de LocalSend.
- Utilizar exclusivamente Java y vistas nativas de Android (evitar Kotlin, Jetpack Compose, Flutter o Google Play Services).
- Preservar la compatibilidad enfocada estrictamente en el rango
minSdkVersion 9atargetSdkVersion 23. - Ejecutar todas las operaciones de red e E/S de archivos en hilos secundarios utilizando flujos de datos (streaming).
- Verificar el comportamiento en el rango objetivo antes de enviar cambios significativos.