R: Sigue environment-setup.md. Necesitas:
./gradlew clean build # verificar setup
R: Android Studio 2023.2 o superior. Si es vieja, actualiza:
brew install android-studioR: Ver build-and-deployment.md:
export KEYSTORE_PASS="tu_pass" export KEY_PASS="tu_key_pass" ./gradlew :Machine:assembleRelease # APK está en: build/outputs/apk/release/Machine-release.apk
R: Necesitas configurar signing en build.gradle.kts:
android { signingConfigs { release { storeFile = file("../keystore/machine-release.jks") storePassword = System.getenv("KEYSTORE_PASS") keyAlias = "machine-key" keyPassword = System.getenv("KEY_PASS") } } buildTypes { release { signingConfig = signingConfigs["release"] } } }
R:
# Debug adb install build/outputs/apk/debug/Machine-debug.apk # Release (después de release build) adb install build/outputs/apk/release/Machine-release.apk # Reinstalar adb install -r build/outputs/apk/release/Machine-release.apk
R:
mkdir MyModuleMyModule/build.gradle.kts:plugins { id("com.android.library") kotlin("android") } android { namespace = "co.ada.mymodule" compileSdk = 36 // ... } dependencies { implementation(project(":Contract")) implementation(project(":Core")) }
settings.gradle.kts:include(":MyModule") project(":MyModule").projectDir = file("MyModule")
> Gradle → Sync NowR:
Machine/src/main/…RutaPAE/src/main/…MachineDomain/ o RutaPAEDomain/MachineData/ o RutaPAEData/
R: En MachineDomain/src/…/state/:
MyNewState.ktStateStateManager.workflowVer developer-guide.md.
R: En MachineDomain/src/…/endpoints/MachineEndpoints.kt:
object MachineEndpoints { fun getMyData(): Request { return "${backendUrl}/api/mydata" .httpGet() .responseJson() } } // Usar val data = MachineEndpoints.getMyData()
R: Ver testing-guide.md. Ejemplo unit test:
@RunWith(RobolectricTestRunner::class) class StateManagerTest { @Test fun testStateTransition() { val manager = StateManager(mockRepository, mockHardware) manager.init(context) assertEquals("WaitingForWeight", manager.getCurrentState()) } }
Ejecutar:
./gradlew test
R: Con Compose test:
@RunWith(AndroidJUnit4::class) class LaboratoryScreenTest { @get:Rule val composeTestRule = createComposeRule() @Test fun testButtonVisible() { composeTestRule.setContent { LaboratoryScreen(viewModel()) } composeTestRule.onNodeWithText("Capturar").assertIsDisplayed() } }
R: En RutaPAE, enqueue worker:
DeliverySyncScheduler.enqueue(context, machineId = 1L)
Esto crea una operación P2P que:
Ver p2p-flow.md.
R: Hay fallback a hotspot. Si también falla:
R:
val p2pManager = DomainManager.p2pManager val peers = p2pManager.discoveredMachineCandidates() // peers contiene máquinas disponibles
R: En StateManager:
val bitmap = Camera2Service(context).takeSelfie() if (bitmap != null) { stateData.facePhoto = bitmap next() } else { retry("Camera error") }
R: Requiere permissions:
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
Luego:
val scale = BluetoothScaleManager(context, MAC_ADDRESS) scale.addEventListener(listener) val weight = scale.getWeight()
R: En dispositivo Android:
adb shell bluetoothctl > devices # lista con direcciones MAC
R: Usar findSimilar:
val embedding = generateEmbedding(facePhoto) val similar = BeneficiaryService.findSimilar(embedding, similarity = 0.8f) // similar contiene top resultados por similitud for (beneficiary in similar) { println("${beneficiary.name}: ${similarity}") }
R:
data class Delivery en MachineData/src/…/entities/data class Delivery( val id: Long, val weight: Float, val nuevoCampo: String = "" // new field )
R: Limpiar en background:
val oneMonthAgo = System.currentTimeMillis() - 30.days.inMilliseconds repository.deliveries.where { it.createdAt < oneMonthAgo } .forEach { repository.deliveries.delete(it.id) }
R: Ver security-and-privacy.md:
// Guardar tokens de forma segura val encryptedPrefs = EncryptedSharedPreferences.create(context, ...) encryptedPrefs.edit().putString("api_token", token).apply() // Leer val token = encryptedPrefs.getString("api_token", null)
R: Usar logger personalizado:
// ❌ Malo Log.d("API", "Token: $token") // ✅ Bueno Log.d("API", "User authenticated") // ✅ Mejor SecureLogger.logToken(token) // oculta la mayoría
R: Sí, en producción. Configurar:
val certificatePinner = CertificatePinner.Builder() .add("backend.api.com", "sha256/AAAAAAA...") .build()
R: Este es el cuello de botella típico. Soluciones:
R: Causas comunes:
withContext(Dispatchers.IO)Ver troubleshooting.md#app-muy-lenta.
R: Abrir Logcat:
Android Studio → View → Tool Windows → Logcat
Filtrar:
Filter: "StateManager" # solo líneas con StateManager
O vía terminal:
adb logcat | grep StateManager
R: Click en número de línea (izquierda):
1. Marcar breakpoint (punto rojo) 2. Run → Debug 'Machine' (Shift+F9) 3. App pausa cuando llega a línea 4. F9 para continuar 5. F10 para step over 6. F11 para step into
R: Ver logcat completo:
adb logcat | tail -100
O usar Android Profiler:
Android Studio → View → Tool Windows → Profiler
R: No synchronized gradle. Falta sync:
Android Studio: File → Sync Now O terminal: ./gradlew clean build
R: Solicitar en runtime (API 23+):
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.CAMERA), 100) }
R:
Ver troubleshooting.md#bluetooth-connection-refused.
R:
// Flow: observable stream val deliveriesFlow: Flow<List<Delivery>> = ... // StateFlow: estado actual val currentState = MutableStateFlow<State>(State.Idle) currentState.value // acceder estado actual
R:
// suspend: simple suspend fun getData(): String = repository.getString() // async: paralelismo val result1 = async { repository.getString() } val result2 = async { repository.getInt() } // esperar ambas val r1 = result1.await() val r2 = result2.await()
R: Seguir estructura:
co.ada.MODULE/ ├── screens/ # UI Composables (si app) ├── viewmodels/ # ViewModel (si app) ├── domain/ │ ├── managers/ # orquestadores │ └── services/ # lógica ├── data/ │ ├── entities/ # modelos BD │ └── repository/ # CRUD └── di/ # inyección
R:
R: Ver best-practices.md:
R: Issues en GitHub con:
R: Proyectos en GitHub. Planificación trimestral.
R: Abrir discussion en GitHub con: