Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

86
Views
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 answers
Answer question

0

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

over 4 years ago · Santiago Trujillo Report

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!