Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f247f9ddee | ||
|
|
8921d7f2a6 | ||
|
|
93dbe0941e | ||
|
|
22d2cf9eda | ||
|
|
d2c3041b0a | ||
|
|
77c417117a | ||
|
|
2c65578bdd | ||
|
|
6aef195f30 | ||
|
|
cc4696dec2 | ||
|
|
73a4f81341 | ||
|
|
adadb89232 | ||
|
|
d326f4c549 | ||
|
|
84f19449b5 | ||
|
|
60f5830ac3 | ||
|
|
8fc8991efa | ||
|
|
cf11aa04bc | ||
|
|
d2d66a7906 | ||
|
|
5ade6350eb | ||
|
|
96c4c360ee | ||
|
|
ab43ce7794 | ||
|
|
24a4c93fb5 | ||
|
|
eba119493c | ||
|
|
87780cddee | ||
|
|
672774e216 | ||
|
|
e6b4d0825b | ||
|
|
d861eca52f | ||
|
|
701b710acc | ||
|
|
81da7510ef |
+138
-9
@@ -1,13 +1,142 @@
|
||||
# Gradle files
|
||||
.gradle/
|
||||
gradle-app.setting
|
||||
!gradle-wrapper.jar
|
||||
!.gradle
|
||||
gradlew
|
||||
gradlew.bat
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
|
||||
# Gradle generated files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Signing files
|
||||
.signing/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
.idea/.name
|
||||
.idea/compiler.xml
|
||||
.idea/copyright/profiles_settings.xml
|
||||
.idea/encodings.xml
|
||||
.idea/misc.xml
|
||||
.idea/modules.xml
|
||||
.idea/scopes/scope_settings.xml
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
.idea/datasources.xml
|
||||
.idea/dataSources.ids
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
.idea/*.xml
|
||||
.idea/copyright/profiles_settings.xml
|
||||
|
||||
# OS-specific files
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Keystore files
|
||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||
#*.jks
|
||||
#*.keystore
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
android-sdk/
|
||||
opus.md
|
||||
opus2.md
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Freeline
|
||||
freeline.py
|
||||
freeline/
|
||||
freeline_project_description.json
|
||||
|
||||
# fastlane
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
fastlane/readme.md
|
||||
|
||||
# Version control
|
||||
vcs.xml
|
||||
|
||||
# lint
|
||||
lint/intermediates/
|
||||
lint/generated/
|
||||
lint/outputs/
|
||||
lint/tmp/
|
||||
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# APK build outputs
|
||||
app/release/
|
||||
app/debug/
|
||||
*.apk
|
||||
|
||||
# Dashboard local files
|
||||
dashboard/node_modules/
|
||||
dashboard/server.log
|
||||
dashboard/config.json
|
||||
|
||||
# Windows desktop project artifacts
|
||||
windows/StreamPlayer.Desktop/.vs/
|
||||
windows/StreamPlayer.Desktop/bin/
|
||||
windows/StreamPlayer.Desktop/obj/
|
||||
windows/StreamPlayer.Desktop/ResolverTest/
|
||||
|
||||
Generated
+1
@@ -0,0 +1 @@
|
||||
StreamPlayer
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+10
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+7
-1
@@ -5,7 +5,13 @@
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="ms-11" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
Generated
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,91 +0,0 @@
|
||||
# StreamPlayer v9.4.2 - Release Notes
|
||||
|
||||
## 📋 Resumen
|
||||
|
||||
Segunda revisión completa del código con **32 mejoras implementadas** y compilación exitosa del APK.
|
||||
|
||||
## 🎯 Cambios Principales
|
||||
|
||||
### 🔧 Configuración y Build
|
||||
- ✅ **Android SDK instalado localmente** (API 33, Build Tools 33.0.2)
|
||||
- ✅ **minifyEnabled=true** y **shrinkResources=true** para optimización de release
|
||||
- ✅ **ProGuard rules** completas para ExoPlayer, OkHttp y Gson
|
||||
- ✅ **Firebase removido** (proyecto de uso personal)
|
||||
- ✅ **StrictMode solo en DEBUG** para evitar penalización en producción
|
||||
|
||||
### 🛠️ Mejoras de Código
|
||||
|
||||
#### Architecture & Performance
|
||||
- ✅ **DiffUtil con AsyncListDiffer** en ChannelAdapter y EventAdapter
|
||||
- ✅ **ExecutorService con shutdown apropiado** en PlayerActivity y EventRepository
|
||||
- ✅ **DNSSetter NetworkCallback** con unregisterCallback para prevenir memory leaks
|
||||
- ✅ **DNS pre-resolution optimization** con flag dnsPreResolved
|
||||
- ✅ **Magic numbers reemplazados** con constantes nombradas
|
||||
|
||||
#### Code Quality
|
||||
- ✅ **JavaDoc documentation** agregada a todas las clases públicas
|
||||
- ✅ **Validación en constructores** (StreamChannel con TextUtils.isEmpty)
|
||||
- ✅ **Logging con Android Log API** (reemplazado System.out.println)
|
||||
- ✅ **Strings externalizadas** a strings.xml (error_stream_fetch, error_playback, etc.)
|
||||
- ✅ **URLs movidas a BuildConfig** (EVENTS_URL, RELEASE_API_URL, DEVICE_REGISTRY_URL)
|
||||
|
||||
#### Bug Fixes
|
||||
- ✅ **Fix método duplicado** en EventAdapter (onCreateViewHolder)
|
||||
- ✅ **Fix syntax error** en build.gradle (closing brace faltante)
|
||||
|
||||
### 📦 Dependencias
|
||||
|
||||
#### Agregadas
|
||||
- ✅ Gson 2.10.1 para JSON parsing
|
||||
- ✅ LeakCanary 2.12 (debug) para detección de memory leaks
|
||||
- ✅ Testing dependencies (JUnit, Mockito, Espresso, Robolectric)
|
||||
|
||||
#### Removidas
|
||||
- ❌ Firebase Crashlytics
|
||||
- ❌ Firebase Analytics
|
||||
- ❌ Firebase Performance
|
||||
- ❌ Google Services plugin
|
||||
|
||||
## 📊 Métricas
|
||||
|
||||
- **APK Size:** ~11 MB (debug build)
|
||||
- **Fixes Aplicados:** 32 de 50 recomendaciones totales
|
||||
- **Issues Críticos Resueltos:** 3/3
|
||||
- **Issues Altos Resueltos:** 2/3
|
||||
- **Cobertura JavaDoc:** +60%
|
||||
|
||||
## 🔍 Issues Restantes (Opcionales)
|
||||
|
||||
Ver `opus2.md` para detalles completos:
|
||||
|
||||
### Medium Priority
|
||||
- Migrar a Media3 (ExoPlayer deprecado)
|
||||
- Implementar Gson parsing en EventRepository
|
||||
- Migrar Thread manual a ExecutorService en DNSSetter
|
||||
- Agregar content descriptions para accesibilidad
|
||||
|
||||
### Low Priority
|
||||
- Crear tests unitarios y de integración
|
||||
- Implementar ViewBinding
|
||||
- Implementar ViewModel con LiveData
|
||||
- Agregar Network Security Config
|
||||
|
||||
## 📱 Instalación
|
||||
|
||||
```bash
|
||||
adb install -r StreamPlayer-v9.4.2-debug.apk
|
||||
```
|
||||
|
||||
## 🔗 Recursos
|
||||
|
||||
- **Repositorio:** https://gitea.cbcren.online/renato97/app
|
||||
- **Branch:** master
|
||||
- **Commit:** Segunda revisión completa con fixes críticos
|
||||
|
||||
## 👨💻 Desarrollador
|
||||
|
||||
**renato97** - [Gitea Profile](https://gitea.cbcren.online/renato97)
|
||||
|
||||
---
|
||||
|
||||
**Nota:** APK compilado en DEBUG mode. Para producción, usar `./gradlew assembleRelease` con signing config apropiado.
|
||||
@@ -1,129 +0,0 @@
|
||||
# StreamPlayer v9.4.3 - Optimización de Calidad
|
||||
|
||||
## 🎯 Objetivo Principal
|
||||
|
||||
**Maximizar la calidad de streaming** para aprovechar resoluciones 720p y 1080p cuando estén disponibles.
|
||||
|
||||
## ⭐ Cambio Destacado
|
||||
|
||||
### Calidad de Video Mejorada 🎬
|
||||
|
||||
**Antes:** ExoPlayer usaba configuración conservadora
|
||||
- WiFi rápido → 480p-720p típicamente
|
||||
- Iniciaba con bitrate bajo y subía lentamente
|
||||
|
||||
**Ahora:** Configuración agresiva para máxima calidad
|
||||
- WiFi rápido → **720p-1080p automáticamente** ✨
|
||||
- Inicia asumiendo HD y se adapta según necesidad
|
||||
|
||||
## 🔧 Implementación Técnica
|
||||
|
||||
### 1. DefaultTrackSelector Optimizado
|
||||
```java
|
||||
.setForceHighestSupportedBitrate(true) // Fuerza máxima calidad
|
||||
.setMaxVideoSize(3840, 2160) // Permite hasta 4K
|
||||
.setMaxVideoBitrate(Integer.MAX_VALUE) // Sin límite de bitrate
|
||||
.setExceedVideoConstraintsIfNecessary(true)
|
||||
```
|
||||
|
||||
**Resultado:** Prioriza automáticamente la mejor calidad disponible en el stream HLS.
|
||||
|
||||
### 2. LoadControl para HD Streaming
|
||||
```java
|
||||
.setBufferDurationsMs(
|
||||
30000, // 30s buffer mínimo (antes: 15s)
|
||||
60000, // 60s buffer máximo (antes: 30s)
|
||||
2000, // Inicio rápido en 2s
|
||||
5000 // Recuperación rápida
|
||||
)
|
||||
```
|
||||
|
||||
**Resultado:** Buffers más grandes previenen interrupciones en alta calidad.
|
||||
|
||||
### 3. Bandwidth Estimator Optimista
|
||||
```java
|
||||
.setInitialBitrateEstimate(5_000_000) // Asume 5 Mbps (HD)
|
||||
```
|
||||
|
||||
**Resultado:** Evita empezar en baja calidad innecesariamente.
|
||||
|
||||
### 4. Quality Logging (Debug)
|
||||
```java
|
||||
Log.i("PlayerActivity",
|
||||
"Reproduciendo: " + width + "x" + height +
|
||||
" @ " + bitrate + " bps");
|
||||
```
|
||||
|
||||
**Resultado:** Verificable en logcat la calidad actual.
|
||||
|
||||
## 📊 Comparativa de Calidad
|
||||
|
||||
| Conexión | Calidad Antes | Calidad Ahora | Mejora |
|
||||
|----------|--------------|---------------|---------|
|
||||
| WiFi 50+ Mbps | 720p | **1080p** | ⬆️⬆️ |
|
||||
| WiFi 10-50 Mbps | 480p-720p | **720p-1080p** | ⬆️ |
|
||||
| 4G/5G | 360p-480p | **480p-720p** | ⬆️ |
|
||||
| 3G | 360p | 360p-480p | = |
|
||||
|
||||
## 📈 Bitrates Típicos
|
||||
|
||||
- **1080p:** 4-8 Mbps (muy nítido)
|
||||
- **720p:** 2-4 Mbps (nítido)
|
||||
- **480p:** 0.5-1.5 Mbps (aceptable)
|
||||
- **360p:** 0.3-0.8 Mbps (pixelado)
|
||||
|
||||
## ⚠️ Consideraciones
|
||||
|
||||
### Consumo de Datos
|
||||
- **1080p:** ~3-4 GB/hora
|
||||
- **720p:** ~1.5-2 GB/hora
|
||||
- **480p:** ~500-800 MB/hora
|
||||
|
||||
### Requisitos
|
||||
- **1080p:** Mínimo 5 Mbps estable
|
||||
- **720p:** Mínimo 2.5 Mbps estable
|
||||
|
||||
## 🔍 Cómo Verificar
|
||||
|
||||
### Método 1: Logcat
|
||||
```bash
|
||||
adb logcat | grep "PlayerActivity"
|
||||
```
|
||||
Verás: `Reproduciendo: 1920x1080 @ 5500000 bps` (ejemplo)
|
||||
|
||||
### Método 2: Visual
|
||||
- **1080p:** Textos pequeños perfectamente legibles
|
||||
- **720p:** Imagen muy nítida
|
||||
- **480p:** Imagen suave, perceptible en TV grande
|
||||
|
||||
## 📝 Archivos Modificados
|
||||
|
||||
- `PlayerActivity.java` - Configuración de ExoPlayer optimizada
|
||||
- `QUALITY_OPTIMIZATION.md` - Documentación técnica completa
|
||||
|
||||
## 🎮 Comportamiento Adaptativo
|
||||
|
||||
1. **Inicio:** Asume buena conexión, busca 1080p
|
||||
2. **Adaptación:** Si hay buffering, baja a 720p
|
||||
3. **Recuperación:** Cuando conexión mejora, vuelve a 1080p
|
||||
4. **Objetivo:** Máxima calidad sostenible
|
||||
|
||||
## 📦 Información Técnica
|
||||
|
||||
- **versionCode:** 94300
|
||||
- **versionName:** 9.4.3
|
||||
- **APK Size:** ~8 MB
|
||||
- **Min SDK:** 21 (Android 5.0)
|
||||
- **Target SDK:** 33 (Android 13)
|
||||
|
||||
## 🚀 Para Usuarios
|
||||
|
||||
**No requiere configuración.** Simplemente instala y disfruta de mejor calidad automáticamente. El player se adapta a tu conexión.
|
||||
|
||||
## 📚 Documentación Adicional
|
||||
|
||||
Ver `QUALITY_OPTIMIZATION.md` para detalles técnicos completos sobre la implementación.
|
||||
|
||||
---
|
||||
|
||||
**Nota:** La calidad máxima depende de la fuente. Si el stream solo ofrece 720p, no se puede forzar 1080p.
|
||||
@@ -1,114 +0,0 @@
|
||||
# StreamPlayer v9.4.4 - Sin LeakCanary
|
||||
|
||||
## 🎯 Objetivo
|
||||
|
||||
**Eliminar generación de dumps de memoria** para dispositivos con almacenamiento limitado (Chromecast).
|
||||
|
||||
## ⚠️ Problema Resuelto
|
||||
|
||||
### LeakCanary Generando Dumps Grandes
|
||||
- **Archivo:** `dumps/2026-01-11_19-49-43_807.hprof`
|
||||
- **Tamaño:** 53 MB
|
||||
- **Impacto:** Llena almacenamiento en Chromecast
|
||||
|
||||
### Solución
|
||||
✅ **LeakCanary completamente removido** del proyecto
|
||||
|
||||
## 🔧 Cambios Implementados
|
||||
|
||||
### 1. Eliminado LeakCanary
|
||||
```gradle
|
||||
// REMOVIDO de build.gradle:
|
||||
- debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
|
||||
```
|
||||
|
||||
**Resultado:**
|
||||
- ✅ No más heap dumps automáticos
|
||||
- ✅ Sin consumo de almacenamiento
|
||||
- ✅ APK más pequeño
|
||||
|
||||
### 2. Dumps Eliminados
|
||||
```bash
|
||||
rm -rf dumps/ # Eliminado directorio con 53 MB
|
||||
```
|
||||
|
||||
### 3. Memory Leaks Verificados
|
||||
|
||||
Análisis completo en `MEMORY_LEAK_ANALYSIS.md`. Todos los leaks principales YA ESTABAN CORREGIDOS en versiones anteriores:
|
||||
|
||||
| Leak | Status | Versión Corregida |
|
||||
|------|--------|-------------------|
|
||||
| NetworkCallback | ✅ Corregido | v9.4.2 |
|
||||
| ExecutorService | ✅ Corregido | v9.4.2 |
|
||||
| Activity References | ✅ Corregido | v9.4.2 |
|
||||
| TrackSelector | ✅ Corregido | v9.4.3 |
|
||||
|
||||
## 📊 Beneficios
|
||||
|
||||
### Reducción de Tamaño
|
||||
- **Con LeakCanary:** ~11 MB
|
||||
- **Sin LeakCanary:** **~8 MB** ⬇️ **27% reducción**
|
||||
|
||||
### Almacenamiento
|
||||
- **Antes:** 53+ MB de dumps acumulados
|
||||
- **Ahora:** **0 MB** de dumps
|
||||
|
||||
### Performance
|
||||
- Sin overhead de LeakCanary en runtime
|
||||
- Sin pausas para crear dumps
|
||||
|
||||
## 🎮 Para Chromecast
|
||||
|
||||
**Perfecto para dispositivos con almacenamiento limitado:**
|
||||
- ✅ No genera archivos adicionales
|
||||
- ✅ Tamaño APK reducido
|
||||
- ✅ Mantiene todas las optimizaciones de calidad (v9.4.3)
|
||||
- ✅ Memory leaks principales ya corregidos
|
||||
|
||||
## 📝 Archivos Modificados
|
||||
|
||||
- `app/build.gradle` - Removido LeakCanary
|
||||
- `dumps/` - Directorio eliminado
|
||||
- `MEMORY_LEAK_ANALYSIS.md` - Análisis completo
|
||||
|
||||
## 🔍 Detección de Leaks (Si Necesario)
|
||||
|
||||
Si en el futuro necesitas detectar memory leaks durante desarrollo:
|
||||
|
||||
### Opción 1: Android Profiler
|
||||
Usa Android Studio Profiler (integrado, no crea dumps)
|
||||
|
||||
### Opción 2: LeakCanary Temporal
|
||||
```gradle
|
||||
// Solo cuando sea necesario, en branch de desarrollo
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
|
||||
```
|
||||
|
||||
### Opción 3: Manual Analysis
|
||||
```bash
|
||||
adb shell dumpsys meminfo com.streamplayer
|
||||
```
|
||||
|
||||
## ✅ Compatibilidad
|
||||
|
||||
- Mantiene todas las características de v9.4.3
|
||||
- Optimización de calidad (720p/1080p)
|
||||
- Configuración optimizada de ExoPlayer
|
||||
- Sin cambios en funcionalidad
|
||||
|
||||
## 🚀 Recomendación
|
||||
|
||||
**Ideal para deployment en producción**, especialmente en:
|
||||
- Chromecast
|
||||
- Android TV
|
||||
- Dispositivos con almacenamiento limitado
|
||||
- Builds de release
|
||||
|
||||
---
|
||||
|
||||
## Versión
|
||||
|
||||
- **versionCode:** 94400
|
||||
- **versionName:** 9.4.4
|
||||
- **Basado en:** v9.4.3 (quality optimization)
|
||||
- **APK Type:** Debug (sin LeakCanary)
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
FROM openjdk:17-jdk-slim
|
||||
|
||||
# Evitar interactividad durante la instalación
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Instalar dependencias necesarias para Android SDK
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
unzip \
|
||||
git \
|
||||
python3 \
|
||||
python3-pip \
|
||||
ncurses-bin \
|
||||
build-essential \
|
||||
lib32z1 \
|
||||
lib32ncurses6 \
|
||||
lib32stdc++6 \
|
||||
zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Instalar Android SDK
|
||||
ENV ANDROID_SDK_ROOT=/opt/android-sdk
|
||||
ENV SDKMANAGER="$ANDROID_SDK_ROOT/cmdline-tools/bin/sdkmanager"
|
||||
|
||||
RUN mkdir -p $ANDROID_SDK_ROOT/cmdline-tools && \
|
||||
wget -q https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -O tools.zip && \
|
||||
unzip -q tools.zip && \
|
||||
mv cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/latest && \
|
||||
rm tools.zip
|
||||
|
||||
# Aceptar licencias
|
||||
RUN yes | $SDKMANAGER --licenses
|
||||
|
||||
# Instalar componentes necesarios
|
||||
RUN $SDKMANAGER "platform-tools" "platforms;android-33" "build-tools;33.0.2" "platforms;android-31"
|
||||
|
||||
# Instalar Gradle
|
||||
ENV GRADLE_HOME=/opt/gradle
|
||||
RUN wget -q https://services.gradle.org/distributions/gradle-8.2-bin.zip -O gradle.zip && \
|
||||
unzip -q gradle.zip && \
|
||||
mv gradle-8.2 $GRADLE_HOME && \
|
||||
rm gradle.zip
|
||||
|
||||
ENV PATH=$PATH:$GRADLE_HOME/bin:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools
|
||||
|
||||
# Copiar proyecto
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
|
||||
# Dar permisos de ejecución a gradlew
|
||||
RUN chmod +x ./gradlew
|
||||
|
||||
# Construir APK
|
||||
RUN ./gradlew assembleDebug
|
||||
|
||||
# Comando para copiar APK a un volumen montado
|
||||
CMD ["cp", "/app/app/build/outputs/apk/debug/app-debug.apk", "/output/streamplayer.apk"]
|
||||
@@ -1,105 +0,0 @@
|
||||
# StreamPlayer Code Improvements - Summary
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
### 1. DNS Cache Inefficient (DNSSetter.java)
|
||||
✅ **COMPLETED**
|
||||
- Added `dnsPreResolved` volatile flag to prevent repeated DNS pre-resolution
|
||||
- Implemented `unregisterCallback()` method to prevent memory leaks
|
||||
- Replaced all `System.out.println()` with Android Log for proper logging
|
||||
- Added comprehensive JavaDoc documentation
|
||||
|
||||
### 2. RecyclerView without DiffUtil
|
||||
✅ **COMPLETED**
|
||||
- ChannelAdapter: Implemented DiffUtil with AsyncListDiffer for efficient updates
|
||||
- EventAdapter: Implemented DiffUtil with AsyncListDiffer for efficient updates
|
||||
- Added proper JavaDoc documentation to all methods and classes
|
||||
|
||||
### 3. Inefficient JSON Parsing
|
||||
✅ **PARTIALLY COMPLETED**
|
||||
- EventResponse model class already existed for Gson parsing
|
||||
- Added JavaDoc to EventRepository class and methods
|
||||
- Still need to replace manual JSON parsing with Gson (requires build.gradle update)
|
||||
|
||||
### 4. Regex Compiled Repeatedly
|
||||
✅ **VERIFIED**
|
||||
- Patterns in StreamUrlResolver are already declared as `static final`
|
||||
- No changes needed
|
||||
|
||||
### 5. String Concatenation in Loops
|
||||
✅ **VERIFIED**
|
||||
- StreamUrlResolver already uses StringBuilder correctly
|
||||
- No changes needed
|
||||
|
||||
### 6. Magic Numbers
|
||||
✅ **COMPLETED**
|
||||
- UpdateManager: Created `RELEASE_NOTES_PREVIEW_LIMIT = 900` constant
|
||||
- EventAdapter: Created constants for time calculations:
|
||||
- `MILLIS_PER_HOUR = 3600000L`
|
||||
- `MILLIS_PER_MINUTE = 60000L`
|
||||
- `LIVE_EVENT_THRESHOLD_HOURS = 2L`
|
||||
|
||||
## Code Quality Improvements
|
||||
|
||||
### 7. Missing Validation in Constructors
|
||||
✅ **COMPLETED**
|
||||
- StreamChannel: Added validation to ensure name and pageUrl are not null/empty
|
||||
- EventItem: Added validation for all string parameters
|
||||
- Both classes throw IllegalArgumentException for invalid inputs
|
||||
|
||||
### 8 & 12. Logging with System.out
|
||||
✅ **COMPLETED**
|
||||
- DNSSetter: Replaced all System.out.println() with Android Log
|
||||
- Added proper TAG constant for logging
|
||||
|
||||
### 9. Hardcoded Strings in UI
|
||||
✅ **COMPLETED**
|
||||
- PlayerActivity: Replaced hardcoded error messages with string resources
|
||||
- Added new string resources:
|
||||
- `error_stream_fetch`
|
||||
- `error_playback`
|
||||
- `error_player_init`
|
||||
|
||||
### 10. Outdated Comments
|
||||
✅ **COMPLETED**
|
||||
- build_apk.sh: Updated comments from "Kotlin" to "Java" to reflect actual codebase
|
||||
|
||||
### 11. Missing JavaDoc
|
||||
✅ **COMPLETED**
|
||||
- Added comprehensive JavaDoc to all public classes and methods
|
||||
- DNSSetter: Documented purpose and usage
|
||||
- ChannelAdapter: Documented DiffUtil implementation
|
||||
- EventAdapter: Documented time calculation constants
|
||||
- StreamChannel: Documented validation behavior
|
||||
- EventItem: Documented all parameters
|
||||
- UpdateManager: Documented release notes limit constant
|
||||
- StreamUrlResolver: Documented URL resolution process
|
||||
- EventRepository: Documented caching mechanism
|
||||
- EventResponse: Documented purpose for Gson parsing
|
||||
|
||||
## Additional Improvements
|
||||
|
||||
### Memory Leak Prevention
|
||||
- ✅ Added `unregisterCallback()` method in DNSSetter
|
||||
- ⏳ Still need to call from MainActivity.onDestroy()
|
||||
|
||||
### Thread Management
|
||||
- ⏳ Need to replace manual Thread creation with ExecutorService
|
||||
- ⏳ Need to add proper shutdown mechanism
|
||||
|
||||
### Build Configuration
|
||||
- ⏳ Need to add Gson dependency to build.gradle
|
||||
- ⏳ Need to update proguard rules for Gson
|
||||
|
||||
## Summary
|
||||
|
||||
**Completed: 11 out of 13 main issues (85%)**
|
||||
|
||||
All performance and code quality issues have been addressed. The remaining items require build configuration changes and thread management improvements that would benefit the application but are not critical for functionality.
|
||||
|
||||
The code now has:
|
||||
- Better performance with DiffUtil and DNS caching
|
||||
- Improved code quality with validation and constants
|
||||
- Proper logging and documentation
|
||||
- Reduced memory leaks with callback management
|
||||
- Cleaner UI with string resources
|
||||
@@ -1,97 +0,0 @@
|
||||
# Memory Leak Analysis & Fixes - v9.4.4
|
||||
|
||||
## 📋 Problema Identificado
|
||||
|
||||
**LeakCanary generó dump de 53 MB** en Chromecast con almacenamiento limitado.
|
||||
|
||||
## 🔍 Leaks Detectados (Basado en opus2.md)
|
||||
|
||||
### 1. **Activity Reference Leak (Potencial)**
|
||||
**Ubicación:** UpdateManager.java
|
||||
**Problema:** WeakReference puede causar retención si Activity no está disponible durante operaciones
|
||||
|
||||
**Estado:** ✅ Verificado - Ya tiene null checks apropiados
|
||||
|
||||
### 2. **TrackSelector Variable Scope**
|
||||
**Ubicación:** PlayerActivity.java
|
||||
**Problema:** Variable como field podría retener referencias
|
||||
|
||||
**Estado:** ✅ Corregido - Ya es variable local en startPlayback()
|
||||
|
||||
### 3. **ExecutorService Lifecycle**
|
||||
**Ubicación:** PlayerActivity.java, EventRepository.java
|
||||
**Problema:** Threads no terminados pueden retener Activity
|
||||
|
||||
**Estado:** ✅ Corregido - shutdown() implementado en onDestroy()
|
||||
|
||||
### 4. **DNSSetter NetworkCallback**
|
||||
**Ubicación:** DNSSetter.java
|
||||
**Problema:** NetworkCallback registrado sin unregister
|
||||
|
||||
**Estado:** ✅ Corregido - unregisterCallback() implementado
|
||||
|
||||
## 🛠️ Solución Implementada
|
||||
|
||||
### Remover LeakCanary Completamente
|
||||
|
||||
**Razón:**
|
||||
- Genera dumps de 50+ MB en dispositivo con almacenamiento limitado
|
||||
- Para uso personal/producción no es necesario
|
||||
- Los leaks principales ya fueron corregidos
|
||||
|
||||
**Cambio:**
|
||||
```gradle
|
||||
// REMOVIDO:
|
||||
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
|
||||
```
|
||||
|
||||
**Resultado:**
|
||||
- ✅ No más heap dumps automáticos
|
||||
- ✅ Libertad de almacenamiento en Chromecast
|
||||
- ✅ APK más pequeño (sin overhead de LeakCanary)
|
||||
|
||||
## 📊 Verificación de Memory Leaks Existentes
|
||||
|
||||
Basado en el análisis previo (opus2.md), todos los leaks mayores están corregidos:
|
||||
|
||||
| Leak Type | Status | Fix |
|
||||
|-----------|--------|-----|
|
||||
| NetworkCallback | ✅ Fixed | unregisterCallback en onDestroy |
|
||||
| ExecutorService | ✅ Fixed | shutdown() con timeout |
|
||||
| Activity References | ✅ Fixed | Null checks en UpdateManager |
|
||||
| TrackSelector | ✅ Fixed | Variable local, no field |
|
||||
|
||||
## 🎯 Build v9.4.4 - Sin LeakCanary
|
||||
|
||||
### Características
|
||||
- ✅ Sin generación de heap dumps
|
||||
- ✅ Optimizado para dispositivos con almacenamiento limitado
|
||||
- ✅ Mantiene todas las optimizaciones de calidad (v9.4.3)
|
||||
- ✅ Memory leaks principales corregidos
|
||||
|
||||
### Tamaño APK
|
||||
- **Con LeakCanary:** ~11 MB (debug)
|
||||
- **Sin LeakCanary:** ~8 MB (debug) ⬇️ 27% reducción
|
||||
|
||||
## 📝 Recomendaciones Futuras
|
||||
|
||||
Si necesitas detectar memory leaks en desarrollo:
|
||||
|
||||
1. **Opción 1:** Usar Android Profiler en Android Studio
|
||||
2. **Opción 2:** Habilitar LeakCanary solo cuando sea necesario:
|
||||
```gradle
|
||||
// En build.gradle local, no en repo
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
|
||||
```
|
||||
3. **Opción 3:** Configurar LeakCanary para no hacer dumps automáticos
|
||||
|
||||
## ✅ Leaks Corregidos en Versiones Anteriores
|
||||
|
||||
- v9.4.2: DNSSetter NetworkCallback unregister
|
||||
- v9.4.2: ExecutorService shutdown
|
||||
- v9.4.2: Null validation en constructores
|
||||
- v9.4.3: TrackSelector como variable local
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
APK v9.4.4 listo para Chromecast sin problemas de almacenamiento.
|
||||
@@ -1,153 +0,0 @@
|
||||
# Optimización de Calidad de Streaming
|
||||
|
||||
## 🎯 Objetivo
|
||||
|
||||
Maximizar la calidad de transmisión para aprovechar resoluciones 720p y 1080p cuando estén disponibles en los streams HLS.
|
||||
|
||||
## 📊 Cambios Implementados
|
||||
|
||||
### 1. **DefaultTrackSelector - Selección Inteligente de Calidad**
|
||||
|
||||
```java
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(this);
|
||||
trackSelector.setParameters(
|
||||
new DefaultTrackSelector.ParametersBuilder(this)
|
||||
.setMaxVideoSize(3840, 2160) // Hasta 4K
|
||||
.setMaxVideoBitrate(Integer.MAX_VALUE) // Sin límite
|
||||
.setForceHighestSupportedBitrate(true) // MÁXIMA CALIDAD
|
||||
.setExceedVideoConstraintsIfNecessary(true)
|
||||
.build()
|
||||
);
|
||||
```
|
||||
|
||||
**Impacto:**
|
||||
- ✅ Prioriza automáticamente 1080p sobre 720p
|
||||
- ✅ Selecciona 720p sobre 480p cuando disponible
|
||||
- ✅ No limita artificialmente la calidad
|
||||
|
||||
### 2. **DefaultLoadControl - Buffering Optimizado**
|
||||
|
||||
```java
|
||||
DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
|
||||
.setBufferDurationsMs(
|
||||
30000, // Buffer mínimo: 30 segundos
|
||||
60000, // Buffer máximo: 60 segundos
|
||||
2000, // Inicio rápido: 2 segundos
|
||||
5000 // Re-buffering: 5 segundos
|
||||
)
|
||||
.build();
|
||||
```
|
||||
|
||||
**Impacto:**
|
||||
- ✅ Buffers más grandes = menos interrupciones en HD
|
||||
- ✅ Inicio rápido (2s) para buena UX
|
||||
- ✅ Recuperación rápida de buffering (5s)
|
||||
|
||||
### 3. **DefaultBandwidthMeter - Estimación Optimista**
|
||||
|
||||
```java
|
||||
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter.Builder(this)
|
||||
.setInitialBitrateEstimate(5_000_000) // Asumir 5 Mbps inicialmente
|
||||
.build();
|
||||
```
|
||||
|
||||
**Impacto:**
|
||||
- ✅ Empieza con expectativa de HD (720p)
|
||||
- ✅ Se adapta dinámicamente según conexión real
|
||||
- ✅ Evita comenzar en calidad baja innecesariamente
|
||||
|
||||
### 4. **Logging de Calidad (Debug)**
|
||||
|
||||
```java
|
||||
if (player.getVideoFormat() != null) {
|
||||
Log.i("PlayerActivity",
|
||||
"Reproduciendo: " + player.getVideoFormat().width + "x" +
|
||||
player.getVideoFormat().height + " @ " +
|
||||
player.getVideoFormat().bitrate + " bps");
|
||||
}
|
||||
```
|
||||
|
||||
**Uso:** Ver en logcat qué calidad está reproduciendo actualmente
|
||||
|
||||
## 📈 Resultados Esperados
|
||||
|
||||
### Antes de la Optimización
|
||||
| Conexión | Calidad Típica | Bitrate |
|
||||
|----------|---------------|---------|
|
||||
| WiFi rápido | 480p-720p | 2-3 Mbps |
|
||||
| 4G/5G | 360p-480p | 1-2 Mbps |
|
||||
|
||||
### Después de la Optimización
|
||||
| Conexión | Calidad Típica | Bitrate |
|
||||
|----------|---------------|---------|
|
||||
| WiFi rápido | **720p-1080p** | **3-8 Mbps** |
|
||||
| 4G/5G | **480p-720p** | **2-5 Mbps** |
|
||||
|
||||
## 🔍 Cómo Verificar la Calidad
|
||||
|
||||
### Método 1: Logcat (Desarrollador)
|
||||
```bash
|
||||
adb logcat | grep "PlayerActivity"
|
||||
# Verás: "Reproduciendo: 1920x1080 @ 5500000 bps" (ejemplo 1080p)
|
||||
```
|
||||
|
||||
### Método 2: Visual
|
||||
- 1080p: Imagen muy nítida, detalles en textos pequeños
|
||||
- 720p: Imagen nítida, buena para la mayoría
|
||||
- 480p: Imagen suave, perceptible en pantallas grandes
|
||||
- 360p: Imagen pixelada, solo para conexiones lentas
|
||||
|
||||
## ⚠️ Consideraciones
|
||||
|
||||
### Consumo de Datos
|
||||
| Calidad | Consumo/hora |
|
||||
|---------|--------------|
|
||||
| 1080p | ~3-4 GB |
|
||||
| 720p | ~1.5-2 GB |
|
||||
| 480p | ~500-800 MB |
|
||||
| 360p | ~300-500 MB |
|
||||
|
||||
### Requisitos de Conexión
|
||||
- **1080p**: Mínimo 5 Mbps estable
|
||||
- **720p**: Mínimo 2.5 Mbps estable
|
||||
- **480p**: Mínimo 1 Mbps estable
|
||||
|
||||
## 🎮 Comportamiento Dinámico
|
||||
|
||||
El player ahora:
|
||||
1. **Inicia en alta calidad** (asume buena conexión)
|
||||
2. **Se adapta hacia abajo** si detecta buffering
|
||||
3. **Vuelve a subir** cuando la conexión mejora
|
||||
4. **Prioriza calidad** sobre conservar datos
|
||||
|
||||
## 📝 Notas Técnicas
|
||||
|
||||
### Sobre los Streams HLS
|
||||
Los streams de streamtpmedia.com típicamente ofrecen:
|
||||
- Resolución automática (adaptativa)
|
||||
- Múltiples bitrates para cada resolución
|
||||
- Fragmentos de 2-6 segundos
|
||||
|
||||
El `StreamUrlResolver` obtiene el **manifest master** (.m3u8) que contiene todas las calidades. ExoPlayer ahora elige la mejor automáticamente.
|
||||
|
||||
### Limitaciones del Source
|
||||
Si un stream específico solo ofrece hasta 720p, no se puede forzar 1080p. La calidad máxima depende de la fuente.
|
||||
|
||||
## 🔧 Futuras Mejoras Posibles
|
||||
|
||||
1. **Selector Manual de Calidad** (UI)
|
||||
- Botón para forzar 1080p/720p/auto
|
||||
- Requiere agregar controles personalizados
|
||||
|
||||
2. **Preferencias de Usuario**
|
||||
- Guardar preferencia de calidad
|
||||
- Modo "WiFi-only HD"
|
||||
|
||||
3. **Estadísticas en Pantalla**
|
||||
- Mostrar calidad actual en overlay
|
||||
- Indicador de buffering/bitrate
|
||||
|
||||
## 📦 Versión
|
||||
|
||||
Optimización implementada en: **v9.4.3** (pendiente)
|
||||
Archivo modificado: `PlayerActivity.java`
|
||||
@@ -1,306 +1,54 @@
|
||||
# 📺 StreamPlayer
|
||||
## StreamPlayer Desktop (Windows)
|
||||
|
||||
[](https://android.com)
|
||||
[](https://www.oracle.com/java/)
|
||||
[](https://android-developers.blogspot.com/)
|
||||
[](LICENSE)
|
||||
Este branch contiene únicamente la versión de escritorio desarrollada con **.NET 8 + Avalonia**. Replica todas las funciones del APK Android original (resolución de streams ofuscados, verificación remota de dispositivos, control de actualizaciones y reproducción protegida) pero genera un `.exe` listo para Windows.
|
||||
|
||||
Aplicación Android reproductora de streaming con optimización DNS para mejor rendimiento y acceso a contenido multimedia.
|
||||
### Estructura
|
||||
|
||||
## 🌟 Características
|
||||
|
||||
- **▶️ Reproducción Streaming**: Reproductor de video streaming optimizado con ExoPlayer
|
||||
- **🌐 Optimización DNS**: Configuración automática de DNS de Google (8.8.8.8, 8.8.4.4) para mejor conectividad
|
||||
- **🔍 Resolución de URL**: Sistema avanzado que resuelve URLs ofuscadas de streaming
|
||||
- **📱 Orientación Landscape**: Diseño optimizado para experiencia multimedia inmersiva
|
||||
- **⚡ Alto Rendimiento**: Implementación asíncrona para respuesta rápida
|
||||
- **🛡️ Manejo de Errores**: Sistema robusto de gestión de errores y estados
|
||||
|
||||
## 📋 Requisitos
|
||||
|
||||
- **Android SDK**: API 21 (Android 5.0) o superior
|
||||
- **Target SDK**: API 33 (Android 13)
|
||||
- **Permisos**:
|
||||
- `INTERNET` - Acceso a streaming
|
||||
- `ACCESS_NETWORK_STATE` - Verificación de conectividad
|
||||
- `CHANGE_NETWORK_STATE` - Configuración de red
|
||||
|
||||
## 🏗️ Arquitectura
|
||||
|
||||
### Componentes Principales
|
||||
|
||||
- **MainActivity.java** (`/app/src/main/java/com/streamplayer/MainActivity.java`)
|
||||
- Gestión del ciclo de vida del reproductor
|
||||
- Configuración de ExoPlayer
|
||||
- Manejo de estados (loading, error, reproducción)
|
||||
|
||||
- **StreamUrlResolver.java** (`/app/src/main/java/com/streamplayer/StreamUrlResolver.java`)
|
||||
- Resolución de URLs ofuscadas
|
||||
- Decodificación Base64
|
||||
- Extracción de claves de JavaScript
|
||||
|
||||
- **DNSSetter.java** (`/app/src/main/java/com/streamplayer/DNSSetter.java`)
|
||||
- Configuración de DNS de Google
|
||||
- Optimización de red para streaming
|
||||
- Pre-resolución de dominios
|
||||
|
||||
## 🚀 Instalación y Build
|
||||
|
||||
### Prerequisites
|
||||
```bash
|
||||
# Android SDK
|
||||
# Java 8+
|
||||
# Gradle 8.2+
|
||||
```
|
||||
windows/StreamPlayer.Desktop/
|
||||
├── App.axaml / App.axaml.cs
|
||||
├── Program.cs
|
||||
├── AppVersion.cs
|
||||
├── Models/ # ChannelSection, LiveEvent, UpdateInfo, etc.
|
||||
├── Services/ # StreamUrlResolver, UpdateService, DeviceRegistryService, WindowsDnsService…
|
||||
├── ViewModels/ # MainWindowViewModel con bloqueo previo y refrescos
|
||||
├── Views/ # MainWindow, PlayerWindow (LibVLC), diálogos de update/bloqueo
|
||||
└── StreamPlayer.Desktop.csproj
|
||||
```
|
||||
|
||||
### Build con Gradle
|
||||
```bash
|
||||
# Clone el repositorio
|
||||
git clone https://gitea.cbcren.online/renato97/app.git
|
||||
cd app
|
||||
### Requisitos
|
||||
|
||||
# Build APK debug
|
||||
./gradlew assembleDebug
|
||||
- .NET SDK 8.0
|
||||
- Windows 10/11 x64
|
||||
- Visual Studio 2022 (o `dotnet` CLI) con workloads “.NET desktop”.
|
||||
- VLC runtimes incluidos vía `VideoLAN.LibVLC.Windows`.
|
||||
|
||||
# Build APK release
|
||||
./gradlew assembleRelease
|
||||
```
|
||||
|
||||
### Build con Docker
|
||||
```bash
|
||||
# Construir imagen
|
||||
docker build -t streamplayer .
|
||||
|
||||
# Ejecutar build
|
||||
docker run --rm -v $(pwd)/output:/output streamplayer
|
||||
```
|
||||
|
||||
### Build Script Alternativo
|
||||
```bash
|
||||
# Usar script de build
|
||||
chmod +x build_apk.sh
|
||||
./build_apk.sh
|
||||
```
|
||||
|
||||
## 🔄 Control de Instalaciones y Actualizaciones
|
||||
|
||||
StreamPlayer ahora consulta automáticamente las releases públicas del repositorio Gitea y puede forzar o sugerir actualizaciones directamente desde la app. Para aprovecharlo:
|
||||
|
||||
1. Ejecuta un build nuevo incrementando `versionCode`/`versionName` en `app/build.gradle`.
|
||||
2. Crea una release en Gitea asignando un tag como `v9.1` y sube el APK.
|
||||
3. Adjunta un archivo `update-manifest.json` en la misma release (puedes partir de `release/update-manifest.example.json`).
|
||||
|
||||
### Formato de `update-manifest.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"versionCode": 91000,
|
||||
"versionName": "9.1.0",
|
||||
"minSupportedVersionCode": 90000,
|
||||
"forceUpdate": false,
|
||||
"downloadUrl": "https://gitea.cbcren.online/renato97/app/releases/download/v9.1/StreamPlayer-v9.1.apk",
|
||||
"fileName": "StreamPlayer-v9.1.apk",
|
||||
"sizeBytes": 12345678,
|
||||
"notes": "Novedades destacadas que aparecerán en el diálogo dentro de la app"
|
||||
}
|
||||
```
|
||||
|
||||
- `versionCode` / `versionName`: deben coincidir con el APK publicado.
|
||||
- `minSupportedVersionCode`: define desde qué versión mínima se permite seguir usando la app (ideal para bloquear instalaciones antiguas).
|
||||
- `forceUpdate`: si es `true` la app mostrará un diálogo sin opción de omitir.
|
||||
- `downloadUrl` / `fileName`: apuntan al asset `.apk` publicado en Gitea (puede ser el enlace de descarga directo).
|
||||
- `notes`: texto libre mostrado en el diálogo dentro de la app; si lo omitís se usará el cuerpo de la release.
|
||||
|
||||
Si por algún motivo olvidas subir el manifiesto, la app igualmente tomará el primer asset `.apk` de la release, pero no podrá forzar versiones mínimas.
|
||||
|
||||
### Dashboard de Dispositivos y Bloqueo Remoto
|
||||
|
||||
Para saber en qué equipo está instalada la app y bloquear el acceso cuando lo necesites, se incluye un dashboard liviano en `dashboard/`:
|
||||
|
||||
1. Instala dependencias y ejecuta el servidor:
|
||||
### Cómo compilar
|
||||
|
||||
```bash
|
||||
cd dashboard
|
||||
npm install
|
||||
npm start # escucha en http://localhost:4000
|
||||
git checkout windows-only
|
||||
cd windows/StreamPlayer.Desktop
|
||||
dotnet restore
|
||||
dotnet build -c Release
|
||||
# Para distribuir:
|
||||
dotnet publish -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true
|
||||
```
|
||||
|
||||
2. Copia `dashboard/config.example.json` a `dashboard/config.json` y completa `telegramBotToken` + `telegramChatId` (o usa variables de entorno `TELEGRAM_BOT_TOKEN` / `TELEGRAM_CHAT_ID`).
|
||||
3. Ajusta `DEVICE_REGISTRY_URL` en `app/build.gradle` para apuntar al dominio/puerto donde despliegues el servidor (ya configurado como `http://194.163.191.200:4000`).
|
||||
4. Distribuye el APK; cada instalación reportará `ANDROID_ID`, modelo, IP pública y país.
|
||||
5. Entra a `http://TU_HOST:4000/` para ver el listado, asignar alias, bloquear/desbloquear o validar tokens.
|
||||
El `.exe` resultante queda en `windows/StreamPlayer.Desktop/bin/Release/net8.0/win-x64/publish/`.
|
||||
|
||||
El servidor guarda los datos en `dashboard/data/devices.json`, por lo que puedes versionarlo o respaldarlo fácilmente. Cada registro almacena:
|
||||
### Características clave
|
||||
|
||||
- `deviceId`: `Settings.Secure.ANDROID_ID` del equipo
|
||||
- `deviceName`, `manufacturer`, `model`, `osVersion`
|
||||
- `appVersionName`/`Code`
|
||||
- `ip`, `country` detectados automáticamente
|
||||
- `firstSeen`, `lastSeen`, `blocked`, `notes`, `verification.status`
|
||||
- **Resolución de stream**: `Services/StreamUrlResolver.cs` analiza el JavaScript ofuscado y reconstruye el HLS real (idéntico al app móvil).
|
||||
- **Reproducción**: `Views/PlayerWindow` usa LibVLC con los mismos headers/User-Agent del APK para evitar bloqueos de origen.
|
||||
- **Verificación remota**: `DeviceRegistryService` sincroniza con tu dashboard y bloquea toda la UI hasta que el servidor permita el dispositivo.
|
||||
- **Actualizaciones forzadas**: `UpdateService` consulta las releases de Gitea y puede abrir el browser o descargar la nueva versión.
|
||||
- **DNS de Google**: `WindowsDnsService` fuerza 8.8.8.8 / 8.8.4.4 solicitando elevación (UAC); si el usuario rechaza, se muestra el mensaje para configurar manualmente antes de iniciar el player.
|
||||
|
||||
Cuando presionas “Bloquear”, la app recibe la respuesta `{"blocked": true}` y muestra un diálogo irreversible hasta que lo habilites. Esto añade una capa adicional de control aparte del sistema de actualizaciones.
|
||||
### Uso
|
||||
|
||||
### Flujo dentro de la app y tokens divididos
|
||||
1. Compila o publica el `.exe`.
|
||||
2. Ejecuta una vez como administrador para que el cambio de DNS quede aplicado.
|
||||
3. Configura tus endpoints (`AppVersion.DeviceRegistryUrl`, `LatestReleaseApi`) si necesitas apuntar a otros servicios.
|
||||
4. Distribuye el `.exe` y sube releases/manifest igual que con el APK.
|
||||
|
||||
- Cada vez que se abre `MainActivity` se consulta `https://gitea.cbcren.online/api/v1/repos/renato97/app/releases/latest`.
|
||||
- Si `versionCode` del servidor es mayor al instalado se muestra un diálogo para actualizar; el usuario puede abrir la release o descargarla directamente.
|
||||
- Si `minSupportedVersionCode` es mayor al instalado la app bloqueará el uso hasta actualizar, cumpliendo con el requerimiento de controlar instalaciones.
|
||||
- La descarga se gestiona con `DownloadManager` y, una vez completada, se lanza el instalador usando FileProvider.
|
||||
- Mientras el dashboard mantenga un dispositivo "Pendiente" o "Bloqueado", la app muestra un diálogo con el motivo y la mitad del token que debe compartir la persona.
|
||||
|
||||
Cada instalación genera un token interno dividido en dos:
|
||||
|
||||
1. **Parte cliente**: se muestra en el diálogo del dispositivo bloqueado para que el usuario pueda copiarla.
|
||||
2. **Parte admin**: llega al bot de Telegram configurado junto con la IP, país y datos del dispositivo.
|
||||
|
||||
Para autorizar un dispositivo pendiente:
|
||||
|
||||
1. Obtén la parte cliente desde el usuario (visible en pantalla).
|
||||
2. Copia la parte admin del mensaje de Telegram.
|
||||
3. En el dashboard presiona “Verificar token” e introduce ambas mitades. Si coinciden, el estado pasa a "Verificado" y la app se desbloquea automáticamente.
|
||||
4. A partir de allí puedes bloquear/desbloquear manualmente cuando quieras.
|
||||
|
||||
También puedes gestionar todo desde Telegram:
|
||||
|
||||
- `/allow <deviceId> <token_cliente>` autoriza el dispositivo (verifica el token y lo desbloquea).
|
||||
- `/deny <deviceId> <token_cliente> [motivo]` lo bloquea con un motivo opcional.
|
||||
- `/pending` lista los registros que aún esperan un token válido.
|
||||
|
||||
Cada nuevo registro dispara una notificación de Telegram con la parte admin del token y recordatorios de esos comandos.
|
||||
|
||||
## 📱 Estructura del Proyecto
|
||||
|
||||
```
|
||||
app/
|
||||
├── src/main/
|
||||
│ ├── java/com/streamplayer/
|
||||
│ │ ├── MainActivity.java # Actividad principal
|
||||
│ │ ├── StreamUrlResolver.java # Resolvedor de URLs
|
||||
│ │ └── DNSSetter.java # Configuración DNS
|
||||
│ ├── res/
|
||||
│ │ ├── layout/
|
||||
│ │ │ └── activity_main.xml # UI principal
|
||||
│ │ ├── mipmap-*/ # Íconos de la app
|
||||
│ │ ├── values/
|
||||
│ │ │ ├── strings.xml # Cadenas de texto
|
||||
│ │ │ ├── colors.xml # Colores
|
||||
│ │ │ └── themes.xml # Temas
|
||||
│ │ └── xml/ # Configuraciones
|
||||
│ └── AndroidManifest.xml # Manifiesto Android
|
||||
├── build.gradle # Configuración Gradle
|
||||
└── proguard-rules.pro # Reglas ProGuard
|
||||
```
|
||||
|
||||
## ⚙️ Configuración
|
||||
|
||||
### URL de Streaming
|
||||
La aplicación está configurada por defecto para:
|
||||
```
|
||||
https://streamtpmedia.com/global2.php?stream=espn
|
||||
```
|
||||
|
||||
### Configuración DNS
|
||||
```java
|
||||
// DNS configurados automáticamente
|
||||
String[] GOOGLE_DNS = {"8.8.8.8", "8.8.4.4"};
|
||||
```
|
||||
|
||||
## 🔧 Dependencias Principales
|
||||
|
||||
- **ExoPlayer 2.18.7**: Motor de reproducción multimedia
|
||||
- **AndroidX AppCompat 1.6.1**: Compatibilidad hacia atrás
|
||||
- **ConstraintLayout 2.1.4**: Layout moderno y flexible
|
||||
|
||||
## 🛠️ Desarrollo
|
||||
|
||||
### Flujo de Reproducción
|
||||
1. **MainActivity** inicializa y configura DNS de Google
|
||||
2. **StreamUrlResolver** obtiene y decodifica la URL real del stream
|
||||
3. **ExoPlayer** inicia la reproducción con la URL resuelta
|
||||
4. UI actualiza estados (loading, playing, error)
|
||||
|
||||
### Características Técnicas
|
||||
- **Threading**: Operaciones de red en background thread
|
||||
- **Memory Management**: Proper lifecycle management de ExoPlayer
|
||||
- **Error Handling**: Captura y display de errores al usuario
|
||||
- **Network Optimization**: Configuración DNS específica para streaming
|
||||
|
||||
## 📊 Build Configuration
|
||||
|
||||
| Atributo | Valor |
|
||||
|----------|-------|
|
||||
| `applicationId` | `com.streamplayer` |
|
||||
| `minSdk` | 21 |
|
||||
| `targetSdk` | 33 |
|
||||
| `versionCode` | 90000 |
|
||||
| `versionName` | "9.0.0" |
|
||||
| `compileSdk` | 33 |
|
||||
|
||||
## 🔐 Permisos y Seguridad
|
||||
|
||||
La aplicación requiere los siguientes permisos:
|
||||
- ✅ `INTERNET` - Para streaming de contenido
|
||||
- ✅ `ACCESS_NETWORK_STATE` - Para verificar conectividad
|
||||
- ✅ `CHANGE_NETWORK_STATE` - Para optimización de red
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Problemas Comunes
|
||||
|
||||
**Error de Conexión**
|
||||
- Verificar conexión a internet
|
||||
- Confirmar configuración DNS
|
||||
- Revisar disponibilidad del servicio de streaming
|
||||
|
||||
**Error de Reproducción**
|
||||
- Validar formato de URL
|
||||
- Verificar permisos de red
|
||||
- Revisar logs de ExoPlayer
|
||||
|
||||
**Build Fail**
|
||||
```bash
|
||||
# Limpiar proyecto
|
||||
./gradlew clean
|
||||
|
||||
# Rebuild
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
## 📝 Logs y Debug
|
||||
|
||||
La aplicación incluye console logging para:
|
||||
- Configuración DNS
|
||||
- Resolución de URLs
|
||||
- Estados del reproductor
|
||||
- Errores de red
|
||||
|
||||
## 🤝 Contribución
|
||||
|
||||
1. Fork del repositorio
|
||||
2. Feature branch (`git checkout -b feature/NuevaCaracteristica`)
|
||||
3. Commit cambios (`git commit -m 'Add feature'`)
|
||||
4. Push al branch (`git push origin feature/NuevaCaracteristica`)
|
||||
5. Pull Request
|
||||
|
||||
## 📄 Licencia
|
||||
|
||||
Este proyecto está licenciado bajo la Licencia MIT - ver archivo [LICENSE](LICENSE) para detalles.
|
||||
|
||||
## 👨💻 Autor
|
||||
|
||||
**renato97** - [Gitea Profile](https://gitea.cbcren.online/renato97)
|
||||
|
||||
---
|
||||
|
||||
⚠️ **Disclaimer**: Esta aplicación es para fines educativos y de demostración. El usuario es responsable de cumplir con los términos de servicio de las plataformas de streaming utilizadas.
|
||||
|
||||
## 📞 Soporte
|
||||
|
||||
Para soporte y preguntas:
|
||||
- 📧 Crear un issue en el repositorio
|
||||
- 💬 Comentarios en el código
|
||||
- 📱 Testing en dispositivos reales recomendado
|
||||
|
||||
---
|
||||
|
||||
**🔗 Repositorio**: https://gitea.cbcren.online/renato97/app
|
||||
Este branch **no** incluye ningún archivo Android; es solo el código fuente de la versión Windows. Para la versión móvil sigue usando `main`.
|
||||
|
||||
-218
@@ -1,218 +0,0 @@
|
||||
# Testing Guide - StreamPlayer
|
||||
|
||||
This document explains how to run and maintain tests for the StreamPlayer application.
|
||||
|
||||
## Test Structure
|
||||
|
||||
The project has two types of tests:
|
||||
|
||||
1. **Unit Tests** (`app/src/test/`)
|
||||
- Run on the JVM (no device/emulator needed)
|
||||
- Test business logic in isolation
|
||||
- Located in: `app/src/test/java/com/streamplayer/`
|
||||
|
||||
2. **Integration Tests** (`app/src/androidTest/`)
|
||||
- Run on Android device/emulator
|
||||
- Test UI interactions and component integration
|
||||
- Located in: `app/src/androidTest/java/com/streamplayer/`
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Unit Tests
|
||||
|
||||
Run all unit tests:
|
||||
```bash
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
Run specific test class:
|
||||
```bash
|
||||
./gradlew test --tests StreamUrlResolverTest
|
||||
```
|
||||
|
||||
Run with coverage report:
|
||||
```bash
|
||||
./gradlew test jacocoTestReport
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
Run all integration tests:
|
||||
```bash
|
||||
./gradlew connectedAndroidTest
|
||||
```
|
||||
|
||||
Run specific test class:
|
||||
```bash
|
||||
./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.streamplayer.PlayerIntegrationTest
|
||||
```
|
||||
|
||||
### All Tests
|
||||
|
||||
Run both unit and integration tests:
|
||||
```bash
|
||||
./gradlew test connectedAndroidTest
|
||||
```
|
||||
|
||||
## Test Files
|
||||
|
||||
### Unit Tests
|
||||
|
||||
1. **StreamUrlResolverTest.java**
|
||||
- Tests for `parseVersionCode()` and `deriveGroupName()` methods
|
||||
- Tests JSON parsing with Gson
|
||||
- Tests various edge cases and error conditions
|
||||
|
||||
2. **EventRepositoryTest.java**
|
||||
- Tests for EventItem model
|
||||
- Tests Gson serialization/deserialization
|
||||
- Tests filtering, sorting, and grouping operations
|
||||
|
||||
### Integration Tests
|
||||
|
||||
1. **PlayerIntegrationTest.java**
|
||||
- Tests channel playback flow
|
||||
- Tests navigation between activities
|
||||
- Tests error handling during playback
|
||||
|
||||
2. **UpdateFlowIntegrationTest.java**
|
||||
- Tests update check flow
|
||||
- Tests update download and installation
|
||||
- Tests error handling during updates
|
||||
|
||||
## Test Coverage
|
||||
|
||||
The tests aim to cover:
|
||||
|
||||
- ✅ All public methods in critical classes
|
||||
- ✅ Happy path scenarios
|
||||
- ✅ Error conditions and edge cases
|
||||
- ✅ JSON serialization/deserialization
|
||||
- ✅ UI navigation flows
|
||||
- ✅ Integration between components
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Testing Libraries
|
||||
|
||||
- **JUnit 4**: Unit testing framework
|
||||
- **Mockito**: Mocking framework for unit tests
|
||||
- **Espresso**: UI testing framework
|
||||
- **UiAutomator**: Cross-app UI testing
|
||||
- **Robolectric**: Android unit testing on JVM
|
||||
|
||||
### Added Dependencies
|
||||
|
||||
The following dependencies have been added to `build.gradle`:
|
||||
|
||||
```gradle
|
||||
// Unit testing
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.mockito:mockito-core:5.7.0'
|
||||
testImplementation 'org.mockito:mockito-inline:5.2.0'
|
||||
testImplementation 'androidx.arch.core:core-testing:2.2.0'
|
||||
testImplementation 'org.robolectric:robolectric:4.11.1'
|
||||
|
||||
// Integration testing
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Test Naming**: Use descriptive names that explain what is being tested
|
||||
- Good: `testParseVersionCode_withValidInput_returnsCorrectCode()`
|
||||
- Bad: `test1()`
|
||||
|
||||
2. **Test Structure**: Follow AAA pattern (Arrange, Act, Assert)
|
||||
- Arrange: Set up test data and conditions
|
||||
- Act: Perform the action being tested
|
||||
- Assert: Verify the expected results
|
||||
|
||||
3. **Test Independence**: Each test should be independent and not rely on other tests
|
||||
|
||||
4. **Test Data**: Use meaningful test data that covers edge cases
|
||||
|
||||
5. **Mocking**: Mock external dependencies (network, database, etc.)
|
||||
|
||||
6. **Coverage**: Aim for high code coverage but focus on testing behavior, not implementation
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
Tests should be run automatically on:
|
||||
- Every pull request
|
||||
- Before releases
|
||||
- Nightly builds
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Unit Tests
|
||||
|
||||
1. **Mockito Issues**: If you get "Mockito cannot mock this class", check:
|
||||
- Add `@RunWith(MockitoJUnitRunner.class)` to test class
|
||||
- Ensure `mockito-inline` dependency is included
|
||||
|
||||
2. **Robolectric Issues**: If tests fail with Robolectric:
|
||||
- Check SDK version compatibility
|
||||
- Add `@Config` annotation with correct SDK version
|
||||
|
||||
### Integration Tests
|
||||
|
||||
1. **Emulator Issues**:
|
||||
- Ensure emulator is running or device is connected
|
||||
- Check that developer options and USB debugging are enabled
|
||||
|
||||
2. **Timing Issues**: Add proper waits and delays:
|
||||
```java
|
||||
Thread.sleep(1000); // Simple delay
|
||||
device.wait(Until.hasObject(By.pkg("com.streamplayer")), 5000);
|
||||
```
|
||||
|
||||
3. **Permission Issues**: Add necessary permissions to test manifest
|
||||
|
||||
## Future Improvements
|
||||
|
||||
1. Add more unit tests for other classes
|
||||
2. Implement test doubles for network layer
|
||||
3. Add performance tests
|
||||
4. Add screenshot tests for UI regression testing
|
||||
5. Implement mutation testing to verify test quality
|
||||
6. Add integration tests for error scenarios
|
||||
7. Implement automated test reporting
|
||||
|
||||
## Firebase Configuration
|
||||
|
||||
To use Firebase services (Crashlytics, Analytics, Performance):
|
||||
|
||||
1. Download `google-services.json` from Firebase Console
|
||||
2. Place it in `app/` directory (replace the example file)
|
||||
3. Firebase plugins are already configured in `build.gradle`
|
||||
|
||||
## LeakCanary
|
||||
|
||||
LeakCanary is included for debug builds to detect memory leaks:
|
||||
```gradle
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
|
||||
```
|
||||
|
||||
Check logcat for leak analysis results when testing on device/emulator.
|
||||
|
||||
## ProGuard/R8
|
||||
|
||||
ProGuard rules have been updated to keep test-related classes:
|
||||
- Keep ExoPlayer classes
|
||||
- Keep OkHttp classes
|
||||
- Keep Gson model classes
|
||||
- Keep test classes and methods
|
||||
|
||||
## Resources
|
||||
|
||||
- [Android Testing Documentation](https://developer.android.com/training/testing)
|
||||
- [JUnit 4 Documentation](https://junit.org/junit4/)
|
||||
- [Mockito Documentation](https://site.mockito.org/)
|
||||
- [Espresso Documentation](https://developer.android.com/training/testing/espresso)
|
||||
Generated
-1017
File diff suppressed because it is too large
Load Diff
Generated
-10
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,78 +0,0 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace "com.streamplayer"
|
||||
compileSdk 33
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.streamplayer"
|
||||
minSdk 21
|
||||
targetSdk 33
|
||||
versionCode 94200
|
||||
versionName "9.4.2"
|
||||
buildConfigField "String", "DEVICE_REGISTRY_URL", '"http://194.163.191.200:4000"'
|
||||
buildConfigField "String", "EVENTS_URL", '"https://streamtpmedia.com/eventos.json"'
|
||||
buildConfigField "String", "RELEASE_API_URL", '"https://gitea.cbcren.online/api/v1/repos/renato97/app/releases/latest"'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
signingConfig signingConfigs.debug
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lint {
|
||||
checkReleaseBuilds = false
|
||||
abortOnError = false
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources {
|
||||
excludes += 'META-INF/com.android.tools/proguard/coroutines.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.2'
|
||||
|
||||
// ExoPlayer para reproducción de video
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.18.7'
|
||||
implementation 'com.google.android.exoplayer:extension-okhttp:2.18.7'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.12.0'
|
||||
|
||||
// Gson para parseo JSON
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
|
||||
// Testing dependencies
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.mockito:mockito-core:5.7.0'
|
||||
testImplementation 'org.mockito:mockito-inline:5.2.0'
|
||||
testImplementation 'androidx.arch.core:core-testing:2.2.0'
|
||||
testImplementation 'org.robolectric:robolectric:4.11.1'
|
||||
|
||||
// Android Test dependencies
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* Automatically generated file. DO NOT MODIFY
|
||||
*/
|
||||
package com.streamplayer;
|
||||
|
||||
public final class BuildConfig {
|
||||
public static final boolean DEBUG = Boolean.parseBoolean("true");
|
||||
public static final String APPLICATION_ID = "com.streamplayer";
|
||||
public static final String BUILD_TYPE = "debug";
|
||||
public static final int VERSION_CODE = 94200;
|
||||
public static final String VERSION_NAME = "9.4.2";
|
||||
// Field from default config.
|
||||
public static final String DEVICE_REGISTRY_URL = "http://194.163.191.200:4000";
|
||||
// Field from default config.
|
||||
public static final String EVENTS_URL = "https://streamtpmedia.com/eventos.json";
|
||||
// Field from default config.
|
||||
public static final String RELEASE_API_URL = "https://gitea.cbcren.online/api/v1/repos/renato97/app/releases/latest";
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
#- File Locator -
|
||||
listingFile=../../../../outputs/apk/debug/output-metadata.json
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
appMetadataVersion=1.1
|
||||
androidGradlePluginVersion=8.5.1
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "COMPATIBLE_SCREEN_MANIFEST",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.streamplayer",
|
||||
"variantName": "debug",
|
||||
"elements": []
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
12
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user