java.io.FileNotFoundException 将音频文件保存到特定文件夹时

java.io.FileNotFoundException when saving audio file to specific folder

我已经在这个问题上工作了一天了。以下是我的代码和我得到的错误日志。这是一个代码,只要按下按钮就可以从用户那里获取音频,并在停止时将文件保存到特定文件夹。此代码不适用于模拟器以及 phone。请帮忙。

hare 是 link 我的项目文件以获得进一步的帮助:https://drive.google.com/open?id=0B-Ubzr_X9p-rfkx0VjFtdWNZS1BDenZlZm9BZGNWQzdIOFMxZGtJZnBkSUhnbWwzanBUaWc&authuser=0

请记住,它还没有完成。我目前正在处理添加关系位,这就是问题所在。

提前致谢

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

 public class RelationAudio extends Activity {

    Button b1;
    Button b2;
    private String rType;
    private String rName;
    private String rPath;

    private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
    private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
    //private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
    private MediaRecorder recorder = null;
    private int currentFormat = 1;
    EditText et;
    Bundle extras;
    private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4, MediaRecorder.OutputFormat.THREE_GPP };
    private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4, AUDIO_RECORDER_FILE_EXT_3GP }; 
/** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.audio_relation);
        extras = getIntent().getExtras();
        if (extras != null) {
            rType = extras.getString("type");
            rPath = extras.getString("path");
        }
      b1=(Button)findViewById(R.id.button1);
      b2=(Button)findViewById(R.id.forward);
      et=(EditText)findViewById(R.id.editText1);
      b1.setOnTouchListener(new View.OnTouchListener() {

        @SuppressLint("ClickableViewAccessibility") @Override
        public boolean onTouch(View v, MotionEvent event) {
         // TODO Auto-generated method stub
         rName = et.getText().toString();
         switch(event.getAction()){
          case MotionEvent.ACTION_DOWN:
              AppLog.logString("Start Recording");
              startRecording();
              break;
          case MotionEvent.ACTION_UP:
              AppLog.logString("stop Recording");
              stopRecording();
              break;
         }

         save(BitmapFactory.decodeFile(rPath));

         return false;
     }
 });
 //Save pic with audio with same name in respective folder. 
// b2.setOnClickListener(new OnClickListener() {
//  
//  @Override
//  public void onClick(View v) {
//      // TODO Auto-generated method stub
//      
//  }
//});

}


@SuppressLint("SdCardPath") private String getFilename(){
     String filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/Family/"+rType+"/";
     String nameFormat=rName+ file_exts[currentFormat];


     File file = new File(filepath);
     System.out.println(file.getAbsolutePath());
     if(!file.exists()){


         System.out.println(file.getAbsolutePath());
         file.mkdirs();
     }
     System.out.println(file.getAbsolutePath()+nameFormat);
     return (file.getAbsolutePath()+"/"+nameFormat);
}
      private void startRecording(){
         recorder = new MediaRecorder();
         recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
         recorder.setOutputFormat(output_formats[currentFormat]);
         recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
         recorder.setOutputFile(getFilename());
         recorder.setOnErrorListener(errorListener);
         recorder.setOnInfoListener(infoListener);

         try {
             recorder.prepare();
             recorder.start();
         } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
             e.printStackTrace();
         } catch (IOException e) {
            // TODO Auto-generated catch block
             e.printStackTrace();
         }
    }
      @SuppressLint("SdCardPath") public void save(Bitmap bitM)
      {
        String fileName=rName;
        File direct = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() + "/Family/"+rType);

          if (!direct.exists()) {
              direct = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() +"/Family/"+rType);
              direct.mkdirs();
          }

          File file = new File(new File(Environment.getExternalStorageDirectory().getAbsoluteFile() + "/Family/"+rType), fileName);
          if (file.exists()) {
              file.delete();
          }
          try {
              FileOutputStream out = new FileOutputStream(file);
              bitM.compress(Bitmap.CompressFormat.PNG, 100, out);
              out.flush();
              out.close();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
 private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
        @Override
         public void onError(MediaRecorder mr, int what, int extra) {
             AppLog.logString("Error: " + what + ", " + extra);
     }
};

private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
     @Override
     public void onInfo(MediaRecorder mr, int what, int extra) {
             AppLog.logString("Warning: " + what + ", " + extra);
     }
};
     private void stopRecording(){
       if(null != recorder){
         recorder.stop();
         recorder.reset();
         recorder.release();

         recorder = null;
 }
}

}

xml 文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

     <ImageView
        android:id="@+id/imageView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/pinkbg" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="RECORDER" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="16dp"
        android:layout_marginRight="16dp"
        android:src="@drawable/arrow_right" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="62dp"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/imageView1"
        android:layout_below="@+id/editText1"
        android:layout_marginTop="38dp"
        android:text="Button" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/button1"
        android:layout_marginLeft="79dp"
        android:layout_marginTop="66dp"
        android:src="@drawable/cam1" />

</RelativeLayout>

错误日志

02-12 02:07:18.189: I/System.out(2261): /storage/sdcard/Family/Brother
02-12 02:07:21.699: I/System.out(2261): /storage/sdcard/Family/Brotherjay.3gp
02-12 02:07:42.809: W/System.err(2261): java.io.FileNotFoundException: /storage/sdcard/Family/Brother/jay.3gp: open failed: EACCES (Permission denied)
02-12 02:07:42.819: W/System.err(2261):     at libcore.io.IoBridge.open(IoBridge.java:409)
02-12 02:07:42.819: W/System.err(2261):     at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
02-12 02:07:42.829: W/System.err(2261):     at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
02-12 02:07:42.829: W/System.err(2261):     at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
02-12 02:07:42.839: W/System.err(2261):     at android.media.MediaRecorder.prepare(MediaRecorder.java:691)
02-12 02:07:42.839: W/System.err(2261):     at com.app.family.RelationAudio.startRecording(RelationAudio.java:112)
02-12 02:07:42.849: W/System.err(2261):     at com.app.family.RelationAudio.access(RelationAudio.java:102)
02-12 02:07:42.849: W/System.err(2261):     at com.app.family.RelationAudio.onTouch(RelationAudio.java:60)
02-12 02:07:42.859: W/System.err(2261):     at android.view.View.dispatchTouchEvent(View.java:7701)
02-12 02:07:42.859: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:42.869: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:42.869: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:42.879: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:42.879: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:42.889: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:42.889: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:42.899: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:42.899: W/System.err(2261):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
02-12 02:07:42.909: W/System.err(2261):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
02-12 02:07:42.909: W/System.err(2261):     at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
02-12 02:07:42.919: W/System.err(2261):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
02-12 02:07:42.919: W/System.err(2261):     at android.view.View.dispatchPointerEvent(View.java:7886)
02-12 02:07:42.919: W/System.err(2261):     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3954)
02-12 02:07:42.939: W/System.err(2261):     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3833)
02-12 02:07:42.939: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
02-12 02:07:42.949: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
02-12 02:07:42.949: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
02-12 02:07:42.959: W/System.err(2261):     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3525)
02-12 02:07:42.959: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
02-12 02:07:42.969: W/System.err(2261):     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3582)
02-12 02:07:42.969: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
02-12 02:07:42.979: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
02-12 02:07:42.979: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
02-12 02:07:42.989: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
02-12 02:07:42.989: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
02-12 02:07:42.999: W/System.err(2261):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5602)
02-12 02:07:42.999: W/System.err(2261):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5582)
02-12 02:07:43.009: W/System.err(2261):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5553)
02-12 02:07:43.009: W/System.err(2261):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5682)
02-12 02:07:43.019: W/System.err(2261):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
02-12 02:07:43.019: W/System.err(2261):     at android.os.MessageQueue.nativePollOnce(Native Method)
02-12 02:07:43.029: W/System.err(2261):     at android.os.MessageQueue.next(MessageQueue.java:138)
02-12 02:07:43.039: W/System.err(2261):     at android.os.Looper.loop(Looper.java:123)
02-12 02:07:43.039: W/System.err(2261):     at android.app.ActivityThread.main(ActivityThread.java:5017)
02-12 02:07:43.049: W/System.err(2261):     at java.lang.reflect.Method.invokeNative(Native Method)
02-12 02:07:43.049: W/System.err(2261):     at java.lang.reflect.Method.invoke(Method.java:515)
02-12 02:07:43.059: W/System.err(2261):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-12 02:07:43.059: W/System.err(2261):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-12 02:07:43.069: W/System.err(2261):     at dalvik.system.NativeStart.main(Native Method)
02-12 02:07:43.069: W/System.err(2261): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
02-12 02:07:43.099: W/System.err(2261):     at libcore.io.Posix.open(Native Method)
02-12 02:07:43.109: W/System.err(2261):     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
02-12 02:07:43.109: W/System.err(2261):     at libcore.io.IoBridge.open(IoBridge.java:393)
02-12 02:07:43.119: W/System.err(2261):     ... 48 more
02-12 02:07:46.689: D/dalvikvm(2261): GC_FOR_ALLOC freed 325K, 4% free 11618K/12012K, paused 40ms, total 49ms
02-12 02:07:46.799: W/System.err(2261): java.io.FileNotFoundException: /storage/sdcard/Family/Brother/jay: open failed: EACCES (Permission denied)
02-12 02:07:46.809: W/System.err(2261):     at libcore.io.IoBridge.open(IoBridge.java:409)
02-12 02:07:46.819: W/System.err(2261):     at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
02-12 02:07:46.819: W/System.err(2261):     at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
02-12 02:07:46.819: W/System.err(2261):     at com.app.family.RelationAudio.save(RelationAudio.java:137)
02-12 02:07:46.829: W/System.err(2261):     at com.app.family.RelationAudio.onTouch(RelationAudio.java:68)
02-12 02:07:46.829: W/System.err(2261):     at android.view.View.dispatchTouchEvent(View.java:7701)
02-12 02:07:46.829: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:46.849: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:46.849: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:46.859: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:46.859: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:46.869: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:46.869: W/System.err(2261):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
02-12 02:07:46.879: W/System.err(2261):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
02-12 02:07:46.889: W/System.err(2261):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
02-12 02:07:46.889: W/System.err(2261):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
02-12 02:07:46.899: W/System.err(2261):     at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
02-12 02:07:46.899: W/System.err(2261):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
02-12 02:07:46.909: W/System.err(2261):     at android.view.View.dispatchPointerEvent(View.java:7886)
02-12 02:07:46.919: W/System.err(2261):     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3954)
02-12 02:07:46.919: W/System.err(2261):     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3833)
02-12 02:07:46.919: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
02-12 02:07:46.929: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
02-12 02:07:46.939: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
02-12 02:07:46.939: W/System.err(2261):     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3525)
02-12 02:07:46.949: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
02-12 02:07:46.949: W/System.err(2261):     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3582)
02-12 02:07:46.959: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
02-12 02:07:46.969: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
02-12 02:07:46.969: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
02-12 02:07:46.969: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
02-12 02:07:46.979: W/System.err(2261):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
02-12 02:07:46.989: W/System.err(2261):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5602)
02-12 02:07:46.989: W/System.err(2261):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5582)
02-12 02:07:46.999: W/System.err(2261):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5553)
02-12 02:07:46.999: W/System.err(2261):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5682)
02-12 02:07:47.009: W/System.err(2261):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
02-12 02:07:47.009: W/System.err(2261):     at android.os.MessageQueue.nativePollOnce(Native Method)
02-12 02:07:47.019: W/System.err(2261):     at android.os.MessageQueue.next(MessageQueue.java:138)
02-12 02:07:47.019: W/System.err(2261):     at android.os.Looper.loop(Looper.java:123)
02-12 02:07:47.029: W/System.err(2261):     at android.app.ActivityThread.main(ActivityThread.java:5017)
02-12 02:07:47.029: W/System.err(2261):     at java.lang.reflect.Method.invokeNative(Native Method)
02-12 02:07:47.039: W/System.err(2261):     at java.lang.reflect.Method.invoke(Method.java:515)
02-12 02:07:47.039: W/System.err(2261):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-12 02:07:47.049: W/System.err(2261):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-12 02:07:47.049: W/System.err(2261):     at dalvik.system.NativeStart.main(Native Method)
02-12 02:07:47.059: W/System.err(2261): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
02-12 02:07:47.079: W/System.err(2261):     at libcore.io.Posix.open(Native Method)
02-12 02:07:47.089: W/System.err(2261):     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
02-12 02:07:47.089: W/System.err(2261):     at libcore.io.IoBridge.open(IoBridge.java:393)
02-12 02:07:47.099: W/System.err(2261):     ... 45 more

EACCES (Permission denied)。您必须在清单中明确声明读取外部存储的权限。

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

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

声明到清单文件的 <Manifest> 标记。

如果您使用 Android 版本 >=4.4,则无论是否声明权限 android.permission.WRITE_EXTERNAL_STORAGE,通常禁止写入外部 SD 卡。

参见例如this