Wie Sie verhindern, dass mediaplayer zu stoppen, wenn der Bildschirm aus geht?
Ich habe einen mediaplayer in einem Music
Klasse, die aufgerufen wird von einem anderen sekundären Activity
. Es funktioniert einwandfrei.
Aber wenn der Bildschirm aus geht (entweder durch timeout oder eine Schaltfläche), die Musik aufhört zu spielen, und wenn Sie wieder kommen und versuchen, schließen Sie die Aktivität geht das Programm zu "App Reagiert Nicht", da ein IllegalStateException
bei einer Abfrage wie mediaplayer.isPlaying()
.
Wie kann ich verhindern das der mediaplayer Stoppt, wenn Bildschirm aus geht?
Muss es sein, durch einen service??
Unter der Annahme, dass die Antwort ist ja, ich habe versucht, zu konvertieren, die Music
class-in-a-service (siehe unten). Ich habe auch <service android:enabled="true" android:name=".Music" />
in die Manifest.xml
, und ich rufe die Music
Klasse wie folgt aus:
startService(new Intent(getBaseContext(), Music.class));
Music track = Music(fileDescriptor);
Nur 2 neue Zeilen in die main-Aktivität sind startService(new Intent(getBaseContext(), Music.class));
und stopService(new Intent(getBaseContext(), Music.class));
zusammen mit den entsprechenden Einfuhren.
Aber jetzt bekomme ich InstantiationException
Fehler, da can't instantiate class
beim Versuch den Dienst zu starten. Was bin ich?
Dies ist die Ausnahme:
E/AndroidRuntime(16642): FATAL EXCEPTION: main
E/AndroidRuntime(16642): java.lang.RuntimeException: Unable to instantiate service com.floritfoto.apps.ave.Music: java.lang.InstantiationException: can't instantiate class com.floritfoto.apps.ave.Music; no empty constructor
E/AndroidRuntime(16642): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2249)
E/AndroidRuntime(16642): at android.app.ActivityThread.access$1600(ActivityThread.java:127)
E/AndroidRuntime(16642): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213)
E/AndroidRuntime(16642): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(16642): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(16642): at android.app.ActivityThread.main(ActivityThread.java:4507)
E/AndroidRuntime(16642): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(16642): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(16642): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
E/AndroidRuntime(16642): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
E/AndroidRuntime(16642): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(16642): Caused by: java.lang.InstantiationException: can't instantiate class com.floritfoto.apps.ave.Music; no empty constructor
E/AndroidRuntime(16642): at java.lang.Class.newInstanceImpl(Native Method)
E/AndroidRuntime(16642): at java.lang.Class.newInstance(Class.java:1319)
E/AndroidRuntime(16642): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2246)
E/AndroidRuntime(16642): ... 10 more
- und dies ist die Music.class:
package com.floritfoto.apps.ave;
import java.io.FileDescriptor;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
import android.widget.Toast;
public class Music extends Service implements OnCompletionListener{
MediaPlayer mediaPlayer;
boolean isPrepared = false;
////TEstes de servico
@Override
public void onCreate() {
super.onCreate();
info("Servico criado!");
}
@Override
public void onDestroy() {
info("Servico fudeu!");
}
@Override
public void onStart(Intent intent, int startid) {
info("Servico started!");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void info(String txt) {
Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_LONG);
toast.show();
}
////Fim testes de servico
public Music(FileDescriptor fileDescriptor){
mediaPlayer = new MediaPlayer();
try{
mediaPlayer.setDataSource(fileDescriptor);
mediaPlayer.prepare();
isPrepared = true;
mediaPlayer.setOnCompletionListener(this);
} catch(Exception ex){
throw new RuntimeException("Couldn't load music, uh oh!");
}
}
public void onCompletion(MediaPlayer mediaPlayer) {
synchronized(this){
isPrepared = false;
}
}
public void play() {
if(mediaPlayer.isPlaying()) return;
try{
synchronized(this){
if(!isPrepared){
mediaPlayer.prepare();
}
mediaPlayer.seekTo(0);
mediaPlayer.start();
}
} catch(IllegalStateException ex){
ex.printStackTrace();
} catch(IOException ex){
ex.printStackTrace();
}
}
public void stop() {
mediaPlayer.stop();
synchronized(this){
isPrepared = false;
}
}
public void switchTracks(){
mediaPlayer.seekTo(0);
mediaPlayer.pause();
}
public void pause() {
mediaPlayer.pause();
}
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
public boolean isLooping() {
return mediaPlayer.isLooping();
}
public void setLooping(boolean isLooping) {
mediaPlayer.setLooping(isLooping);
}
public void setVolume(float volumeLeft, float volumeRight) {
mediaPlayer.setVolume(volumeLeft, volumeRight);
}
public String getDuration() {
return String.valueOf((int)(mediaPlayer.getDuration()/1000));
}
public void dispose() {
if(mediaPlayer.isPlaying()){
stop();
}
mediaPlayer.release();
}
}
- haben Sie Lesen Sie die Dokumentation auf, wie man einen Dienst nutzen ? developer.android.com/reference/android/app/Service.html
- Natürlich nicht! Ich will einfach nur zu implementieren, die die meisten grundlegenden mediaplayer je gemacht!! Ich will nicht (und erwarte nicht müssen), zu wissen, alle seine Feinheiten. Ich versuche nur zu Folgen, die (berühmte?) marakana Beispiel hier marakana.com/forums/android/examples/60.html. Was mache ich falsch...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese Linie von Logcat ist das wichtige:
Ihre service-Bedürfnisse einen anderen Konstruktor ohne Argumente:
BEARBEITEN:
Sich mit einem service ist der richtige Ansatz, wenn Sie möchten, um die Musik zu spielen, wenn der Bildschirm ausgeschaltet ist. Jedoch, das Telefon wird versuchen, zu schlafen, wenn der Bildschirm ausgeschaltet ist, und kann diese unterbrechen Ihr
MediaPlayer
.Die zuverlässigste Lösung ist die Benutzung eines partial WakeLock zu verhindern, dass das Gerät vom schlafen während Sie Musik wiedergeben. Werden Sie sicher, dass die Freigabe der
WakeLock
richtig, wenn Sie nicht aktiv spielen die Musik, die sonst die Batterie entladen wird.Können Sie auch verwenden möchten
startForeground()
, die reduzieren das Risiko von Ihrem Dienst getötet zu werden, wenn es der Arbeitsspeicher. Es wird auch eine schöne Nutzererfahrung, indem Sie zeigen, eine persistente Benachrichtigung, wenn Dienst ausgeführt wird.Instanziierung der
Music
Klasse mitMusic track = Music(fileDescriptor);
ist wahrscheinlich tun einige Schäden. Ein besserer Ansatz ist die übergabe der Datei-Deskriptor alsExtra
imIntent
dass Sie anstartService()
:Dann, abrufen der Datei-Deskriptor von demselben
Intent
wenn es übergeben wird, um Ihre serviceonStartCommand()
Methode:Ein paar Dinge hier zu beachten. Ich habe verschoben Sie den code von Ihrer original-Konstruktor (sollte entfernt werden) in
onStartCommand()
. Sie können entfernen Sie dieonStart()
Methode als gut, denn es wird nur aufgerufen werden, auf pre-2.0-Geräte. Wenn Sie möchten, zur Unterstützung modernen Android-Versionen, müssen Sie mitonStartCommand()
statt. Endlich, dieSTART_STICKY
Rückgabewert wird sichergestellt, dass der Dienst bleibt aktiv, bis Sie Sie nennenstopService()
von Ihrer Aktivität.EDIT 2:
Sich mit einem service ermöglicht Benutzern das navigieren zwischen Aktivitäten, die ohne Unterbrechung des
MediaPlayer
. Sie haben nicht viel Kontrolle darüber, wie lange einActivity
bleiben im Speicher, sondern ein aktiverService
(vor allem, wenn Sie anrufenstartForeground()
) nicht getötet werden, es sei denn, es gibt sehr starke Arbeitsspeicher.Zur Interaktion mit der
MediaPlayer
nachdem der Dienst gestartet wird, haben Sie ein paar Optionen. Übergeben Sie zusätzliche Befehle, um den Dienst durch die SchaffungIntent
s und mit der Aktion string (und/oder einige extras) zu sagen, das service, was Sie möchten, es zu tun. Rufen Sie einfachstartActivity()
wieder mit dem neuenIntent
, undonStartCommand()
aufgerufen wird, im service, an welcher Stelle Sie können manipulieren dieMediaPlayer
. Die zweite Möglichkeit ist die Verwendung eines gebunden-service (Beispiel hier) und bind/unbind jedes mal, wenn Sie enter/verlassen einer Aktivität benötigt für die Kommunikation mit dem service. Mit einem gebundenen service "fühlt" sich an, als würde man direkt mit der Manipulation der service, aber es ist auch komplexer, da Sie brauchen, um zu verwalten FREIBLEIBEND und unverbindlich.public Music(FileDescriptor fileDescriptor){
? Ich Tat es, und bekam "Der Konstruktor-Dienst(String) ist nicht definiert", und fragte mich, entfernen Sie die "Musik". Ich Tat es, und die sehr gleicheInstantiationException
. 🙁"Music"
innerhalb der Klammer). Aber dann bekomme ich noch das gleiche problem: ich sehe in der logcat, dass der mediaplayer wird getrennt, sobald der Bildschirm ausgeschaltet ist und ich bekommeIllegalStateException
wenn-AbfragemediaPlayer.isPlaying
, wie wenn noch keine Leistung ausgeführt wurde. 🙁Service
. Zum Beispiel, können Sie definieren Methoden, die die Wiedergabe-status oder die Dauer des aktuellen Songs. Bitte werfen Sie einen Blick auf die Beispiel-link unten meine Antwort.als option können Sie den Bildschirm aktiviert zu halten die MediaPlayer Wiedergabe der Medien: