我有这个功能,可以在单击按钮时生成音频文件。我在请求写入外部存储文件夹的权限时遇到问题。我已经有了一些东西,但我没有收到要求它的对话框。如果有人将该功能添加到我现有的代码中将会很有帮助。
翻译并生成音频文件:
private void initializeTextToSpeech(Locale selectedLocale) {
speech = new TextToSpeech(getContext(), status -> {
if (status == TextToSpeech.SUCCESS) {
int result = speech.setLanguage(selectedLocale);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e(TAG, "Language not supported");
// Handle the case where the language is not supported
} else {
Log.i(TAG, "Text-to-Speech initialized");
// Now that TextToSpeech is initialized and language is set, let's synthesize text to an audio file
String textToSpeak = translatedText;
saveAudioToFile(textToSpeak);
}
} else {
Log.e(TAG, "Text-to-Speech initialization failed");
// Handle Text-to-Speech initialization failure
}
});
}
private void createFile() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_CODE);
}
}
folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "Text To Speech Audio");
if (!folder.exists()) {
boolean isDirectoryCreated = folder.mkdirs();
if (!isDirectoryCreated)
Toast.makeText(getContext(), "Can't create directory to save the Audio", Toast.LENGTH_SHORT).show();
}
folder.mkdirs();
mAudioFilename = folder.getAbsolutePath() + "/" + languageCode + "-" + translateTo + mUtteranceID + System.currentTimeMillis() + ".wav";
}
private void saveAudioToFile(String textToSpeak) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
speech.synthesizeToFile(textToSpeak, null, new File(mAudioFilename), mUtteranceID);
Toast.makeText(getContext(), "Saved to " + mAudioFilename, Toast.LENGTH_LONG).show();
} else {
HashMap<String, String> hm = new HashMap();
hm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, mUtteranceID);
speech.synthesizeToFile(textToSpeak, hm, mAudioFilename);
Toast.makeText(getContext(), "Saved to " + mAudioFilename, Toast.LENGTH_LONG).show();
}
}
我的电话:
generateAudioBtn.setOnClickListener(view -> {
initializeTextToSpeech(selectedLocale);
createFile();
});
这里的问题是您正在请求权限但没有等待用户的响应就继续创建文件。您应该将 createFile() 调用移至 onRequestPermissionsResult 回调,该回调在用户响应权限请求对话框时调用。
具体操作方法如下:
首先,重写 Activity 中的 onRequestPermissionsResult 方法:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == WRITE_EXTERNAL_STORAGE_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission was granted, continue with creating the file
createFile();
} else {
// Permission was denied, handle the error
Toast.makeText(getContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
}
}
然后,修改 createFile() 方法以仅请求权限:
private void createFile() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_CODE);
return; // Return here, don't continue with creating the file
}
}
// Continue with creating the file if the permission is already granted
folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "Text To Speech Audio");
if (!folder.exists()) {
boolean isDirectoryCreated = folder.mkdirs();
if (!isDirectoryCreated)
Toast.makeText(getContext(), "Can't create directory to save the Audio", Toast.LENGTH_SHORT).show();
}
folder.mkdirs();
mAudioFilename = folder.getAbsolutePath() + "/" + languageCode + "-" + translateTo + mUtteranceID + System.currentTimeMillis() + ".wav";
}
现在,当您单击该按钮时,它将请求权限并等待用户的响应,然后再继续创建文件。如果已经授予权限,它将立即继续创建文件。