Ich habe meine eigene MediaPlayer-Klasse geschrieben, um Dateien unter einem bestimmten Pfad abzuspielen und Dateien aus dem Assets-Ordner wiederzugeben. Hier ist die Klasse:
public class CMediaPlayer extends MediaPlayer{
public void play(String audioPath){
this.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
File f = new File(audioPath);
if(f.exists()){
try{
FileInputStream fis = new FileInputStream(f);
FileDescriptor fileD = fis.getFD();
this.setDataSource(fileD);
this.prepare();
}catch(IOException e){
}
this.start();
}
}
public void play(AssetFileDescriptor descriptor){
this.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
try {
this.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
this.prepare();
}catch (IOException e){
}
this.start();
}
}
Ich möchte mit dieser Klasse mehrere Sounds aus einer Aktivität spielen. Hier ist mein Code:
public class playGame extends Activity {
//a lot of variables
CMediaPlayer mediaPlayer; //declare my mediaplayer
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
//release??????
Intent myIntent = new Intent(getBaseContext(), startView.class);
startActivity(myIntent);
}
return super.onKeyDown(keyCode, event);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_question2);
mediaPlayer = new CMediaPlayer(); //define my mediaplayer
//stuff
}
//more variables
public void playQuestion(File question){
//stuff
TextView myTextView = (TextView) findViewById(R.id.textViewQuestion);
//stuff
myTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaPlayer.play(pathSoundQuestion); //play sound when clicked
}
});
//stuff
myImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaPlayer.play(pathSoundQuestion); //play sound when clicked
}
});
//stuff
mediaPlayer.play(pathSoundQuestion); //plays sound immediatly, first played sound (works fine)
//button1
Button myButton = (Button) findViewById(R.id.button1);
//stuff
myButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
if(lastClickedButton == v){
//stuff
return;
}
//stuff
mediaPlayer.play(pathAudio1); //play sound when clicked (error)
}
});
//button2
myButton = (Button) findViewById(R.id.button2);
//stuff
myButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
if(lastClickedButton == v){
//stuff
return;
}
//stuff
mediaPlayer.play(pathAudio2); //play sound, same problem
}
});
//goes on like this some more times...
}
public void logIn(View v, String right){
//stuff
if(right.equals("true")){
//stuff
try {
AssetFileDescriptor descriptor = getAssets().openFd("Right");
mediaPlayer.play(descriptor); //play sound from assets
Intent myIntent = new Intent(getApplication(), playGame.class);
startActivity(myIntent);
}catch (IOException e){
}
}else{
//stuff
try {
AssetFileDescriptor descriptor = getAssets().openFd("Wrong");
mediaPlayer.play(descriptor); //play sound from assets
Intent myIntent = new Intent(getApplication(), playGame.class);
startActivity(myIntent);
}catch (IOException e){
}
}
}
}
Die App gibt den ersten Ton wieder, wie in meinen Kommentaren in meinem Code erwähnt. Wenn ich auf eine Schaltfläche klicke, die einen anderen Ton starten soll, erhalte ich die folgende Fehlermeldung:
03-16 23:07:38.478 13646-13646/com.example.cello.myownquiz E/AndroidRuntime﹕ FATAL EXCEPTION: main
Java.lang.IllegalStateException
at Android.media.MediaPlayer.setDataSource(Native Method)
at Android.media.MediaPlayer.setDataSource(MediaPlayer.Java:1005)
Ist meine MediaPlayer-Klasse in Ordnung oder fehlt mir je nach Status etwas? Ist diese Klasse die einzige Stelle, an der die Freigabe erfolgt, oder muss ich sie auch irgendwo in meiner Aktivität platzieren?
Kann jemand meinen Fehler sehen? Dieses Problem mit dem mediaPlayer hat mich einen ganzen Tag lang versucht, ich hoffe, Sie können mir helfen ...
mp.release();
in mp.reset();
ändern
public void reset ()
Setzt den MediaPlayer in den nicht initialisierten Zustand zurück. Nach dem Aufruf dieser Methode müssen Sie sie erneut initialisieren, indem Sie die Datenquelle festlegen und "prepare ()" aufrufen.
öffentliche void release ()
Gibt Ressourcen frei, die diesem MediaPlayer-Objekt zugeordnet sind. Es empfiehlt sich, diese Methode aufzurufen, wenn Sie mit dem MediaPlayer fertig sind. Immer wenn eine Activity einer Anwendung angehalten wird (ihre onPause () - Methode wird aufgerufen) oder gestoppt (ihre onStop () - Methode wird aufgerufen), sollte diese Methode aufgerufen werden, um das MediaPlayer-Objekt freizugeben, es sei denn, die Anwendung hat dies ein besonderes Bedürfnis, das Objekt um zu halten. Neben unnötigen Ressourcen (wie Speicher und Codec-Instanzen) kann ein nicht sofortiger Aufruf dieser Methode, wenn ein MediaPlayer-Objekt nicht mehr benötigt wird, zu einem fortlaufenden Batterieverbrauch für mobile Geräte und zu Wiedergabefehlern für andere Anwendungen führen, wenn dies nicht der Fall ist Mehrere Instanzen desselben Codecs werden auf einem Gerät unterstützt. Selbst wenn mehrere Instanzen desselben Codecs unterstützt werden, kann mit einer Leistungsverschlechterung gerechnet werden, wenn nicht mehrere Instanzen gleichzeitig verwendet werden.
Du musst das Objekt herumliegen lassen.
Sie können es auf einfache Weise tun
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(context, ringtone);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MEDIA);
mediaPlayer.prepare();
mediaPlayer.start();
ich habe auch dieses Problem, aber ich habe verwendet:
public void play(String name){
try {
AssetFileDescriptor afd = getAssets().openFd(name);
if(myPlayer == null){
myPlayer = new MediaPlayer();
}
myPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
myPlayer.prepare();
myPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
und zu stoppen:
public void stopPlayer(){
if(myPlayer!= null && myPlayer.isPlaying()){
myPlayer.stop();
myPlayer = null;
}else{
myPlayer = null;
}
}