当前位置: 动力学知识库 > 问答 > 编程问答 >

java - SeekBar for recording 30 second sound - handleReceiveCallback error

问题描述:

I've been trying to allow users to record sounds that are up to 30 seconds long, and using a SeekBar to indicate how much they've recorded so far. I've got some code I pieced together from a variety of instructions online, but I keep getting an NPE and "Exception in MessageQueue callback: handleReceiveCallback"/"Exception dispatching input event" error. I'm not sure how to interpret this or what I'm doing wrong. Through log tags, I can tell that it gets as far as StartRecording() and then throws an exception when the Handler is called to track the recording length. Can anyone see the problem? Code below:

Inside AudioRecorder class:

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;

};

}

And inside AudioRecorderActivity class:

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;

}

});

Any help would be appreciated. Thank you!!

Edit: here is the exact error (there are two sets that occur whenever I press the record button)

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)

网友答案:

You forgot to create a new object of the Handler. Add

handler=new Handler(); 

to the AudioRecorder class and you'll be fine.

Also, I think you made another mistake concerning setting the value:

getCurrentPosition() will return a value between 0 and 30. When you call getCurrentPosition()/1000 it technically can't go above 0, as int1/int1+int2 will always return 0. Seekbar takes a range from 0 to 100. Comment out the /1000 so it is

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

and you should be fine.

getCurrentPosition()*10/3 will make the Seekbar reach its end when the recording hits the 30 sec mark.

分享给朋友:
您可能感兴趣的文章:
随机阅读: