Java 能否将文件保存在Galaxy S21的外部存储器中?

Java 能否将文件保存在Galaxy S21的外部存储器中?,java,android-studio,Java,Android Studio,我正在尝试构建一个音乐录制应用程序,录制和停止部分正在工作,但该应用程序似乎无法播放录制的文件,因为它抛出以下错误: java.io.FileNotFoundException: /storage/emulated/0/CKENCAudioRecording.3gp: open failed: ENOENT (No such file or directory) W/System.err: at libcore.io.IoBridge.open(IoBridge.java:492) W/

我正在尝试构建一个音乐录制应用程序,录制和停止部分正在工作,但该应用程序似乎无法播放录制的文件,因为它抛出以下错误:

java.io.FileNotFoundException: /storage/emulated/0/CKENCAudioRecording.3gp: open failed: ENOENT (No such file or directory)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:492)
W/System.err:     at java.io.FileInputStream.<init>(FileInputStream.java:160)
W/System.err:     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1259)
W/System.err:     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1230)
W/System.err:     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1195)
W/System.err:     at com.example.karaokebuddies.record$3.onClick(record.java:99)
W/System.err:     at android.view.View.performClick(View.java:8160)
W/System.err:     at android.widget.TextView.performClick(TextView.java:16193)
W/System.err:     at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
W/System.err:     at android.view.View.performClickInternal(View.java:8137)
W/System.err:     at android.view.View.access$3700(View.java:888)
W/System.err:     at android.view.View$PerformClick.run(View.java:30236)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:938)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loop(Looper.java:246)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:8462)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:596)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
W/System.err:     at libcore.io.Linux.open(Native Method)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err:     at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8323)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:478)
我在stack overflow中搜索了很多类似的案例,但没有一个真正有用

我包括了必要的权限,并将requestLegacyExternalStorage设置为true:

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

    android:requestLegacyExternalStorage="true"

android:requestLegacyExternalStorage=“true”
这是我的record.java:

package com.example.karaokebuddies;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.IOException;
import java.util.Random;

import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

public class record extends AppCompatActivity {
    private Button play, stop, record, stopPlaying;
    private MediaRecorder myAudioRecorder;
    private String outputFile;
    private String AudioSavePathInDevice = null;
    Random random;
    String RandomAudioFileName = "ABCDEFGHIJKLMNOP";
    public static final int RequestPermissionCode = 1;
    private MediaPlayer mediaPlayer;
    boolean isRecording = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.record);
        play = (Button) findViewById(R.id.play);
        stop = (Button) findViewById(R.id.stop);
        record = (Button) findViewById(R.id.record);
        stopPlaying = (Button) findViewById(R.id.button_stopPlaying);
        stop.setEnabled(false);
        play.setEnabled(false);
        stopPlaying.setEnabled(false);
        random = new Random();

        record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkPermission()) {
                    AudioSavePathInDevice = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + CreateRandomAudioFileName(5) + "AudioRecording.3gp";
                    MediaRecorderReady();

                    try {
                        myAudioRecorder.prepare();
                        myAudioRecorder.start();
                        isRecording = true;
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    record.setEnabled(false);
                    stop.setEnabled(true);
                    Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();
                } else {
                    requestPermission();
                }
            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRecording) {
                    myAudioRecorder.stop();
                }
                myAudioRecorder.release();
                isRecording = false;
                stop.setEnabled(false);
                play.setEnabled(true);
                record.setEnabled(true);
                stopPlaying.setEnabled(false);
                Toast.makeText(getApplicationContext(), "Audio Recorded successfully", Toast.LENGTH_LONG).show();
            }
        });

        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) throws IllegalArgumentException, SecurityException, IllegalStateException {
//                MediaPlayer mediaPlayer = new MediaPlayer();

                stop.setEnabled(false);
                record.setEnabled(false);
                stopPlaying.setEnabled(true);

                mediaPlayer = new MediaPlayer();
                try {
//                    mediaPlayer.setDataSource(outputFile);
                    mediaPlayer.setDataSource(AudioSavePathInDevice);
                    mediaPlayer.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                mediaPlayer.start();
                Toast.makeText(getApplicationContext(), "Playing Audio", Toast.LENGTH_LONG).show();
            }
        });

        stopPlaying.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stop.setEnabled(false);
                record.setEnabled(true);
                stopPlaying.setEnabled(false);
                play.setEnabled(true);

                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    MediaRecorderReady();
                }
            }
        });
    }

    public void MediaRecorderReady() {
        myAudioRecorder = new MediaRecorder();
        myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        myAudioRecorder.setOutputFile(AudioSavePathInDevice);
    }

    public String CreateRandomAudioFileName(int string) {
        StringBuilder stringBuilder = new StringBuilder(string);
        int i = 0;
        while (i < string) {
            stringBuilder.append(RandomAudioFileName.charAt(random.nextInt(RandomAudioFileName.length())));
            i ++;
        }
        return stringBuilder.toString();
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(record.this, new String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, RequestPermissionCode);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case RequestPermissionCode:
                if (grantResults.length > 0) {
                    boolean StoragePermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean RecordPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                    if (StoragePermission && RecordPermission) {
                        Toast.makeText(record.this, "Permission Granted", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(record.this, "Permission Denied", Toast.LENGTH_LONG).show();
                    }
                }
                break;
        }
    }

    public boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
        int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), RECORD_AUDIO);
        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }
}
package com.example.karokebuddies;
导入android.content.pm.PackageManager;
导入android.media.MediaPlayer;
导入android.media.MediaRecorder;
导入android.os.Bundle;
导入android.os.Environment;
导入android.view.view;
导入android.widget.Button;
导入android.widget.Toast;
导入androidx.annotation.NonNull;
导入androidx.appcompat.app.appcompat活动;
导入androidx.core.app.ActivityCompat;
导入androidx.core.content.ContextCompat;
导入java.io.IOException;
导入java.util.Random;
导入静态android.Manifest.permission.RECORD\u音频;
导入静态android.Manifest.permission.WRITE\u外部存储;
公共类记录扩展了AppCompative活动{
私人按钮播放、停止、录制、停止播放;
私人媒体录音机;
私有字符串输出文件;
私有字符串AudioSavePathInDevice=null;
随机;
字符串RandomAudioFileName=“ABCDEFGHIJKLMNOP”;
公共静态最终int RequestPermissionCode=1;
私人媒体播放器;
布尔值isRecording=false;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.record);
play=(按钮)findViewById(R.id.play);
停止=(按钮)findViewById(R.id.stop);
记录=(按钮)findViewById(R.id.record);
stopPlaying=(按钮)findViewById(R.id.Button\u stopPlaying);
stop.setEnabled(false);
play.setEnabled(假);
stopPlaying.setEnabled(false);
随机=新随机();
record.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
if(checkPermission()){
AudioSavePathInDevice=Environment.getExternalStorageDirectory().getAbsolutePath()+“/”+CreateRandomAudioFileName(5)+“AudioRecording.3gp”;
MediaRecorderReady();
试一试{
myAudioRecorder.prepare();
myAudioRecorder.start();
isRecording=true;
}捕获(非法状态){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
record.setEnabled(false);
stop.setEnabled(true);
Toast.makeText(getApplicationContext(),“录制已开始”,Toast.LENGTH_LONG.show();
}否则{
requestPermission();
}
}
});
stop.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
如果(isRecording){
myAudioRecorder.stop();
}
myAudioRecorder.release();
isRecording=false;
stop.setEnabled(false);
play.setEnabled(真);
record.setEnabled(true);
stopPlaying.setEnabled(false);
Toast.makeText(getApplicationContext(),“音频录制成功”,Toast.LENGTH_LONG.show();
}
});
play.setOnClickListener(新视图.OnClickListener(){
@凌驾
public void onClick(视图v)抛出IllegalArgumentException、SecurityException、IllegalStateException{
//MediaPlayer=新的MediaPlayer();
stop.setEnabled(false);
record.setEnabled(false);
stopPlaying.setEnabled(true);
mediaPlayer=新的mediaPlayer();
试一试{
//setDataSource(outputFile);
mediaPlayer.setDataSource(AudioSavePathInDevice);
mediaPlayer.prepare();
}捕获(IOE异常){
e、 printStackTrace();
}
mediaPlayer.start();
Toast.makeText(getApplicationContext(),“播放音频”,Toast.LENGTH_LONG.show();
}
});
stopPlaying.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
stop.setEnabled(false);
record.setEnabled(true);
stopPlaying.setEnabled(false);
play.setEnabled(真);
如果(mediaPlayer!=null){
mediaPlayer.stop();
mediaPlayer.release();
MediaRecorderReady();
}
}
});
}
public void MediaRecorderReady(){
myAudioRecorder=新的MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.ThreeGPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myAudioRecorder.setOutputFile(AudioSavePathIndex);
}
公共字符串CreateRandomAudioFileName(int字符串){
StringBuilder StringBuilder=新的StringBuilder(字符串);
int i=0;
while(ipackage com.example.karaokebuddies;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.IOException;
import java.util.Random;

import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

public class record extends AppCompatActivity {
    private Button play, stop, record, stopPlaying;
    private MediaRecorder myAudioRecorder;
    private String outputFile;
    private String AudioSavePathInDevice = null;
    Random random;
    String RandomAudioFileName = "ABCDEFGHIJKLMNOP";
    public static final int RequestPermissionCode = 1;
    private MediaPlayer mediaPlayer;
    boolean isRecording = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.record);
        play = (Button) findViewById(R.id.play);
        stop = (Button) findViewById(R.id.stop);
        record = (Button) findViewById(R.id.record);
        stopPlaying = (Button) findViewById(R.id.button_stopPlaying);
        stop.setEnabled(false);
        play.setEnabled(false);
        stopPlaying.setEnabled(false);
        random = new Random();

        record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkPermission()) {
                    AudioSavePathInDevice = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + CreateRandomAudioFileName(5) + "AudioRecording.3gp";
                    MediaRecorderReady();

                    try {
                        myAudioRecorder.prepare();
                        myAudioRecorder.start();
                        isRecording = true;
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    record.setEnabled(false);
                    stop.setEnabled(true);
                    Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();
                } else {
                    requestPermission();
                }
            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRecording) {
                    myAudioRecorder.stop();
                }
                myAudioRecorder.release();
                isRecording = false;
                stop.setEnabled(false);
                play.setEnabled(true);
                record.setEnabled(true);
                stopPlaying.setEnabled(false);
                Toast.makeText(getApplicationContext(), "Audio Recorded successfully", Toast.LENGTH_LONG).show();
            }
        });

        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) throws IllegalArgumentException, SecurityException, IllegalStateException {
//                MediaPlayer mediaPlayer = new MediaPlayer();

                stop.setEnabled(false);
                record.setEnabled(false);
                stopPlaying.setEnabled(true);

                mediaPlayer = new MediaPlayer();
                try {
//                    mediaPlayer.setDataSource(outputFile);
                    mediaPlayer.setDataSource(AudioSavePathInDevice);
                    mediaPlayer.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                mediaPlayer.start();
                Toast.makeText(getApplicationContext(), "Playing Audio", Toast.LENGTH_LONG).show();
            }
        });

        stopPlaying.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stop.setEnabled(false);
                record.setEnabled(true);
                stopPlaying.setEnabled(false);
                play.setEnabled(true);

                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    MediaRecorderReady();
                }
            }
        });
    }

    public void MediaRecorderReady() {
        myAudioRecorder = new MediaRecorder();
        myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        myAudioRecorder.setOutputFile(AudioSavePathInDevice);
    }

    public String CreateRandomAudioFileName(int string) {
        StringBuilder stringBuilder = new StringBuilder(string);
        int i = 0;
        while (i < string) {
            stringBuilder.append(RandomAudioFileName.charAt(random.nextInt(RandomAudioFileName.length())));
            i ++;
        }
        return stringBuilder.toString();
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(record.this, new String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, RequestPermissionCode);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case RequestPermissionCode:
                if (grantResults.length > 0) {
                    boolean StoragePermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean RecordPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                    if (StoragePermission && RecordPermission) {
                        Toast.makeText(record.this, "Permission Granted", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(record.this, "Permission Denied", Toast.LENGTH_LONG).show();
                    }
                }
                break;
        }
    }

    public boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
        int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), RECORD_AUDIO);
        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }
}
final File root = new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)));

// Create the directory if it doesn't exist
if (!root.exists()) {
    boolean wasSuccessful = root.mkdirs();

    // Display Toast message if the directory creation wasn't successful
    if (!wasSuccessful) {
        mToast = Toast.makeText(this, R.string.photo_directory_not_created_error, Toast.LENGTH_SHORT);
        mToast.show();
    }
}