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

  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 } } 

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() .

  • Android mejor manera de obtener la ubicación repetidamente en el fondo considerando la batería así
  • Análisis de fondo wifi en Android
  • Guardar el estado del servicio enlazado antes de que sea eliminado por Android
  • Ninguna llamada a onStartCommand () sigue al reinicio de un servicio bloqueado en Android 2.3
  • Android: comprueba si mi servicio se está ejecutando en segundo plano
  • Silencio de Google Iniciar sesión en el servicio de fondo Android
  • ¿Cómo reiniciar un servicio muerto automáticamente?
  • Parámetro startId de servicio de Android
  • Compartir una biblioteca nativa en dos aplicaciones
  • Cómo iniciar el servicio en android sin actividad
  • No se le permite enlazar con el servicio
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.