Android的MediaPlayer的 - 的setDataSource和发布 - IllegalStateException异常 [英] Android MediaPlayer - setDataSource and Release - IllegalStateException
问题描述
我写我自己的MediaPlayer类在一个特定的路径,播放文件,并从资产文件夹播放文件。这里是类:
公共类CMediaPlayer扩展的MediaPlayer {公共无效播放(字符串audioPath){ this.setOnCompletionListener(新OnCompletionListener(){
@覆盖
公共无效onCompletion(MediaPlayer的MP){
mp.release();
}
}); 文件f =新的文件(audioPath);
如果(f.exists()){
尝试{
FIS的FileInputStream =新的FileInputStream(F);
申请的FileDescriptor = fis.getFD();
this.setDataSource(提交);
这prepare(); }赶上(IOException异常五){ }
this.start();
}
} 公共无效播放(AssetFileDescriptor描述符){ this.setOnCompletionListener(新OnCompletionListener(){
@覆盖
公共无效onCompletion(MediaPlayer的MP){
mp.release();
}
});
尝试{
this.setDataSource(descriptor.getFileDescriptor(),descriptor.getStartOffset(),descriptor.getLength());
descriptor.close();
这prepare();
}赶上(IOException异常五){ }
this.start();
}}
我想播放的几种声音从一种活动类。这里是我的code:
公共类琐事延伸活动{\r
\r
//很多变数\r
\r
CMediaPlayer媒体播放器; //声明我的媒体播放器\r
\r
@覆盖\r
公共布尔的onkeydown(INT键code,KeyEvent的事件){\r
如果(键code == KeyEvent.KEY code_BACK){\r
//发布??????\r
意图myIntent =新意图(getBaseContext(),startView.class);\r
startActivity(myIntent);\r
}\r
返回super.onKeyDown(键code,事件);\r
}\r
\r
保护无效的onCreate(捆绑savedInstanceState){\r
super.onCreate(savedInstanceState);\r
的setContentView(R.layout.activity_play_question2);\r
\r
媒体播放器=新CMediaPlayer(); //定义我的媒体播放器\r
\r
//东东\r
}\r
\r
//更多的变数\r
\r
公共无效playQuestion(文件问题){\r
\r
//东东\r
\r
TextView的myTextView =(的TextView)findViewById(R.id.textViewQuestion);\r
//东东\r
myTextView.setOnClickListener(新View.OnClickListener(){\r
@覆盖\r
公共无效的onClick(视图v){\r
mediaPlayer.play(pathSoundQuestion); //点击时播放声音\r
}\r
});\r
\r
//东东\r
\r
myImageView.setOnClickListener(新View.OnClickListener(){\r
@覆盖\r
公共无效的onClick(视图v){\r
mediaPlayer.play(pathSoundQuestion); //点击时播放声音\r
}\r
});\r
\r
//东东\r
mediaPlayer.play(pathSoundQuestion); //播放声音立刻,首先播放的声音(正常工作)\r
\r
// BUTTON1\r
按钮则myButton =(按钮)findViewById(R.id.button1);\r
//东东\r
myButton.setOnClickListener(新Button.OnClickListener(){\r
@覆盖\r
公共无效的onClick(视图v){\r
如果(lastClickedButton == V){\r
//东东\r
返回;\r
}\r
//东东\r
mediaPlayer.play(pathAudio1); //点击时播放声音(错误)\r
}\r
});\r
\r
//按钮2\r
则myButton =(按钮)findViewById(R.id.button2);\r
//东东\r
myButton.setOnClickListener(新Button.OnClickListener(){\r
@覆盖\r
公共无效的onClick(视图v){\r
如果(lastClickedButton == V){\r
//东东\r
返回;\r
}\r
//东东\r
mediaPlayer.play(pathAudio2); //播放声音,同样的问题\r
}\r
});\r
\r
//继续这样一些次...\r
}\r
\r
公共无效登录(视图V,字符串右){\r
//东东\r
\r
如果(right.equals(真)){\r
//东东\r
尝试{\r
。AssetFileDescriptor描述符= getAssets()openFd(右);\r
mediaPlayer.play(描述); //从资产播放声音\r
意图myIntent =新意图(getApplication(),playGame.class);\r
startActivity(myIntent);\r
}赶上(IOException异常五){\r
}\r
}其他{\r
//东东\r
尝试{\r
。AssetFileDescriptor描述符= getAssets()openFd(错误);\r
mediaPlayer.play(描述); //从资产播放声音\r
意图myIntent =新意图(getApplication(),playGame.class);\r
startActivity(myIntent);\r
}赶上(IOException异常五){\r
}\r
}\r
}\r
}
\r
该应用程序扮演我的评论我的code提到的第一个声音。当我点击一个按钮,应该开始另一种声音,我收到以下错误:
03-16 23:07:38.478 13646-13646 / com.example.cello.myownquiz E / AndroidRuntime:致命异常:主要
java.lang.IllegalStateException
在android.media.MediaPlayer.setDataSource(本机方法)
在android.media.MediaPlayer.setDataSource(MediaPlayer.java:1005)
是我的MediaPlayer类好还是我失去了依赖于国家的东西吗?这是同类产品中唯一当场打电话给释放或做我必须把它放在我的活动呢?
是否有人看到我的错误?这个问题与媒体播放器带我尝试了一整天,希望你能帮助我...
改变 mp.release();
到 mp.reset();
公共无效复位()
重置的MediaPlayer其未初始化状态。调用此方法后,你将不得不通过设置数据源,并调用prepare()重新初始化它。
块引用>公共无效发行()
与此MediaPlayer对象相关的释放资源。它被认为是很好的做法,当你正在使用的MediaPlayer进行调用此方法。特别是,当一个应用程序的活动被暂停(它的onPause()方法被调用),或停止(它的onStop()方法被调用),此方法应被调用来释放MediaPlayer对象,除非应用程序有特殊需要保持对象周围。除了不必要的资源(如内存和codeCS的实例)正在举行,不调用此方法,如果立即MediaPlayer对象不再需要,也可能导致持续的电池消耗的移动设备,并且播放失败其他如果应用程序在同一codeC没有多个实例支持的设备上。即使同一codeC的多个实例都支持,当不必要多个实例在同一时间使用的一些性能降级可以预期。
块引用>你需要不断的对象周围。
反正你可以做一个简单的方法
MeddiaPlayer的MediaPlayer =新的MediaPlayer();
mediaPlayer.setDataSource(背景下,铃声);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MEDIA);
媒体播放器prepare()。
mediaPlayer.start();I wrote my own MediaPlayer class to play files at a specific path and to play files from the assets folder. Here is the class:
public class CMediaPlayer extends MediaPlayer{ public void play(String audioPath){ this.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); File f = new File(audioPath); if(f.exists()){ try{ FileInputStream fis = new FileInputStream(f); FileDescriptor fileD = fis.getFD(); this.setDataSource(fileD); this.prepare(); }catch(IOException e){ } this.start(); } } public void play(AssetFileDescriptor descriptor){ this.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); try { this.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength()); descriptor.close(); this.prepare(); }catch (IOException e){ } this.start(); } }
I want to play several sounds with that class from an activity. Here is my code:
public class playGame extends Activity { //a lot of variables CMediaPlayer mediaPlayer; //declare my mediaplayer @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK ) { //release?????? Intent myIntent = new Intent(getBaseContext(), startView.class); startActivity(myIntent); } return super.onKeyDown(keyCode, event); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_play_question2); mediaPlayer = new CMediaPlayer(); //define my mediaplayer //stuff } //more variables public void playQuestion(File question){ //stuff TextView myTextView = (TextView) findViewById(R.id.textViewQuestion); //stuff myTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mediaPlayer.play(pathSoundQuestion); //play sound when clicked } }); //stuff myImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mediaPlayer.play(pathSoundQuestion); //play sound when clicked } }); //stuff mediaPlayer.play(pathSoundQuestion); //plays sound immediatly, first played sound (works fine) //button1 Button myButton = (Button) findViewById(R.id.button1); //stuff myButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { if(lastClickedButton == v){ //stuff return; } //stuff mediaPlayer.play(pathAudio1); //play sound when clicked (error) } }); //button2 myButton = (Button) findViewById(R.id.button2); //stuff myButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { if(lastClickedButton == v){ //stuff return; } //stuff mediaPlayer.play(pathAudio2); //play sound, same problem } }); //goes on like this some more times... } public void logIn(View v, String right){ //stuff if(right.equals("true")){ //stuff try { AssetFileDescriptor descriptor = getAssets().openFd("Right"); mediaPlayer.play(descriptor); //play sound from assets Intent myIntent = new Intent(getApplication(), playGame.class); startActivity(myIntent); }catch (IOException e){ } }else{ //stuff try { AssetFileDescriptor descriptor = getAssets().openFd("Wrong"); mediaPlayer.play(descriptor); //play sound from assets Intent myIntent = new Intent(getApplication(), playGame.class); startActivity(myIntent); }catch (IOException e){ } } } }
The app plays the first sound as mentioned in my comments in my code. When I click a button which should start another sound I get the following error:
03-16 23:07:38.478 13646-13646/com.example.cello.myownquiz E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalStateException at android.media.MediaPlayer.setDataSource(Native Method) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1005)
Is my MediaPlayer class okay or am I missing something depending on the state? Is this class the only spot to call release or do I have to put it somewhere in my activity, too?
Does anybody see my mistake? This problem with the mediaPlayer took me a whole day of trying, hope you can help me...
解决方案change
mp.release();
tomp.reset();
public void reset ()
Resets the MediaPlayer to its uninitialized state. After calling this method, you will have to initialize it again by setting the data source and calling prepare().
public void release ()
Releases resources associated with this MediaPlayer object. It is considered good practice to call this method when you're done using the MediaPlayer. In particular, whenever an Activity of an application is paused (its onPause() method is called), or stopped (its onStop() method is called), this method should be invoked to release the MediaPlayer object, unless the application has a special need to keep the object around. In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a MediaPlayer object is no longer needed may also lead to continuous battery consumption for mobile devices, and playback failure for other applications if no multiple instances of the same codec are supported on a device. Even if multiple instances of the same codec are supported, some performance degradation may be expected when unnecessary multiple instances are used at the same time.
you need to keep the object around.
anyway you can do it in a simple way
MeddiaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(context, ringtone); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MEDIA); mediaPlayer.prepare(); mediaPlayer.start();
这篇关于Android的MediaPlayer的 - 的setDataSource和发布 - IllegalStateException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!