我在audioTales服务中使用了mediaPlayer。我第一次按startService - 它很棒。但如果我将停止服务而不是启动egain - MediaPlayer.reset中存在IllegalStateException 在我的情况下,我在.release()之前调用.reset(),所以这不是崩溃的原因......
我是android开发的新手,所以请不要非常严格......)
这里是catlog:
03-07 21:54:40.521 18845-18845/ua.andriyantonov.tales E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to create service ua.andriyantonov.tales.TalePlay_Service: java.lang.IllegalStateException
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2377)
at android.app.ActivityThread.access$1600(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1281)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4744)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException
at android.media.MediaPlayer._reset(Native Method)
at android.media.MediaPlayer.reset(MediaPlayer.java:1331)
at ua.andriyantonov.tales.TalePlay_Service.onCreate(TalePlay_Service.java:69)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2367)
at android.app.ActivityThread.access$1600(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1281)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4744)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
这是Service.class:
@Override
public void onCreate(){
bufferIntent = new Intent(BROADCAST_BUFFER);
seekIntent = new Intent(BROADCAST_ACTION);
aDialogIntent = new Intent(BROADCAST_ADIALOG);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnErrorListener(this);
mPlayer.setOnBufferingUpdateListener(this);
mPlayer.setOnSeekCompleteListener(this);
mPlayer.setOnInfoListener(this);
mPlayer.reset();
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
/**set up receiver for seekBar change and PlayResume btns*/
getApplication().registerReceiver(seekBarChangedBroadcastReceiver,
new IntentFilter(TaleActivity_Audio.BROADCAST_SEEKBAR));
LocalBroadcastManager.getInstance(getApplication()).registerReceiver(switchPlayPauseBroadcastReceiver,
new IntentFilter(TaleActivity_Audio.BROADCAST_switchPlayStatus));
initNotification();
/** Manage incomingphone calls during playback
* public static final String BROADCAST_BUFFER = "ua.andriyantonov.tales.broadcastbuffer";
e mp on incoming
* Resume on hangup */
telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
/** register the listener with telephony manager */
phoneStateListener = new PhoneStateListener(){
@Override
public void onCallStateChanged(int state,String incomingNumber){
switch (state){
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
case TelephonyManager.CALL_STATE_RINGING:
if (mPlayer!=null){
pauseTaleAudio();
isPausedInCall=true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
/** need to make alertDialog and ask "do you want to resume?" */
if (mPlayer!=null){
if (isPausedInCall){
isPausedInCall=false;
pauseTaleAudio();
sendAfterCallADialogBroadcast();
}
}
break;
}
}
};
telephonyManager.listen(phoneStateListener,PhoneStateListener.LISTEN_CALL_STATE);
/**check if the tale was already downloaded and mp3 file existed
* if it was - use mp3 from storage
* if not - upload from cloudService*/
UpdateTalesData.loadTalesData(getApplicationContext());
talePosition=UpdateTalesData.talePosition;
if (UpdateTalesData.checkTaleExist.exists()){
dataSource= Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+
getResources().getString(R.string.app_name)+"/"+
getResources().getString(R.string.mainAudioTale_name)+talePosition+".mp3";
} else {
dataSource=UpdateTalesData.data_HTTP;
}
/** set data source for player and get prepared*/
if (!mPlayer.isPlaying()){
try {
mPlayer.setDataSource(dataSource);
/** send message to activity to progress uploading dialog*/
mPlayer.prepareAsync();
}catch (IllegalArgumentException e){
e.printStackTrace();
}catch (IllegalStateException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
/** show buffering progress bar if playing online*/
if (!UpdateTalesData.checkTaleExist.exists()){
sendBufferingBroadcast();
}
/** set up seekbar handler*/
setupHandler();
return START_NOT_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
if (mPlayer!=null){
if (mPlayer.isPlaying()){
mPlayer.stop();
}
mPlayer.release();
}
stopSelf();
if (phoneStateListener!=null){
telephonyManager.listen(phoneStateListener,PhoneStateListener.LISTEN_NONE);
}
handler.removeCallbacks(sendUpdatesToUI);
cancelNotification();
getApplication().unregisterReceiver(seekBarChangedBroadcastReceiver);
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(switchPlayPauseBroadcastReceiver);
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) { }
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch (what){
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Toast.makeText(this,"MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK" +extra,
Toast.LENGTH_SHORT).show();
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Toast.makeText(this,"MEDIA_ERROR_SERVER_DIED" +extra,
Toast.LENGTH_SHORT).show();
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Toast.makeText(this,"MEDIA_ERROR_UNKNOWN" +extra,
Toast.LENGTH_SHORT).show();
break;
}
return false;
}
@Override
public void onPrepared(MediaPlayer mp) {
sendBufferCompleteBroadcast();
playTaleAudio();
}
public void playTaleAudio(){
if (!mPlayer.isPlaying()){
mPlayer.start();
}
}
public void pauseTaleAudio(){
if (mPlayer.isPlaying()){
mPlayer.pause();
}
}
private void setupHandler(){
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 0);
}
private Runnable sendUpdatesToUI = new Runnable() {
@Override
public void run() {
LogTaleAudioPosition();
handler.postDelayed(this,1000);
}
};
private void LogTaleAudioPosition(){
if(mPlayer.isPlaying()){
taleAudioPosition = mPlayer.getCurrentPosition();
taleAudioMaxDuration = mPlayer.getDuration();
seekIntent.putExtra("counter",String.valueOf(taleAudioPosition));
seekIntent.putExtra("audioMax",String .valueOf(taleAudioMaxDuration));
seekIntent.putExtra("song_ended",String .valueOf(audioTaleEnded));
String maxDurationText = convertFormat(taleAudioMaxDuration);
seekIntent.putExtra("audioMaxText",maxDurationText);
String currTimePosText = convertFormat(taleAudioPosition);
seekIntent.putExtra("currTimePosText",currTimePosText);
sendBroadcast(seekIntent);
}
}
public String convertFormat(long miliSeconds){
long s = TimeUnit.MILLISECONDS.toSeconds(miliSeconds)%60;
long m = TimeUnit.MILLISECONDS.toMinutes(miliSeconds)%60;
return String .format("%02d:%02d",m,s);
}
/** receive player position (play or pause) if it has been changed by the user in fragment*/
private BroadcastReceiver switchPlayPauseBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switchPlayPause(intent);
}
};
public void switchPlayPause(Intent intent){
switchPlayStatus = intent.getIntExtra("switchPlayStatus",-1);
if (switchPlayStatus==1){
pauseTaleAudio();
} else if (switchPlayStatus==2){
playTaleAudio();
}
}
/** receive seekbar position if it has been changed by the user in fragment*/
private BroadcastReceiver seekBarChangedBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateSeekBarPosition(intent);
}
};
public void updateSeekBarPosition(Intent intent){
int seekPos = intent.getIntExtra("seekPos",0);
if(mPlayer.isPlaying()){
handler.removeCallbacks(sendUpdatesToUI);
mPlayer.seekTo(seekPos);
setupHandler();
}
}
/** send message to activity that audio is being prepared and buffering started*/
public void sendBufferingBroadcast(){
bufferIntent.putExtra("buffering","1");
sendBroadcast(bufferIntent);
}
/** send message to activity that audio is prepared and ready to start playing*/
public void sendBufferCompleteBroadcast(){
bufferIntent.putExtra("buffering","0");
sendBroadcast(bufferIntent);
}
/** send message to activity that audio is prepared and ready to start playing*/
public void sendAfterCallADialogBroadcast(){
aDialogIntent.putExtra("aDialogIntent","1");
sendBroadcast(aDialogIntent);
}
@Override
public void onCompletion(MediaPlayer mp) {
stopSelf();
audioTaleEnded=1;
seekIntent.putExtra("song_ended",String .valueOf(audioTaleEnded));
sendBroadcast(seekIntent);
UpdateTalesData.saveTalesIntData(context,"isPlaying",UpdateTalesData.isPlaying=0);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onSeekComplete(MediaPlayer mp) {
if (!mPlayer.isPlaying()){
playTaleAudio();
}
}
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
private void initNotification(){
CharSequence tikerText = getResources().getString(R.string.tickerText);
NotificationManager mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher,tikerText,System.currentTimeMillis());
Context context = getApplicationContext();
CharSequence contentTitle = getResources().getString(R.string.contentTitle);
CharSequence contentText = UpdateTalesData.taleName;
Intent notifIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
notifIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notifIntent.putExtra("showAudioFrag",true);
PendingIntent contentIntent = PendingIntent.getActivity(context,0,notifIntent,PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context,contentTitle,contentText,contentIntent);
Log.d("", "" + notifIntent.getExtras());
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
private void cancelNotification(){
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);
}
}
答案 0 :(得分:7)
在我的情况下,解决方案是下一个:
mPlayer.reset();
; onCreate
onDestroy()
中将mPlayer.release();
更改为mPlayer.reset();
之后我没有IllegalStateException。
我希望我的案例和解决方案可以帮助某人)