简体   繁体   English

MediaRecorder prepare() failed /storage/emulated/0/: open failed: EPERM (Operation not allowed)

[英]MediaRecorder prepare() failed /storage/emulated/0/: open failed: EPERM (Operation not permitted)

I am trying to record audio on my Android 12 Device with File and Media Permission granted but recorder.prepare();我正在尝试在我的 Android 12 设备上录制音频,并授予File and Media Permission ,但recorder.prepare(); throws投掷

prepare() failed /storage/emulated/0/Music/Exotel/Media/Exotel Audio/Voice Messages/Exotel Temp/Exotel_Voice1658709937668.3gpp: open failed: EPERM (Operation not permitted)

I am using official documentation but they are saving recording into app specific storage( getExternalCacheDir().getAbsolutePath(); ) and i am saving on external public storage String TempPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath()+ "/" + subfolder;我正在使用 官方文档,但他们正在将录音保存到特定于应用程序的存储中( getExternalCacheDir().getAbsolutePath(); )并且我正在保存外部公共存储String TempPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath()+ "/" + subfolder; . . No matter what i try i still get the same error whenever i tried to save into external shared storage.无论我尝试什么,每当我尝试保存到外部共享存储时,我仍然会遇到相同的错误。

Here is my code:这是我的代码:

String subfolder = "Exotel/Media/Exotel Audio/Voice Messages/Exotel Temp";
String time = new SimpleDateFormat("yyyyMMddhhmmss", Locale.US).format(new Date());
String filename = Session.getUserFname()+"_Voice"+time+".3gp";
String TempPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath()+ "/" + subfolder;
File dir = new File(TempPath);

if (!dir.exists()){
    dir.mkdirs();
}

TempPath = TempPath+"/"+filename;
Log.d(TAG, "onTouch: Temp Path "+TempPath);

recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(TempPath);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

try {
    recorder.prepare();
    recorder.start();
} catch (IOException | IllegalStateException e) {
    Log.e(TAG, "prepare() failed "+e.getMessage());
}

The getExternalStoragePublicDirectory() method is deprecated in API level 29 (Android 10). getExternalStoragePublicDirectory()方法在 API 级别 29 (Android 10) 中已弃用

If you want to save a file into a public shareable directory you have to use MediaStore API .如果要将文件保存到公共可共享目录中,则必须使用MediaStore API I also recommend taking a look at all options for storing files on Android.我还建议查看在 Android 上存储文件的所有选项

If you have no problems with saving your recordings into a cache directory (by using the code from the official docs).如果您将录音保存到缓存目录中没有问题(使用官方文档中的代码)。 Then you can copy the file from the cache to the public directory using MediaStore API:然后您可以使用 MediaStore API 将文件从缓存复制到公共目录:

private void copyToPublicDirectory(String filename) throws IOException {
    InputStream inputStream = createInputStream(filename);
    OutputStream outputStream = createOutputStream(filename);
    copy(inputStream, outputStream);
}

private InputStream createInputStream(String filename) throws IOException {
    File cacheDirectory = getExternalCacheDir();
    if (cacheDirectory == null)
        throw new RuntimeException("Cache is not currently available");
    return new FileInputStream(new File(cacheDirectory, filename));
}

private OutputStream createOutputStream(String filename) throws IOException {
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, filename);
    Uri contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    Uri uri = getContentResolver().insert(contentUri, contentValues);
    if (uri == null)
        throw new RuntimeException("Cannot insert file: " + filename);
    OutputStream outputStream = getContentResolver().openOutputStream(uri);
    if (outputStream == null)
        throw new RuntimeException("Cannot open uri: " + uri);
    return outputStream;
}

private void copy(InputStream source, OutputStream target) throws IOException {
    byte[] buffer = new byte[8192];
    int length;
    while ((length = source.read(buffer)) != -1) {
        target.write(buffer, 0, length);
    }
}

Note: 3gp recordings have video/3gpp mime type.注意: 3gp 录音有video/3gpp mime 类型。 And it will be saved into the Movies directory (as @blackapps already said).它将被保存到Movies目录中(正如@blackapps 已经说过的那样)。 If you want to record a file in audio format and save it into the Music directory, then do the following:如果您想以音频格式录制文件并将其保存到Music目录中,请执行以下操作:

  1. Change content uri from MediaStore.Video.Media.EXTERNAL_CONTENT_URI to MediaStore.Audio.Media.EXTERNAL_CONTENT_URI in the code above.将上面代码中的内容 uri 从MediaStore.Video.Media.EXTERNAL_CONTENT_URI更改为MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

  2. Use OGG format in your MediaRecorder setup (OGG format is available only for Android API 29 and higher):在 MediaRecorder 设置中使用 OGG 格式(OGG 格式仅适用于 Android API 29 及更高版本):

     setOutputFormat(MediaRecorder.OutputFormat.OGG) setAudioEncoder(MediaRecorder.AudioEncoder.OPUS)

PS: don't forget to add all necessary permissions to make things work. PS:不要忘记添加所有必要的权限以使事情正常进行。

File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "/" + getString(R.string.app_name) + "/" + getString(R.string.voice_messages));文件路径 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "/" + getString(R.string.app_name) + "/" + getString(R.string.voice_messages));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 FileNotFoundException open failed: EPERM (Operation not allowed) during save image file to internal storage on android - FileNotFoundException open failed: EPERM (Operation not permitted) during saving image file to internal storage on android java.io.FileNotFoundException 打开失败:EPERM(不允许操作) - java.io.FileNotFoundException open failed: EPERM (Operation not permitted) Google Play服务错误:读取失败:EPERM(不允许操作) - Error in Google Play Services: read failed: EPERM (Operation not permitted) java.net.SocketException:套接字失败:EPERM(不允许操作) - java.net.SocketException: socket failed: EPERM (Operation not permitted) MediaRecorder IOException 准备失败 - MediaRecorder IOException prepare failed 未解决的 java.net.SocketException:套接字失败:EPERM(不允许操作) - Un-resolved java.net.SocketException: socket failed: EPERM (Operation not permitted) java.net.SocketException:套接字失败:EPERM 操作不允许,尽管 AndroidManifest 中有许可 - java.net.SocketException: socket failed: EPERM Operation not permitted although AndroidManifest have permits in it Android Java 抛出 java.net.SocketException:套接字失败:EPERM(不允许操作) - Android Java throws java.net.SocketException: socket failed: EPERM (Operation not permitted) FileNotFoundException:/storage/emulated/0/JsonParseTutorialCache:打开失败:ENOENT(没有这样的文件或目录) - FileNotFoundException: /storage/emulated/0/JsonParseTutorialCache: open failed: ENOENT (No such file or directory) java.io.FileNotFoundException:/storage/emulated/0/New file.txt:打开失败:EACCES(权限被拒绝) - java.io.FileNotFoundException: /storage/emulated/0/New file.txt: open failed: EACCES (Permission denied)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM