AndroidのMediaPlayerに問題があります。重要な機能、主にMediaPlayerの現在のステータスを取得する方法、または準備ができているかどうかを確認する方法が不足しているようです。準備されたリスナーがあることは知っていますが、MediaPlayerはアクティビティよりも長持ちするため、再生アクティビティが再開されたときに、メディアをロードしようとしているかどうか、メディアがロードされているかどうかなど、現在のプレーヤーの状態を取得すると便利です。 。何かが足りないのですか、それともプレーヤーの状態を自分で追跡する必要がありますか?
ニースになる他の機能はonPlayStateChanged()です-私は現在、手動で再生状態を追跡する必要があります。私はそれを間違っていますか?
答えるのに遅すぎないことを願っています。 MediaPlayer クラスには、isPrepared()メソッドやgetStatus()メソッドなどはなく、自分でその状態を追跡する必要があります。しかし、それはそれほど難しいことではありません。
MediaPlayerクラスには、非常に役立つ優れた状態図があります。その図に基づいてサービスを実装する必要があります。また、MediaPlayerオブジェクトを常に同じスレッドから制御している場合は、その状態を追跡するのは簡単なので、そうすることをお勧めします。 prepareAsync()メソッドは、処理する必要がある唯一の非同期メソッドですが、プレーヤーが準備中であることを示すブール値を保持できます。これは、prepareAsync()呼び出しからonPrepared()がと呼ばれます。とにかく、いつでもonErrorを実装し、IllegalStateExceptionをキャッチして、不正な状態から誤ってメソッドを呼び出した場合のクラッシュを回避できます。
それにもかかわらず、 メディア再生ガイド は私を大いに助けました。
問題のトラブルシューティングを行うためにデバッグ中にステータスを確認する必要があったため、MediaPlayerが準備されたことを知った後、このコードをどこかに配置しました。
try {
this.audioPlayer.prepare();
} catch (Exception e) {
}
これにより、「E/MediaPlayer:prepareAsyncが状態32で呼び出されました」のようなエラーがコンソールに出力されます。
さて、すべてのステータスコードがリストされている場所を見つけることができたら...
私はあなたや他の人に役立つかもしれない何かを見つけました。 MediaPlayerクラスにはsetOnPreparedListener()
関数があり、MediaPlayerの準備時にコードの一部を実行できるようにします。
また、メディアがロードされていることを確認したい場合は、getDuration()
関数を使用できます。このコードはミリ秒単位で期間を返します。利用可能な期間がない場合は-1を返します。以下にコードを示します。
yourMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if(yourMediaPlayer.getDuration() != -1){
//your code when when something is loading
}
}
}
getState
クラスのMediaPlayer
はありませんが、alex.magellanで説明されているように、内部的には状態があります。 「許可されていない状態」でメソッドを呼び出すと、例外が発生します。
これらを回避するために、StateMachine
クラスでMediaPlayerWrapper
を作成しました。したがって、MediaPlayer
を直接呼び出す代わりに、MediaPlayerWrapper
が使用されます。これにより、StateMachine
が内部的に更新され、getState()
メソッドが公開されます。
StateMachine
およびWrapper
クラスの実装は ここにあります。
MediaPlayerクラス自体を介してそれを行う方法はないと思います。
最も簡単なことは、作成およびリセット時にtrueに設定されるグローバル変数です。リリース時にfalseに設定されます。
boolean playerAvailable = true;
mediaPlayer = MediaPlayer.create(myContext, soundId); // ready to play
playerAvailable = true;
....
mediaPlayer.reset(); // ready to play again
playerAvailable = true;
....
mediaPlayer.release(); // can't be played until release.
playerAvailable = false;