java - SeekBar 用于录制 30 秒声音 - handlerReceiveCallback 错误

标签 java android handler audio-recording seekbar

我一直在尝试允许用户录制长达 30 秒的声音,并使用 SeekBar 来指示他们到目前为止已经录制了多少时间。我从网上的各种指令中拼凑出了一些代码,但我不断收到 NPE 和“MessageQueue 回调中的异常:handleReceiveCallback”/“异常调度输入事件”错误。我不知道如何解释这一点或我做错了什么。通过日志标签,我可以知道它已到达 StartRecording(),然后在调用 Handler 来跟踪记录长度时抛出异常。任何人都可以看到问题吗?代码如下:

AudioRecorder 类内部:

import java.io.File;
import java.io.IOException;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;


public class AudioRecorder {

    private static final String LOG_TAG = "AudioRecordTest";
    private String fileName = Environment.getExternalStorageDirectory()+"/audio"+System.currentTimeMillis()+".3gp";
    private static MediaRecorder mRecorder;
    private static MediaPlayer   mPlayer;
    public boolean isRecording;
    public boolean isPlaying;
    int recordTime;
    Handler handler;

    public void onRecord(boolean start) {
        if (start) {
            startRecording();
        } else {
            stopRecording();
        }

    }

    public void onPlay(boolean start) {
        if (start) {
            startPlaying();
        } else {
            stopPlaying();
        }

    }

    public void startPlaying() {
        mPlayer = new MediaPlayer();
        try {
            mPlayer.setDataSource(fileName);
            mPlayer.prepare();
            mPlayer.start();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }
        isPlaying = true;
    }

    public void stopPlaying() {
        mPlayer.release();
        mPlayer = null;
        isPlaying = false;
    }

    public void startRecording() {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(fileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recordTime = 0;

        try {
            mRecorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }

        Log.w("LCC", "Start playing made it this far! 1!");

        mRecorder.start();
        isRecording = true;
        handler.post(UpdateRecordTime);
    }

    public void stopRecording() {
        mRecorder.stop();
        mRecorder.reset();
        mRecorder = null;
        isRecording = false;
        handler.removeCallbacks(UpdateRecordTime);
    }

    public void playSound(Context c){
        if (mPlayer == null) {
            Uri uri = Uri.parse(fileName);
            mPlayer = MediaPlayer.create(c, uri);

            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                public void onCompletion(MediaPlayer mp) {
                    stopPlayer();
                }
            });
        }

        mPlayer.start();
    }

    public void stopPlayer() {
        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }

    Runnable UpdateRecordTime = new Runnable(){
         public void run(){
             if(isRecording){ 
                  recordTime++;
                  // Delay 1s before next call      
                  handler.postDelayed(this, 1000);
                }
         }
    };

    public int getCurrentPosition(){
        return recordTime;
    };
}

在 AudioRecorderActivity 类中:

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SeekBar;

public class AudioRecorderActivity extends ActionBarActivity {
    private AudioRecorder mRecorder = new AudioRecorder();
    //private View mPlayButton;
    //private View mStopButton;
    //private View mRecordButton;
    private View mRecordButton;
    private SeekBar mSeekBar;
    private boolean isRecording;


    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //requestWindowFeature(Window.FEATURE_NO_TITLE);
        //getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                       // WindowManager.LayoutParams.FLAG_FULLSCREEN);        
        setContentView(R.layout.activity_record);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);

        mSeekBar = (SeekBar)findViewById(R.id.SeekBar);
        mSeekBar.setMax(30);

        mRecordButton = findViewById(R.id.recordPlayButton);
        mRecordButton.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                switch(event.getAction()){
                 case MotionEvent.ACTION_DOWN:
                     mRecorder.onRecord(true);
                     isRecording = true;

                    final Handler mHandler = new Handler();
                    final Runnable mRunnable = new Runnable() {

                        @Override
                        public void run() {
                            if(mRecorder.isRecording){
                                int mCurrentPosition = mRecorder.getCurrentPosition() / 1000;
                                mSeekBar.setProgress(mCurrentPosition);
                            }
                            mHandler.postDelayed(this, 1000);
                        }
                    };

                     break;
                 case MotionEvent.ACTION_UP:
                     mRecorder.stopRecording();
                     isRecording = false;
                     break;
                }
                return false;
            }
        });

如有任何帮助,我们将不胜感激。谢谢!!

编辑:这是确切的错误(每当我按下录制按钮时就会发生两组)

02-03 17:17:28.189: W/LCC(3757): Start playing made it this far! 1!
02-03 17:17:28.579: E/InputEventReceiver(3757): Exception dispatching input event.
02-03 17:17:28.579: E/MessageQueue-JNI(3757): Exception in MessageQueue callback: handleReceiveCallback
02-03 17:17:28.599: E/MessageQueue-JNI(3757): java.lang.NullPointerException
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.littlecloudcollective.waves.AudioRecorder.startRecording(AudioRecorder.java:80)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.littlecloudcollective.waves.AudioRecorder.onRecord(AudioRecorder.java:28)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.littlecloudcollective.waves.AudioRecorderActivity$1.onTouch(AudioRecorderActivity.java:43)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.View.dispatchTouchEvent(View.java:7229)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2177)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1482)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.app.Activity.dispatchTouchEvent(Activity.java:2469)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:260)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2125)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.View.dispatchPointerEvent(View.java:7414)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3523)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3455)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4565)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4543)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4647)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.os.MessageQueue.nativePollOnce(Native Method)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.os.MessageQueue.next(MessageQueue.java:125)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.os.Looper.loop(Looper.java:124)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at android.app.ActivityThread.main(ActivityThread.java:4963)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at java.lang.reflect.Method.invokeNative(Native Method)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at java.lang.reflect.Method.invoke(Method.java:511)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
02-03 17:17:28.599: E/MessageQueue-JNI(3757):   at dalvik.system.NativeStart.main(Native Method)
02-03 17:17:28.599: D/AndroidRuntime(3757): Shutting down VM
02-03 17:17:28.599: W/dalvikvm(3757): threadid=1: thread exiting with uncaught exception (group=0x41104438)
02-03 17:17:28.609: E/AndroidRuntime(3757): FATAL EXCEPTION: main
02-03 17:17:28.609: E/AndroidRuntime(3757): java.lang.NullPointerException
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.littlecloudcollective.waves.AudioRecorder.startRecording(AudioRecorder.java:80)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.littlecloudcollective.waves.AudioRecorder.onRecord(AudioRecorder.java:28)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.littlecloudcollective.waves.AudioRecorderActivity$1.onTouch(AudioRecorderActivity.java:43)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.View.dispatchTouchEvent(View.java:7229)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2237)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1936)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2177)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1482)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.app.Activity.dispatchTouchEvent(Activity.java:2469)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:260)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2125)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.View.dispatchPointerEvent(View.java:7414)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3523)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3455)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4565)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4543)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4647)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.os.MessageQueue.nativePollOnce(Native Method)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.os.MessageQueue.next(MessageQueue.java:125)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.os.Looper.loop(Looper.java:124)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at android.app.ActivityThread.main(ActivityThread.java:4963)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at java.lang.reflect.Method.invokeNative(Native Method)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at java.lang.reflect.Method.invoke(Method.java:511)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
02-03 17:17:28.609: E/AndroidRuntime(3757):     at dalvik.system.NativeStart.main(Native Method)

最佳答案

您忘记创建 Handler 的新对象。添加

handler=new Handler(); 

AudioRecorder 类就可以了。

此外,我认为您在设置值时犯了另一个错误:

getCurrentPosition() 将返回 0 到 30 之间的值。当您调用 getCurrentPosition()/1000 时,从技术上讲,它不能超过 0,因为 int1/int1+int2 将始终返回 0。Seekbar 的范围为 0 到 100。注释掉 /1000,因此它是

int mCurrentPosition = mRecorder.getCurrentPosition();
                       mSeekBar.setProgress(mCurrentPosition);

你应该没问题。

getCurrentPosition()*10/3 将使搜索栏在录音达到 30 秒标记时到达其末尾。

关于java - SeekBar 用于录制 30 秒声音 - handlerReceiveCallback 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28291533/

相关文章:

javascript - 将参数传递给调用的事件处理程序,即 element.onchange(); javascript

java - Java 中的 Hibernate DetachedCriteria 多个结果

java - 有什么办法可以优化 Map of List 吗?

java - Spring MVC 测试 - 在集成测试需要特定类型时注入(inject)模拟存储库

android - 当最小值和最大值相同时如何设置数字选择器值?

c# - C# WinForms 应用程序中的应用程序范围的消息处理程序

java - setOnItemSelectedListener 上下文

java - 如何使用按钮启动和停止旋转 ImageView 的动画

android - 第二次从相机捕获时无法加载图像

Android在进度条加载完成后隐藏标题栏