java 在 Android 问题上使用 MediaPlayer 类播放 mp3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7629999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:46:03  来源:igfitidea点击:

play an mp3 with MediaPlayer class on Android issues

javaandroidandroid-mediaplayer

提问by Pabluez

What is wrong with my code? I have a toggle button and i would like to play/stop an mp3. I guess that the code should be as follows:

我的代码有什么问题?我有一个切换按钮,我想播放/停止 mp3。我猜代码应该如下:

package com.android.iFocus;


import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ToggleButton;

public class iFocusActivity extends Activity implements OnClickListener {
    public int count;
    MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.rain);

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ToggleButton toggleRain = (ToggleButton)findViewById(R.id.toggleRain);

        //Define Listeners
        toggleRain.setOnClickListener(this);

        count = 0;


    }


    @Override    
    public void onClick(View toggleRain) {


        if(count==0){

            mediaPlayer.start();
            count=1;
        } else {
            //MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.rain);
                    mediaPlayer.pause();
            mediaPlayer.stop();
                    mediaPlayer.release();
            count=0;
        }

    }

}

the problem is: Eclipse doesn't give any error, but on emulator/phone it gives me an exception and die immediately after started. here goes:

问题是:Eclipse 没有给出任何错误,但在模拟器/电话上它给了我一个异常并在启动后立即死亡。开始:

10-02 20:28:24.312: INFO/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.android.iFocus/.iFocusActivity }
10-02 20:28:24.392: DEBUG/AndroidRuntime(960): Shutting down VM
10-02 20:28:24.402: DEBUG/dalvikvm(960): Debugger has detached; object registry had 1 entries
10-02 20:28:24.462: INFO/ActivityManager(59): Start proc com.android.iFocus for activity com.android.iFocus/.iFocusActivity: pid=967 uid=10036 gids={}
10-02 20:28:24.502: INFO/AndroidRuntime(960): NOTE: attach of thread 'Binder Thread #3' failed
10-02 20:28:25.822: DEBUG/AndroidRuntime(967): Shutting down VM
10-02 20:28:25.822: WARN/dalvikvm(967): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
10-02 20:28:25.932: ERROR/AndroidRuntime(967): FATAL EXCEPTION: main
10-02 20:28:25.932: ERROR/AndroidRuntime(967): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.android.iFocus/com.android.iFocus.iFocusActivity}: java.lang.NullPointerException

Well, when i initialize mediaPlayer inside onClick inner class, it doesn't give me any error and the aplication doesn't give me any error for to start the song. but it does not stop as should. So, when i click on toggleButton, it starts, when i click again, it doesn't do anything but give me an error on log cat:

好吧,当我在 onClick 内部类中初始化 mediaPlayer 时,它不会给我任何错误,并且应用程序不会给我任何启动歌曲的错误。但它并没有像应该的那样停止。因此,当我单击切换按钮时,它会启动,当我再次单击时,它不会执行任何操作,但会在 log cat 上给我一个错误:

Error when first press toggle button and the song starts ok (but give this error):

第一次按下切换按钮并且歌曲正常启动时出错(但出现此错误):

10-02 20:39:02.712: INFO/ActivityManager(59): Start proc com.android.iFocus for activity com.android.iFocus/.iFocusActivity: pid=996 uid=10036 gids={}
10-02 20:39:02.782: INFO/AndroidRuntime(989): NOTE: attach of thread 'Binder Thread #3' failed
10-02 20:39:04.432: INFO/ActivityManager(59): Displayed activity com.android.iFocus/.iFocusActivity: 1804 ms (total 640049 ms)
10-02 20:39:08.672: DEBUG/AudioSink(34): bufferCount (4) is too small and increased to 12
10-02 20:39:08.982: WARN/AudioFlinger(34): write blocked for 73 msecs, 2105 delayed writes, thread 0xb3b8
10-02 20:39:09.682: DEBUG/dalvikvm(437): GC_EXPLICIT freed 686 objects / 38192 bytes in 216ms
10-02 20:39:14.502: WARN/AudioFlinger(34): write blocked for 86 msecs, 2110 delayed writes, thread 0xb3b8
10-02 20:39:14.642: DEBUG/dalvikvm(188): GC_EXPLICIT freed 164 objects / 11408 bytes in 176ms
10-02 20:39:19.622: DEBUG/dalvikvm(261): GC_EXPLICIT freed 43 objects / 1912 bytes in 154ms
10-02 20:39:20.352: WARN/AudioFlinger(34): write blocked for 78 msecs, 2119 delayed writes, thread 0xb3b8

Error when i again press the toggleButton and the song should stop:

当我再次按下切换按钮并且歌曲应该停止时出错:

10-02 20:43:22.412: ERROR/MediaPlayer(1032): pause called in state 8
10-02 20:43:22.412: ERROR/MediaPlayer(1032): error (-38, 0)
10-02 20:43:22.412: ERROR/MediaPlayer(1032): stop called in state 0
10-02 20:43:22.412: ERROR/MediaPlayer(1032): error (-38, 0)
10-02 20:43:22.612: WARN/MediaPlayer(1032): mediaplayer went away with unhandled events
10-02 20:43:22.612: WARN/MediaPlayer(1032): mediaplayer went away with unhandled events
10-02 20:43:22.622: WARN/MediaPlayer(1032): mediaplayer went away with unhandled events
10-02 20:43:22.622: WARN/MediaPlayer(1032): mediaplayer went away with unhandled events

回答by Pete Houston

First thing first, my analysis: 1. You didn't init the MediaPlayer inside onCreate():

首先,我的分析: 1. 你没有在 onCreate() 中初始化 MediaPlayer:

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.rain);

'this' <--- this thing is NULL, so you've got a NullPointerException at Runtime, first loading app timing.
2. On second click to button, you've called

'this' <--- 这东西是 NULL,所以你在运行时有一个 NullPointerException,首先加载应用程序计时。
2. 在第二次单击按钮时,您调用了

mediaPlayer.release();

And next time you click, exception at MediaPlayer State

下次单击时,MediaPlayer 状态异常

Well, the fix is pretty much simple, you need to consider best practice on Android programming:

嗯,修复非常简单,您需要考虑 Android 编程的最佳实践:

package pete.android.study;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ToggleButton;

public class Main extends Activity implements OnClickListener {
        // declare controls
        public int count = 0;
        MediaPlayer mediaPlayer = null;  
        ToggleButton toggleRain = null;
        /*
         * (non-Javadoc)
         * @see android.app.Activity#onCreate(android.os.Bundle)
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            // load layout
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            // load controls
            toggleRain = (ToggleButton)findViewById(R.id.toggleRain);
            // init player
            mediaPlayer = MediaPlayer.create(this, R.raw.rain);
            // set click event handler
            toggleRain.setOnClickListener(this);
            // init state for playing
            count = 0;
        }

        /*
         * (non-Javadoc)
         * @see android.view.View.OnClickListener#onClick(android.view.View)
         */
        @Override    
        public void onClick(View toggleRain) {
            if(count == 0){
                mediaPlayer.start();
                count = 1;
            } else {
                mediaPlayer.pause();                
                count = 0;
            }
        }

        /*
         * (non-Javadoc)
         * @see android.app.Activity#onDestroy()
         */
        @Override
        protected void onDestroy() {
            if(mediaPlayer != null) {
                mediaPlayer.stop();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        }

}

Certainly it works like charm ^^! There are many ways to improve this simple app, however, I guess you can find out by looking over Android Developers' References Documentation :)

当然它像魅力一样有效^^!有很多方法可以改进这个简单的应用程序,但是,我想您可以通过查看 Android 开发人员的参考文档找到:)

回答by ghempton

Have you tried moving the initialization inside of onCreate instead of just inside the class body? This would be the best place to do it.

您是否尝试将初始化移动到 onCreate 内部而不是仅在类主体内部?这将是最好的地方。

If you initialize inside of onClick, the error you show is expected. This is because a new MediaPlayer instance is being created every time you click.

如果您在 onClick 内部进行初始化,则会出现您显示的错误。这是因为每次单击时都会创建一个新的 MediaPlayer 实例。

回答by Kevin Coppock

Your problem is with the release()statement here:

你的问题在于release()这里的声明:

if(count==0){
    mediaPlayer.start();
    count = 1;
} else {
    //MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.rain);
    mediaPlayer.pause();
    mediaPlayer.stop();
    mediaPlayer.release();
    count = 0;
}

There are a few different ways you can change this, depending on your desired result. If you just want to play/pause, as you've said, then you only need to remove the stop()and release()calls. ESPECIALLY release(). That call releases the audio resources back to the system, meaning you'll need to get it back into a prepared state before you can use it again.

有几种不同的方法可以改变它,这取决于你想要的结果。如果您只是想播放/暂停,正如您所说,那么您只需要删除stop()release()调用。特别是release()。该调用将音频资源释放回系统,这意味着您需要将其恢复到准备好的状态,然后才能再次使用它。

I highly recommend reading this reference documentVERY thoroughly. The MediaPlayer class is fairly complex, and it's easy and common for mistakes like this to appear when the states aren't managed properly.

我强烈建议非常彻底地阅读此参考文档。MediaPlayer 类相当复杂,如果状态管理不当,很容易出现这样的错误。