录制音频时无法暂停或停止

时间:2014-07-21 08:36:56

标签: android nullpointerexception mediarecorder mp4parser

这是我的代码:

RecordActivity.java

public class RecordActivity extends ActionBarActivity {

protected static final String TAG = "RecordActivity";
private ImageButton start_btn,pause_btn,stop_btn;
private MediaRecorder myrecorder = null;
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
Context mcontext;
private String mTargetRecordFileName;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_record);
    mcontext = this;
    start_btn = (ImageButton) findViewById(R.id.im_start_btn);
    pause_btn = (ImageButton) findViewById(R.id.im_pause_btn);
    stop_btn = (ImageButton) findViewById(R.id.im_stop_btn);
    stop_btn.setVisibility(View.INVISIBLE);
    pause_btn.setVisibility(View.INVISIBLE);
    start_btn.setEnabled(true);
    start_btn.setOnClickListener(new OnClickListener() {

        @SuppressLint("InlinedApi")
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            start_btn.setVisibility(View.INVISIBLE);
            pause_btn.setVisibility(View.VISIBLE);
            stop_btn.setVisibility(View.VISIBLE);
            start_btn.setEnabled(false);
            pause_btn.setEnabled(true);
            myrecorder = new MediaRecorder();

            myrecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            myrecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            myrecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
            myrecorder.setOutputFile(getTemporaryFileName());
            start(v);

        }

        private void start(View v) {
            // TODO Auto-generated method stub
            try{
            myrecorder.prepare();
            myrecorder.start();
            Log.i(TAG, getTemporaryFileName());
        } catch(IllegalStateException e){

        } catch(IOException e){

        }
        }
    });

    pause_btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            appendToFile(mTargetRecordFileName, getTemporaryFileName());
            myrecorder.stop();
            myrecorder.reset();
            myrecorder.release();
            pause_btn.setVisibility(View.INVISIBLE);
            start_btn.setVisibility(View.VISIBLE);
            stop_btn.setVisibility(View.VISIBLE);
            start_btn.setEnabled(true);
            stop_btn.setEnabled(true);

        }
    });

    stop_btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            appendToFile(mTargetRecordFileName, getTemporaryFileName());
              myrecorder.stop();     // stop recording
              myrecorder.reset();    // set state to idle
              myrecorder.release();  // release resources back to the system
              myrecorder = null;
              start_btn.setVisibility(View.VISIBLE);
              pause_btn.setVisibility(View.INVISIBLE);
              start_btn.setEnabled(true);
        }
    });
}

private String getTemporaryFileName() {

    return mcontext.getCacheDir().getAbsolutePath() + File.separator + "tmprecord";
}



