[英]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
目录中,请执行以下操作:
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
。
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.