Servicios android – error: servicio no registrado
Estoy tratando de entender los servicios limitados. Debajo de mi programa de ejemplo en el que intento seguir http://developer.android.com/guide/components/bound-services.html . El servicio funciona en la medida de lo que puedo reproducir, pausar y detener el audio, pero cuando cambio a otra aplicación me sale el siguiente servicio no registrado error.
java.lang.RuntimeException: Unable to stop activity {com.example.dd_services_audio_01/com.example.dd_services_audio_01.MainActivity}: java.lang.IllegalArgumentException: Service not registered: com.example.dd_services_audio_01.MainActivity$1@2afca5d8 09-05 14:04:32.625: E/AndroidRuntime(5810): at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:2451) 09-05 14:04:32.625: E/AndroidRuntime(5810): at android.app.ActivityThread.handleStopActivity(ActivityThread.java:2496)
Como la codificación parece seguir el ejemplo de la documentación de cerca no tengo ni idea de dónde van las cosas mal. Ejecuto esta aplicación con minSdk nivel 8. El error ocurre en MainActivity.onStop en la línea
- Service vs Thread en Android
- StopService no deja de ser mi servicio ... ¿por qué?
- Diálogo de alerta del servicio de Android
- ¿Cómo mostrar Toast de un Servicio después de que la actividad principal termine?
- La aplicación de Android que supervisa las llamadas entrantes mantiene el teléfono despierto
mService.unbindService(mConnection);
Cualquier sugerencia para resolver esto sería grande.
Gracias
martín
package com.example.dd_services_audio_01; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.example.dd_services_audio_01.AudioPlayerService.AudioPlayerBinder; public class MainActivity extends Activity { private final String TAG = "MainActivity"; AudioPlayerService mService; boolean mBound = false; Button mPlay, mPause, mStop; String audioFile = Environment.getExternalStorageDirectory() + "/justdzongsar/DJKR_AboutToGetIt.mp3"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG,"onCreate"); setContentView(R.layout.activity_main); mPlay = (Button) findViewById(R.id.buttonPlay); mPause = (Button) findViewById(R.id.buttonPause); mStop = (Button) findViewById(R.id.buttonStop); mPlay.setOnClickListener(new OnClickListener() { public void onClick(View v) { mService.play(audioFile); } }); mPause.setOnClickListener(new OnClickListener() { public void onClick(View v) { mService.pause(); } }); mStop.setOnClickListener(new OnClickListener() { public void onClick(View v) { mService.stop(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override protected void onStart() { super.onStart(); // Bind to LocalService Intent intent = new Intent(this, AudioPlayerService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); if (mBound) { mService.unbindService(mConnection); mBound=false; } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get // LocalService instance AudioPlayerBinder binder = (AudioPlayerBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mService = null; mBound = false; } }; }
y
package com.example.dd_services_audio_01; import java.io.IOException; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnPreparedListener; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class AudioPlayerService extends Service implements OnPreparedListener, OnCompletionListener { private final String TAG = "AudioPlayerService"; private final IBinder mBinder = new AudioPlayerBinder(); private MediaPlayer mMediaPlayer; private String currentDataSource; public class AudioPlayerBinder extends Binder { public AudioPlayerService getService() { Log.v(TAG, "AudioPlayerBinder: getService() called"); return AudioPlayerService.this; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return mBinder; } @Override public boolean onUnbind(Intent intent) { // All clients have unbound with unbindService() return false; } @Override public void onStart(Intent intent, int startId) { Log.i(TAG, "AudioPlayerService: onStart() called, instance=" + this.hashCode()); } @Override public void onDestroy() { Log.i(TAG, "AudioPlayerService: onDestroy() called"); releaseMediaPlayer(); } // ----- public void play(String audioFile) { Log.d(TAG, "audio play called with file " + audioFile); if (mMediaPlayer != null && audioFile.compareTo(currentDataSource) == 0) { if (mMediaPlayer.isPlaying() == true) { return; } mMediaPlayer.start(); return; } releaseMediaPlayer(); try { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(audioFile); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnCompletionListener(this); currentDataSource = audioFile; mMediaPlayer.prepareAsync(); } catch (IOException ioe) { Log.e(TAG, "error trying to play " + audioFile, ioe); } } public void pause() { Log.d(TAG, "audio pause"); if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); } } public void seek(int timeInMillis) { if (mMediaPlayer != null) { mMediaPlayer.seekTo(timeInMillis); } } public int elapsed() { if (mMediaPlayer == null) { return 0; } return mMediaPlayer.getCurrentPosition(); } public void stop() { Log.d(TAG, "audio stop"); releaseMediaPlayer(); } // -- private void releaseMediaPlayer() { if (mMediaPlayer == null) { return; } if (mMediaPlayer.isPlaying()) { mMediaPlayer.stop(); } mMediaPlayer.release(); mMediaPlayer = null; } @Override public void onCompletion(MediaPlayer arg0) { // TODO Auto-generated method stub releaseMediaPlayer(); } @Override public void onPrepared(MediaPlayer mp) { if (mp != null) { mp.start(); } // TODO Auto-generated method stub } }
- Llamar el método de clase de actividad de la clase de servicio
- ¿Sigue funcionando un servicio incluso cuando el teléfono está dormido?
- Error "No se puede iniciar el servicio de intención" al iniciar el servicio desde una actividad en Android
- ¿Cómo implementar mejor dos actividades que comparten un servicio (con conexión Bluetooth)?
- Enfoque eficiente para comprobar continuamente si la conexión a Internet está disponible en Android
- Inicio del servicio desde otro servicio
- Android: Service vs SingleTop Actividad se trasladó al fondo - ¿cuál es la diferencia?
- Uso del servicio para ejecutar fondo y crear notificaciones
Tenía un problema similar, pero la respuesta aceptada no era la solución para mí. Afortunadamente uno de los comentarios me dio la respuesta:
OnServiceDisconnected no se supone que se plantea cuando desvincula su servicio, así que no confíe en él. Se supone que le informará en caso de que la conexión entre su Servicio y ServiceConnection se caiga.
Gracias a @Waqas encontré el error: estaba actualizando la bandera boolean binded
onServiceConnected()
sólo dentro de onServiceConnected()
y onServiceDisconnected()
. Ahora he agregado "binded = false" cada vez que llamo unbindService()
y el problema ha desaparecido. Eso es todo, no confíe en onServiceDisconnected
Ah, uno de estos días
mService.unbindService(mConnection);
Es obviamente absurdo, llamando a desatar en el contexto equivocado. Debería ser
unbindService(mConnection);
Un error adicional en la codificación publicada es la falta de
@Override public boolean onUnbind(Intent intent) { // All clients have unbound with unbindService() releaseMediaPlayer(); return false; }
Como un sidenote, ya que ninguna de las otras respuestas ayudó, encontré que mi error estaba utilizando un Context
diferente para unir y unbind. Mi enlace era del contexto de la Aplicación, pero mi desvinculación era del contexto de la Actividad.
Para corregir el error, me aseguré de utilizar el mismo contexto para bindService()
y unbindService()
.
Puede que tenga que asegurarse de que mService no es nulo. La línea siguiente me dio el error "Servicio no registrado":
if (mContext != null) mContext.unbindService(mServiceConn);
Esto era muy confuso porque mContext y mServiceConn no eran nulos.
Esto lo arregló:
if (mContext != null && mService != null) mContext.unbindService(mServiceConn);
Mi MediaPlayer
se detendría cuando matara la aplicación, pero con una capa de 5 minutos o menos, volvería a empezar de nuevo por sí solo.
Para solucionar esto, además de la respuesta de @ dorjeduck, tuve que llamar a mediaPlayer.stop()
antes de llamar a mediaPlayer.release()
.
- ¿Cómo animar la posición de desplazamiento? ¿Cómo desplazarse sin problemas?
- Las pestañas de Android ActionBar establecen la pestaña seleccionada inicialmente