private void appendToFile(final String targetFileName,final String newFileName) {
    Mp4ParserWrapper.append(targetFileName, newFileName);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.record, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

Mp4ParserWrapper.java

public class Mp4ParserWrapper {
public static final int FILE_BUFFER_SIZE = 1024;
private static final String TAG = "Mp4ParserWrapper";

public static boolean append(String mainFileName, String anotherFileName){
    boolean rvalue = false;
    try{
        File targetFile = new File(mainFileName);
        File anotherFile = new File(anotherFileName);
        if (targetFile.exists() && targetFile.length() > 0) {
            String tmpFileName = mainFileName + ".tmp";
            append(mainFileName, anotherFileName, tmpFileName);
            copyFile(tmpFileName, mainFileName);
            rvalue = anotherFile.delete() && new File(tmpFileName).delete();
        } else if (targetFile.createNewFile()) {
            copyFile(anotherFileName, mainFileName);
            rvalue = anotherFile.delete();
    }
    } catch (IOException e) {
        Log.e(TAG,"Append two mp4 files exception", e);
    }
    return rvalue;

}

public static void copyFile(final String from, final String destination)
        throws IOException {
    FileInputStream in = new FileInputStream(from);
    FileOutputStream out = new FileOutputStream(destination);
    copy(in, out);
    in.close();
    out.close();
}

public static void copy(FileInputStream in, FileOutputStream out) throws IOException {
    byte[] buf = new byte[FILE_BUFFER_SIZE];
    int len;
    while ((len = in.read(buf)) != -1) {
        out.write(buf, 0, len);
    }
}

public static void append(
        final String firstFile,
        final String secondFile,
        final String newFile) throws IOException {
    final Movie movieA = MovieCreator.build(new FileDataSourceImpl(secondFile));
    final Movie movieB = MovieCreator.build(new FileDataSourceImpl(firstFile));

    final Movie finalMovie = new Movie();

    final List<Track> movieOneTracks = movieA.getTracks();
    final List<Track> movieTwoTracks = movieB.getTracks();

    for (int i = 0; i < movieOneTracks.size() || i < movieTwoTracks.size(); ++i) {
        finalMovie.addTrack(new
                            AppendTrack(movieTwoTracks.get(i),
                            movieOneTracks.get(i)));
    }

    final Container container = new DefaultMp4Builder().build(finalMovie);

    final FileOutputStream fos = new FileOutputStream(new File(String.format(newFile)));
    final WritableByteChannel bb = Channels.newChannel(fos);
    container.writeContainer(bb);
    fos.close();

}
}

我正在使用 isoparser1.0 RC-27.jar 来合并音频文件。但是我收到了以下错误:

07-21 14:02:15.230: I/RecordActivity(8748): /data/data/com.example.audiorecordertest/cache/tmprecord
07-21 14:02:19.433: D/AndroidRuntime(8748): Shutting down VM
07-21 14:02:19.433: W/dalvikvm(8748): threadid=1: thread exiting with uncaught exception (group=0x41635d40)
07-21 14:02:19.437: E/AndroidRuntime(8748): FATAL EXCEPTION: main
07-21 14:02:19.437: E/AndroidRuntime(8748): Process: com.example.audiorecordertest, PID: 8748
07-21 14:02:19.437: E/AndroidRuntime(8748): java.lang.NullPointerException
07-21 14:02:19.437: E/AndroidRuntime(8748):     at java.io.File.fixSlashes(File.java:185)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at java.io.File.<init>(File.java:134)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at com.example.audiorecordertest.Mp4ParserWrapper.append(Mp4ParserWrapper.java:37)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at com.example.audiorecordertest.RecordActivity.appendToFile(RecordActivity.java:195)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at com.example.audiorecordertest.RecordActivity.access$7(RecordActivity.java:194)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at com.example.audiorecordertest.RecordActivity$2.onClick(RecordActivity.java:98)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at android.view.View.performClick(View.java:4456)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at android.view.View$PerformClick.run(View.java:18465)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at android.os.Handler.handleCallback(Handler.java:733)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at android.os.Handler.dispatchMessage(Handler.java:95)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at android.os.Looper.loop(Looper.java:136)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at android.app.ActivityThread.main(ActivityThread.java:5086)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at java.lang.reflect.Method.invokeNative(Native Method)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at java.lang.reflect.Method.invoke(Method.java:515)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-21 14:02:19.437: E/AndroidRuntime(8748):     at dalvik.system.NativeStart.main(Native Method)

最好知道我使用的容器是什么以及如何将音频文件从容器移动到SD卡。

1 个答案:

答案 0 :(得分:0)

以下行导致问题:

 appendToFile(mTargetRecordFileName, getTemporaryFileName());

您已声明mTargetRecordFileName,但未在任何地方初始化,因此它正在尝试使用null文件名执行文件操作。

以下方法将返回您可以分配给mTargetRecordFileName的根外部存储中的文件的文件名:

private String getOutputFile()
{
    return Environment.getExternalStorageDirectory() + 
        File.separator + "media_file_name.mp4";
}

另外,请确保您在清单中获得以下权限:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />