Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

80
Vistas
Wear OS Tiles and Media Service

El ejemplo de mosaicos de Wear OS es excelente, no es un problema, pero ¿cómo se iniciaría el servicio de medios en segundo plano que reproduce las canciones seleccionadas en la aplicación principal? Cada vez que intento iniciar el servicio, aparece el siguiente error. No hay un subproceso de interfaz de usuario al que hacer referencia y la documentación solo tiene métodos para onclick, LoadAction y LaunchAction.

 override fun onTileRequest(request: TileRequest) = serviceScope.future { when(request.state!!.lastClickableId){ "play"-> playClicked() }.... suspend fun playClicked(){ try { // Convert the asynchronous callback to a suspending coroutine suspendCancellableCoroutine<Unit> { cont -> mMediaBrowserCompat = MediaBrowserCompat( applicationContext, ComponentName(applicationContext, MusicService::class.java), mMediaBrowserCompatConnectionCallback, null ) mMediaBrowserCompat!!.connect() } }catch (e:Exception){ e.printStackTrace() } finally { mMediaBrowserCompat!!.disconnect() } }

ERROR

 java.lang.RuntimeException: Can't create handler inside thread Thread[DefaultDispatcher-worker-1,5,main] that has not called Looper.prepare()
over 4 years ago · Santiago Trujillo
4 Respuestas
Responde la pregunta

0

serviceScope se ejecuta en Dispatchers.IO, debe usar withContext(Dispatchers.Main) al realizar llamadas a MediaBrowserCompat.

over 4 years ago · Santiago Trujillo Denunciar

0

Cool Yuri, lo siguiente funcionó y creo que es más eficiente

 fun playClicked() = GlobalScope.launch(Dispatchers.Main) { mMediaBrowserCompat = MediaBrowserCompat( applicationContext, ComponentName(applicationContext, MusicaWearService::class.java), mMediaBrowserCompatConnectionCallback, null ) mMediaBrowserCompat!!.connect() }
over 4 years ago · Santiago Trujillo Denunciar

0

Gracias, Yuri, funcionó, pero terminó bloqueando el subproceso de la interfaz de usuario, la solución que funciona está a continuación.

 fun playClicked(){ mainHandler.post(playSong) } private val playSong: Runnable = object : Runnable { @RequiresApi(Build.VERSION_CODES.N) override fun run() { mMediaBrowserCompat = MediaBrowserCompat( applicationContext, ComponentName(applicationContext, MusicaWearService::class.java), mMediaBrowserCompatConnectionCallback, null ) mMediaBrowserCompat!!.connect() } }```
over 4 years ago · Santiago Trujillo Denunciar

0

En respuesta a la respuesta anterior, serviceScope.future crea un CoroutineScope que hará que el futuro devuelto al servicio espere a que se completen todos los trabajos secundarios.

Si desea que se ejecute de forma separada de la llamada onTileRequest, puede ejecutar lo siguiente, que iniciará un nuevo trabajo dentro de la aplicación GlobalScope y permitirá que onTileRequest regrese de inmediato.

 "play"-> GlobalScope.launch { }

El beneficio de esto es que no incluye un tercer modelo de concurrencia en la mezcla, ListenableFutures, Coroutines y ahora Handler. LF y Coroutines están destinados a evitar que tenga que recurrir a una tercera opción de concurrencia.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda