Media Player在状态0中调用,错误(-38,0)
我目前正试图devise一个简单的应用程序,stream式无线电台。 我有站的URL,并设置像媒体播放器
MediaPlayer mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(URL); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { mediaPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.start();
该程序模拟不崩溃,但没有播放,我得到以下错误:
start called in state 0
和正确的下面是
Error (-38,0)
有谁知道这是什么意思?
我已经读了一些有关这些状态错误,但找不到适用于我的项目的任何东西。
您需要使用侦听器在onPrepared
方法中调用mediaPlayer.start()
。 你得到这个错误是因为你在调用mediaPlayer.start()
之前已经达到了预备状态。
这里是你如何做到这一点:
mp.setDataSource(url); mp.setOnPreparedListener(this); mp.prepareAsync(); public void onPrepared(MediaPlayer player) { player.start(); }
看起来像Error -38意味着一个状态exception(如错误信息所示)。 例如,如果您调用了start()
,在歌曲准备就绪之前,或者当您调用pause()
,即使歌曲根本不播放。
要解决此问题,请在调用方法之前检查mediaPlayer的状态。 例如:
if(mediaPlayer.isPlaying()) { mediaPlayer.pause(); }
此外,MediaPlayer正在发送事件消息。 即使你不需要准备好的事件(尽pipe在这个事件被触发前最好不要开始播放),你必须设置一个callback监听器。 这也适用于OnErrorListener
, OnCompletionListener
, OnPreparedListener
和OnSeekCompletedListener
(如果您调用seek方法)。
听众可以简单地通过
mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { // Do something. For example: playButton.setEnabled(true); } });
这是我的代码,testing和工作正常:
package com.example.com.mak.mediaplayer; import android.media.MediaPlayer; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.app.Activity; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final MediaPlayer mpp = MediaPlayer.create(this, R.raw.red); //mp3 file in res/raw folder Button btnplay = (Button) findViewById(R.id.btnplay); //Play btnplay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View vone) { mpp.start(); } }); Button btnpause = (Button) findViewById(R.id.btnpause); //Pause btnpause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View vtwo) { if (mpp.isPlaying()) { mpp.pause(); mpp.seekTo(0); } } }); } }
当我尝试获取媒体播放器的当前位置(MediaPlayer.getCurrentPosition())时,出现此错误。 我通过跟踪它的状态来解决这个问题,在调用onPreparedListener之后只调用getCurrentPosition()方法。
有时候文件是以Android无法解码的方式进行编码的。 甚至一些MP4文件不能播放。 请尝试不同的文件格式(大部分时间播放.3gp)并查看..
我在代码下面testing。 工作正常
public class test extends Activity implements OnErrorListener, OnPreparedListener { private MediaPlayer player; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); player = new MediaPlayer(); player.setAudioStreamType(AudioManager.STREAM_MUSIC); try { player.setDataSource("web_sound/BachGavotte.mp3"); player.setOnErrorListener(this); player.setOnPreparedListener(this); player.prepareAsync(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); player.release(); player = null; } @Override public void onPrepared(MediaPlayer play) { play.start(); } @Override public boolean onError(MediaPlayer arg0, int arg1, int arg2) { return false; } }
前几天我遇到了同样的问题。 我的audio媒体播放器在高处理能力的设备上工作良好,但对于速度慢的设备,媒体播放器只是没有玩一段时间,而从LogCat中有很多抱怨被称为错误的状态。 所以我通过在OnPreparedListener()的 onPrepared()方法中调用start() , pause() ,…来调用它,如下所示:
mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { ........ mediaPlayer.start(); .... songControlBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } else { mediaPlayer.start(); } } }); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { ............ } }); } });
也尝试发布任何你不需要的媒体播放器。 例如,如果您不想在后台播放audio或video,则应该在onPause()中调用mediaPlayer.release () 。
我解决了这两个错误(-19,0)和(-38,0),通过每次创buildMediaPlayer的一个新的对象之前播放和释放它。
之前:
void play(int resourceID) { if (getActivity() != null) { //Using the same object - Problem persists player = MediaPlayer.create(getActivity(), resourceID); player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { player.release(); } }); player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); }
}
后:
void play(int resourceID) { if (getActivity() != null) { //Problem Solved //Creating new MediaPlayer object every time and releasing it after completion final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID); player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { player.release(); } }); player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); }
}
您在日志中收到此消息,因为您在MediaPlayer实例的当前状态中执行了一些不允许的操作。
因此,你应该总是注册一个error handling程序来捕获这些东西(如@tidbeckbuild议)。
起初,我build议你看一下MediaPlayer
类的文档,并理解它的含义。 请参阅: http : //developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram
这里的错误可能是常见的错误之一,其他人写在这里,但总的来说,我会看看哪些方法是有效的,以什么状态调用的文档: http : //developer.android.com/参考/安卓/媒体/ MediaPlayer.html#Valid_and_Invalid_States
在我的例子中, mediaPlayer.CurrentPosition
是媒体播放器处于不允许调用该属性的状态下调用的方法。
我也有这个错误,我尝试了onPreparedListener但仍然有这个错误。 最后,我得到的解决scheme,错误是我的错,因为我忘了在Android Manifest XML的互联网许可。 🙂
<uses-permission android:name="android.permission.INTERNET" />
我使用mediaplayer的示例代码。 我在StreamService.java中使用
onCreate方法
String url = "http://s17.myradiostream.com:11474/"; mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(url); mediaPlayer.prepare();
if(length>0) { mediaPlayer = new MediaPlayer(); Log.d("length",""+length); try { mediaPlayer.setDataSource(getApplication(),Uri.parse(uri)); } catch(IOException e) { e.printStackTrace(); } mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.seekTo(length); mediaPlayer.start(); } }); mediaPlayer.prepareAsync();
这是每一个沮丧。 所以,我得到了适合我的解决scheme。
try { if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(file.getAbsolutePath()); mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.start(); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } }); } }); mediaPlayer.prepare(); } catch (Exception e) { e.printStackTrace(); }
我刚才遇到了同样的问题,一楼的朋友是对的,你在错误的时间调用了start()
,你应该用这个方法mediaPlayer.setOnPreparedListener(this)
为prepare()或prepareSync()
设置一个监听器。 ; 在准备之前,在这个callback中调用start()
它可能会解决你的问题。 我已经尝试过了。
mp = new MediaPlayer(); AssetFileDescriptor afd = mContext.getAssets().openFd(fileName); mp.reset(); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mp.prepare(); mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { mp.start(); } }); mp.prepareAsync();