无法创建文件或目录,返回nullpointerexception

时间:2014-07-22 09:39:18

标签: android nullpointerexception android-mediarecorder mp4parser

我使用mp4parser来附加录制的音频。当我点击暂停或停止按钮时,我收到以下nullpointer异常错误。我希望文件存储在缓存中的外部目录中。不能理解我犯错的地方。

07-22 13:21:18.847: I/RecordActivity(2478):
/data/data/com.example.audiorecordertest/cache/tmprecord
07-22 13:21:24.751: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.755: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.755: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.761: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.761: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.762: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.767: D/isoparser(2478): AbstractBox:mem mapping tkhd
07-22 13:21:24.767: D/isoparser(2478): AbstractBox:parsing details of tkhd
07-22 13:21:24.768: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.768: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.769: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.770: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.770: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.772: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.773: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.773: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.774: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.775: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.775: D/isoparser(2478): AbstractBox:mem mapping hdlr
07-22 13:21:24.775: D/isoparser(2478): AbstractBox:parsing details of hdlr
07-22 13:21:24.776: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.777: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.778: D/isoparser(2478): AbstractBox:mem mapping stts
07-22 13:21:24.778: D/isoparser(2478): AbstractBox:parsing details of stts
07-22 13:21:24.779: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.780: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.780: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.781: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:mem mapping mdhd
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:parsing details of mdhd
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:mem mapping mvhd
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:parsing details of mvhd
07-22 13:21:24.799: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.799: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.800: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.801: W/System.err(2478): java.lang.NullPointerException
07-22 13:21:24.803: W/System.err(2478): at com.googlecode.mp4parser.authoring.
container.mp4.MovieCreator.build(MovieCreator.java:48)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
Mp4ParserWrapper.append(Mp4ParserWrapper.java:72)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
Mp4ParserWrapper.append(Mp4ParserWrapper.java:34)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
RecordActivity.appendToFile(RecordActivity.java:179)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
RecordActivity.access$7(RecordActivity.java:178)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
RecordActivity$2.onClick(RecordActivity.java:108)
07-22 13:21:24.804: W/System.err(2478): at
android.view.View.performClick(View.java:4456)
07-22 13:21:24.804: W/System.err(2478):     at
android.view.View$PerformClick.run(View.java:18465)
07-22 13:21:24.805: W/System.err(2478): at
android.os.Handler.handleCallback(Handler.java:733)
07-22 13:21:24.805: W/System.err(2478): at
android.os.Handler.dispatchMessage(Handler.java:95)
07-22 13:21:24.805: W/System.err(2478): at android.os.Looper.loop(Looper.java:136)
07-22 13:21:24.805: W/System.err(2478): at
android.app.ActivityThread.main(ActivityThread.java:5086)
07-22 13:21:24.806: W/System.err(2478): at 
java.lang.reflect.Method.invokeNative(Native Method)
07-22 13:21:24.806: W/System.err(2478): at
java.lang.reflect.Method.invoke(Method.java:515)
07-22 13:21:24.807: W/System.err(2478): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
07-22 13:21:24.807: W/System.err(2478): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-22 13:21:24.808: W/System.err(2478): at
dalvik.system.NativeStart.main(Native Method)

这是我的代码:

RecordActivity

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

import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;

public class RecordActivity extends ActionBarActivity {

protected static final String TAG = "RecordActivity";
private ImageButton start_btn,pause_btn,stop_btn;
private MediaRecorder myrecorder = null;
Context mcontext;
private String outputFile;
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);

    mTargetRecordFileName = getOutputFile();

    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

              myrecorder.stop();     // stop recording
              myrecorder.reset();    // set state to idle
              myrecorder.release();  // release resources back to the system
              myrecorder = null;
              appendToFile(mTargetRecordFileName, getTemporaryFileName());
              start_btn.setVisibility(View.VISIBLE);
              pause_btn.setVisibility(View.INVISIBLE);
              start_btn.setEnabled(true);
        }
    });
}

private String getOutputFile()
{
    String path = Environment.getExternalStorageDirectory().
getAbsolutePath() +  "/MyFolder/";
    File dir = new File(path);
    if(!dir.exists())
        dir.mkdirs();
    outputFile = path + File.separator + "MA_"+"Srijith".subSequence(0, 3);
    return outputFile;
}

private String getTemporaryFileName() {

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

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

@Override
   protected void onDestroy() {
      super.onDestroy();
      try {
         trimCache(getApplicationContext());
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }

   public static void trimCache(Context context) {
      try {
         File dire = context.getCacheDir();
         if (dire != null && dire.isDirectory()) {
            //deleteDir(dire);
             deleteDir(dire);
         }
      } catch (Exception e) {
         // TODO: handle exception
      }
   }

private static boolean deleteDir(File dire) {
    // TODO Auto-generated method stub
    if (dire != null && dire.isDirectory()) {
         String[] children = dire.list();
         for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dire, children[i]));
            if (!success) {
               return false;
            }
         }
      }

      return dire.delete();
}
}

Mp4ParserWrapper

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.util.List;

import android.util.Log;

import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.FileDataSourceImpl;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;

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);
    } catch(NullPointerException ex){
        ex.printStackTrace();
    }
    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();

}

}

请帮忙。

1 个答案:

答案 0 :(得分:0)

检查以下两行:

final Movie movieA = MovieCreator.build(new FileDataSourceImpl(secondFile));
final Movie movieB = MovieCreator.build(new FileDataSourceImpl(firstFile));

没有行号,因此我无法看到Mp4ParserWrapper类中哪一行是第72行,但是出现错误的地方。如果我理解正确,则变量secondFile已通过getTemporaryFileName()初始化,这看起来非常可疑。难道它不是指向一些电影文件吗?

---根据您的评论进行编辑:

我从未与MovieCreator合作过,但却找不到相关信息,但我猜你是以错误的方式使用append功能。

public static void append(
    final String firstFile,
    final String secondFile,
    final String newFile)

您宣传firstFilesecondFile作为输出。但如果我理解正确,这些实际上应该是输入文件。因此,您应该将firstFile指向一个mp4文件,将secondFile指向另一个mp4文件。 append函数将这两个文件的轨道连接成一个文件。在newFile中,您应该指定要保存此结果新文件的路径。