web-dev-qa-db-fra.com

services android - erreur: service non enregistré

J'essaie de comprendre les services délimités. Ci-dessous mon exemple de programme dans lequel j'essaie de suivre http://developer.Android.com/guide/components/bound-services.html . Le service fonctionne dans la mesure où je peux lire, mettre en pause et arrêter l'audio. Cependant, lorsque je passe à une autre application, l'erreur suivante relative au service non enregistré apparaît. 

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)

Comme le codage semble suivre de près l'exemple de la documentation, je n'ai aucune idée de ce qui ne va pas. J'exécute cette application avec minSdk niveau 8. L'erreur se produit dans MainActivity.onStop à la ligne

 mService.unbindService(mConnection);

Toutes les suggestions pour résoudre ce problème seraient formidables.

Merci

martin

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

}

et

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

}

}
25
dorjeduck

Avait un problème similaire, mais la réponse acceptée n'était pas la solution pour moi. Heureusement, un des commentaires m'a donné la réponse:

onServiceDisconnected n'est pas censé être levé lorsque vous dissociez votre service, ne vous y fiez pas. Il est supposé vous informer en cas de perte de la connexion entre votre service et ServiceConnection. 

Grâce à @Waqas, j'ai trouvé l'erreur: je mettais à jour l'indicateur boolean binded uniquement à l'intérieur de onServiceConnected() et onServiceDisconnected(). Maintenant, j'ai ajouté "binded = false" chaque fois que j'appelle unbindService() et le problème a disparu. C'est ça, ne comptez pas sur onServiceDisconnected

57
Salvatorelab

Ah, un de ces jours 

mService.unbindService(mConnection);

est évidemment absurde, appeler unbind dans le mauvais contexte. CA devrait etre

unbindService(mConnection); 

Une erreur supplémentaire dans le codage affiché est l'absence de 

@Override
public boolean onUnbind(Intent intent) {
    // All clients have unbound with unbindService()

    releaseMediaPlayer();

    return false;
}
19
dorjeduck

Sidenote, aucune des autres réponses n’ayant aidé, j’ai constaté que mon erreur utilisait une variable Context différente pour bind et unbind. Mon lien provenait du contexte de l'application, mais mon lien non lié provenait du contexte de l'activité.

Pour corriger l'erreur, je me suis assuré d'utiliser le même contexte pour bindService() et unbindService().

6
Anonsage

Ma MediaPlayer s'arrêterait lorsque j'aurais tué l'application, mais la couche de 5 minutes ou moins serait relancée toute seule.

Pour résoudre ce problème, en plus de la réponse de @ dorjeduck, je devais également appeler mediaPlayer.stop() avant d'appeler mediaPlayer.release().

0
craned