2012-04-10 3 views
9

Ich schreibe eine Android-Alarm-Anwendung, die einen Dienst verwendet, um den Alarmton zu spielen. Momentan kann ich das Audio abspielen lassen, aber es wird in einer Form wiedergegeben, die stummgeschaltet werden kann, indem die Lautstärke des Geräts heruntergeregelt wird. Daher versuche ich einen Anruf zu setAudioStreamType(AudioManager.STREAM_ALARM); hinzuzufügen, um dies zu verhindern.(Android MediaPlayer) Wie soll ich setAudioStreamType() aufrufen, wenn MediaPlayer.create() implizit prepare() aufruft?

Ich habe folgende für meine onStartCommand() Funktion für den Service:

MediaPlayer mMP;  
@Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     try 
     { 
      mMP = MediaPlayer.create(this, R.raw.alarm); 
      mMP.setAudioStreamType(AudioManager.STREAM_ALARM); 
      mMP.setLooping(true); 
      //mMP.prepare(); commented out since prepare() is called in create 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     if (mMP != null) mMP.start(); 

     return START_STICKY; 
    } 

Mein Problem ist, dass mit dem Aufruf von setAudioStreamType(), der Mediaplayer nie das Audio spielt. Wenn ich diese Zeile kommentiere, wird das Audio abgespielt.

Mit der Linie in, erhalte ich die folgenden Laufzeitfehler (e):

04-10 19: 32: 03,115: E/Mediaplayer (3411): setAudioStream im Zustand genannt 8

04-10 19: 32: 03,115: E/Mediaplayer (3411): Fehler (-38, 0)

04-10 19: 32: 03,115: E/Mediaplayer (3411): im Zustand 0

genannt anfangen

04-10 19: 32: 03.115: E/MediaPlayer (3411): Fehler (-38, 0)

04-10 19: 32: 03,115: E/Mediaplayer (3411): Fehler (-38,0)

04-10 19: 32: 03,115: E/Mediaplayer (3411): Fehler (- 38,0)

Einige Untersuchungen (ich kann den Link jetzt nicht gefunden) sagte mir, dass setAudioStreamType() nicht aufgerufen werden kann, nachdem prepare() aufgerufen wurde, und dass create() implizit aufruft prepare().

In jeder Hinsicht, wie soll ich setAudioStreamType() ohne einen solchen Fehler?

Antwort

12

Sie können entweder mp.reset() anrufen und dann den Datenstromtyp und die Datenquelle festlegen und dann vorbereiten. Alternativ verwenden Sie einfach den Standardkonstruktor und behandeln die Initialisierung selbst.

EDIT:

Resources res = getResources(); 
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.alarm); 

mp.reset(); 
mp.setAudioStreamType(AudioManager.STREAM_ALARM); 
mp.setLooping(true); 
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
mp.prepare(); 
mp.start(); 
+0

Es klingt wie Sie etwas in dieser Richtung sind darauf hindeutet (beginnend nach dem Aufruf von 'create()'): 'reset();' 'setAudioStreamType();' 'setLooping();' 'prepare();' Bin ich richtig? Wenn ja, bekomme ich beim Aufruf zur Vorbereitung folgenden Fehler: '04-10 20: 06: 25.515: E/MediaPlayer (845): Aufruf im Zustand 1 gestartet ' ' 04-10 20: 06: 25.515: E/MediaPlayer (845): error (-38, 0) ' – finiteloop

+0

Scheint, als ob Sie den Fehler beim Aufruf von' start() 'tatsächlich bekommen, nicht' prepare() '. Können Sie den aktualisierten Code zur Frage hinzufügen? – kcoppock

+0

Sie haben Recht, dieser besondere Fehler ist nach dem Aufruf zum Starten aufgetreten, es ist auch ein Fehler beim Aufruf zur Vorbereitung aufgetreten, den ich im Protokoll verpasst habe, als ich meinen Kommentar gepostet habe. '04-10 21: 42: 11.896: E/MediaPlayer (593): prepareAsync im Zustand 1' aufgerufen. – finiteloop

2

akzeptierte Antwort wirft ein Illegal. Dies funktioniert

MediaPlayer mediaPlayer = new MediaPlayer(); 

try { 
    mediaPlayer.setDataSource(
      this, 
      getCustomToneUri() 
); 

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); 

    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
    @Override 
    public void onPrepared(MediaPlayer mp) { 
     mp.start(); 
    } 
    }); 

    mediaPlayer.prepareAsync(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
Verwandte Themen