希望有人可以帮助我...
我有一个流.mp3
个文件的活动。它看起来像这样:
public class PlayMediaActivity extends Activity implements OnPreparedListener, MediaController.MediaPlayerControl{
private static final String TAG = "AudioPlayer";
private MediaPlayer mediaPlayer;
private MediaController mediaController;
private Handler handler = new Handler();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_media);
String title = this.getIntent().getStringExtra("Title");
String URL = this.getIntent().getStringExtra("URL");
this.setTitle(title); // Title on top of activity.
((TextView)findViewById(R.id.now_playing_text)).setText(title);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaController = new MediaController(this);
try {
mediaPlayer.setDataSource(URL);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
Log.e(TAG, "Could not open file " + title + " for playback.", e);
}
}
@Override
protected void onStop() {
super.onStop();
mediaController.hide();
mediaPlayer.stop();
mediaPlayer.release();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//the MediaController will hide after 3 seconds - tap the screen to make it appear again
mediaController.show();
return false;
}
//--MediaPlayerControl methods----------------------------------------------------
public void start() {
mediaPlayer.start();
}
public void pause() {
mediaPlayer.pause();
}
public int getDuration() {
return mediaPlayer.getDuration();
}
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
public void seekTo(int i) {
mediaPlayer.seekTo(i);
}
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
public int getBufferPercentage() {
return 0;
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
//--------------------------------------------------------------------------------
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "onPrepared");
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(findViewById(R.id.main_audio_view));
handler.post(new Runnable() {
public void run() {
mediaController.setEnabled(true);
mediaController.show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_play_media, menu);
return true;
}
}
这似乎很有效,直到我用telnet模拟电话(“gsm call”)并中断音频。当我完成通话后切换回我的应用时,它会从IllegalStateException
投出getCurrentPosition()
:
03-29 13:33:59.896: E/AndroidRuntime(1238): FATAL EXCEPTION: main
03-29 13:33:59.896: E/AndroidRuntime(1238): java.lang.IllegalStateException
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.media.MediaPlayer.getCurrentPosition(Native Method)
03-29 13:33:59.896: E/AndroidRuntime(1238): at com.lcboise.lifechurch.PlayMediaActivity.getCurrentPosition(PlayMediaActivity.java:79)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.widget.MediaController.setProgress(MediaController.java:381)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.widget.MediaController.show(MediaController.java:284)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.widget.MediaController.show(MediaController.java:249)
03-29 13:33:59.896: E/AndroidRuntime(1238): at com.lcboise.lifechurch.PlayMediaActivity.onTouchEvent(PlayMediaActivity.java:61)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.app.Activity.dispatchTouchEvent(Activity.java:2099)
03-29 13:33:59.896: E/AndroidRuntime(1238): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.view.ViewRoot.handleMessage(ViewRoot.java:1878)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.os.Handler.dispatchMessage(Handler.java:99)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.os.Looper.loop(Looper.java:130)
03-29 13:33:59.896: E/AndroidRuntime(1238): at android.app.ActivityThread.main(ActivityThread.java:3683)
03-29 13:33:59.896: E/AndroidRuntime(1238): at java.lang.reflect.Method.invokeNative(Native Method)
03-29 13:33:59.896: E/AndroidRuntime(1238): at java.lang.reflect.Method.invoke(Method.java:507)
03-29 13:33:59.896: E/AndroidRuntime(1238): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-29 13:33:59.896: E/AndroidRuntime(1238): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-29 13:33:59.896: E/AndroidRuntime(1238): at dalvik.system.NativeStart.main(Native Method)
任何想法我做错了什么?是否有某些状态我必须在中断时保存,然后在恢复应用程序时恢复?
答案 0 :(得分:0)
以下是一个完整正常的MediaPlayer
和MediaController
示例,可在来电时暂停/恢复音频。如果有人发现错误,请与我们联系。
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Menu;
import android.view.MotionEvent;
import android.widget.MediaController;
import android.widget.TextView;
public class PlayMediaActivity extends Activity implements OnPreparedListener, OnErrorListener, MediaController.MediaPlayerControl{
private static final String TAG = "AudioPlayer";
private MediaPlayer myMediaPlayer;
private MediaController mediaController;
private int seek_position = 0;
private boolean isPaused = false; // If the player was paused before being stopped.
private PhoneStateListener phoneStateListener = null;
ProgressDialog dialog = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_media);
String title = this.getIntent().getStringExtra("Title");
String URL = this.getIntent().getStringExtra("URL");
((TextView)findViewById(R.id.now_playing_text)).setText(title);
// Register for phone events so we can pause/restart audio when a call happens.
phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
//Incoming call: Pause music
boolean s = isPaused;
pause();
isPaused = s; // Want to restore the state before we paused for phone call.
} else if(state == TelephonyManager.CALL_STATE_IDLE) {
//Not in call: Play music
if(isPaused == true) {
pause();
}
else {
if(!isPlaying()) { // Only start if it's not currently started.
start();
}
}
} else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
//A call is dialing, active or on hold. Pause music
boolean s = isPaused;
pause();
isPaused = s; // Want to restore the state before we paused for phone call.
}
super.onCallStateChanged(state, incomingNumber);
}
};
try {
myMediaPlayer = new MediaPlayer();
myMediaPlayer.setOnPreparedListener(PlayMediaActivity.this);
myMediaPlayer.setOnErrorListener(PlayMediaActivity.this);
mediaController = new MediaController(PlayMediaActivity.this);
mediaController.setMediaPlayer(PlayMediaActivity.this);
mediaController.setAnchorView(findViewById(R.id.main_audio_view));
mediaController.setEnabled(true);
// Inform the user that we are doing something (reading from the network).
ContextThemeWrapper cw = new ContextThemeWrapper( PlayMediaActivity.this, R.style.AlertDialogTheme );
dialog = ProgressDialog.show(cw, "", "Loading. Please wait...", true);
myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
myMediaPlayer.setDataSource(URL);
myMediaPlayer.prepareAsync();
}
catch (Exception e)
{
Log.e(TAG, "Could not open file " + title + " for playback.", e);
if(dialog != null) {
dialog.dismiss();
}
ShowDialog("Unable to play audio. Try again later.");
}
}
private void ShowDialog(String message) {
// Alert the user something went wrong.
ContextThemeWrapper cw = new ContextThemeWrapper( PlayMediaActivity.this, R.style.AlertDialogTheme );
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( cw );
alertDialogBuilder.setTitle("Oops!");
// set dialog message
alertDialogBuilder
.setMessage(message)
.setCancelable(true) // Allow back hardkey to dismiss
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, close current activity
dialog.dismiss();
PlayMediaActivity.this.finish();
}
});
alertDialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() { // Catch back key press.
@Override
public void onCancel(DialogInterface dialog) {
//do whatever you want the back key to do
dialog.dismiss();
PlayMediaActivity.this.finish();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
@Override
protected void onStop() { // Activity becomes hidden.
super.onStop();
mediaController.hide(); // So you don't get the "Leaked activity..." message.
if(this.isPaused == true) {
seek_position = myMediaPlayer.getCurrentPosition();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
myMediaPlayer.stop();
myMediaPlayer.release();
myMediaPlayer = null;
// Unregister for phone state information as part of cleanup.
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
}
@Override
protected void onResume() {
super.onResume();
if(this.isPaused == true) { // Restore the playback position if it was paused.
myMediaPlayer.seekTo(seek_position);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//the MediaController will hide after 3 seconds - tap the screen to make it appear again
mediaController.show();
return false;
}
//--MediaPlayerControl methods----------------------------------------------------
public void start() {
myMediaPlayer.start();
this.isPaused = false;
}
public void pause() {
myMediaPlayer.pause();
this.isPaused = true;
}
public int getDuration() {
return myMediaPlayer.getDuration();
}
public int getCurrentPosition() {
return myMediaPlayer.getCurrentPosition();
}
public void seekTo(int i) {
myMediaPlayer.seekTo(i);
}
public boolean isPlaying() {
return myMediaPlayer.isPlaying();
}
public int getBufferPercentage() {
return 0;
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
//--------------------------------------------------------------------------------
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "onPrepared");
if(dialog != null) {
dialog.dismiss();
}
// Show and play the media AFTER it's been prepared.
mediaController.show();
mediaPlayer.start();
// Register for call state information AFTER we have started the media. This registration fires
// the IDLE event, which would try and start the media. This causes a error in the media player
// because we are "prepared" yet.
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
public boolean onError(MediaPlayer mp, int what, int extra) {
if(dialog != null) {
dialog.dismiss();
}
ShowDialog("Unable to play audio. Try again later.");
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_play_media, menu);
return true;
}
}