使用Ringtone类的MediaPlayer.setDataSource中的java.lang.IllegalStateException [英] java.lang.IllegalStateException in MediaPlayer.setDataSource, using Ringtone class

查看:567
本文介绍了使用Ringtone类的MediaPlayer.setDataSource中的java.lang.IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用户(三星Galaxy S5,Android 4.4)报告了一次崩溃,我不知道发生了什么.似乎不太可能,但也许有些人遇到了相同或相似的问题.

I had a crash reported by an user (Samsung Galaxy S5, Android 4.4) and I do not understand what is happening. It seems imporbable but maybe some people have encountered the same problem, or similar.

这是痕迹:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.IllegalStateException
at android.media.MediaPlayer._setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1383)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1367)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1302)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1240)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:986)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:951)
at android.media.Ringtone.setUri(Ringtone.java:219)
at android.media.Ringtone.setStreamType(Ringtone.java:89)
at com.aasfet.clocklight.WakeActivity$RingAsyncTask.doInBackground(WakeActivity.java:510)
at com.aasfet.clocklight.WakeActivity$RingAsyncTask.doInBackground(WakeActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 3 more

这是我的代码中出现错误的部分:

Here is the part of my code that is in the error:

private class RingAsyncTask extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected Integer doInBackground(Integer... params) {
            int previousVolume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
            int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
            int newVolume = (int)(volume * (float)maxVolume);
            if(newVolume < 1){
                newVolume = 1;
            }
            if(progressive){
                audioManager.setStreamVolume(AudioManager.STREAM_ALARM, 1, 0);
            }else{
                audioManager.setStreamVolume(AudioManager.STREAM_ALARM, newVolume, 0);
            }
            getRingtone().setStreamType(AudioManager.STREAM_ALARM);
            getRingtone().play();
...

getRingtone()是我的函数之一,它返回通过活动的onResume中的RingtoneManager光标获得的Ringtone对象,我认为那里没有任何问题.

getRingtone() is one of my functions and returns a Ringtone object that was obtained with a RingtoneManager cursor in the activity's onResume, I do not think there is any problem there.

在Android源代码中,Ringtone.setStreamType调用Ringtone.setURI.这是setURI:

In the Android source, Ringtone.setStreamType calls Ringtone.setURI. Here is setURI:

 public void setUri(Uri uri) {
168        destroyLocalPlayer();
169
170        mUri = uri;
171        if (mUri == null) {
172            return;
173        }
174
175        // TODO: detect READ_EXTERNAL and specific content provider case, instead of relying on throwing
176
177        // try opening uri locally before delegating to remote player
178        mLocalPlayer = new MediaPlayer();
179        try {
180            mLocalPlayer.setDataSource(mContext, mUri);
181            mLocalPlayer.setAudioStreamType(mStreamType);
182            mLocalPlayer.prepare();
...

因此,setURI创建一个新的MediaPlayer,然后在MediaPlayer上调用setDataSource. android文档告诉我们,使用new MediaPlayer()会将其设置为空闲"状态,而空闲"状态是调用setDataSource的正确状态. 我真的不明白怎么发生,显然是千分之一的错误.我无法联系有错误的用户,也从未在自己的终端上重现过该错误,因此我发现自己被封锁了. 我正在考虑捕获我的代码中的错误,并在发生错误时,尝试使用Ringtone.setStreamType再次尝试,并假设该错误是由于系统的瞬态状态"而发生的,该状态可能在几毫秒后发生了变化.简而言之,我很绝望:)

So, setURI creates a new MediaPlayer, then calls setDataSource on the MediaPlayer. The android doc tells us that using new MediaPlayer() sets it in "idle" state, and that "idle" state is the correct state for calling setDataSource. I really do no understand how, apparently one time in a thousand, I get this error. I cannot contact the user who had the error, never reproduced it on my end, so I find myself blocked. I'm thinking of catching the error in my code and when it happens, try again with my Ringtone.setStreamType, on the assumption that it happens because of a transient "state" of the system that may have changed a few milliseconds later. In short I am quite desperate :)

任何帮助或类似经验将不胜感激:)

Any help or similar experiences would be appreciated :)

推荐答案

就我而言,我必须在MediaPlayer实例上调用reset(),然后再为其提供不同的URL.

In my case, i had to call reset() on the MediaPlayer instance, before i supplied it with a different url.

文档而言,setDataSource仅在IDLE状态下有效.

As far as the documentation goes, setDataSource is only valid in IDLE state.

您还可以访问此答案,使用非常漂亮的解释图表.

You can also visit this answer , explained very nicely using diagram.

这篇关于使用Ringtone类的MediaPlayer.setDataSource中的java.lang.IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