我用过
tts.addSpeech(key_string, path);
将音频文件映射到文本字符串,例如
key_string =“Android”
和
path =“/ storage / emulated/0 / Android / data / com.example.admin.machinelearning / files /associations/androidcalm.wav”
在 Android Api等级17
上调用以下方法tts.speak(key_string, queueMode, params);
一切正常,播放映射的声音文件。
但是在 Android Api等级23 上调用上述方法,我收到以下错误,
02-15 11:08:25.941 7220-19682/? W/MediaPlayer: Couldn't open file on client side; trying server side: java.io.FileNotFoundException: No content provider: /storage/emulated/0/Android/data/com.example.admin.machinelearning/files/associations/androidcalm.wav
02-15 11:08:25.946 7220-19682/? D/MediaPlayer: create failed:
java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.example.admin.machinelearning/files/associations/androidcalm.wav: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:452)
at java.io.FileInputStream.<init>(FileInputStream.java:76)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1122)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1094)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1048)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:986)
at android.media.MediaPlayer.create(MediaPlayer.java:893)
at android.speech.tts.AudioPlaybackQueueItem.run(AudioPlaybackQueueItem.java:58)
at android.speech.tts.AudioPlaybackHandler$MessageLoop.run(AudioPlaybackHandler.java:134)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:438)
at java.io.FileInputStream.<init>(FileInputStream.java:76)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1122)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1094)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1048)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:986)
at android.media.MediaPlayer.create(MediaPlayer.java:893)
at android.speech.tts.AudioPlaybackQueueItem.run(AudioPlaybackQueueItem.java:58)
at android.speech.tts.AudioPlaybackHandler$MessageLoop.run(AudioPlaybackHandler.java:134)
at java.lang.Thread.run(Thread.java:818)
我确保声音文件存在并且可以使用下面的代码播放,
Uri uri = Uri.parse(new File("/storage/emulated/0/Android/data/com.example.admin.machinelearning/files/associations/androidcalm.wav").toString());
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(getActivity(),uri);
mediaPlayer.prepare();
mediaPlayer.start();
成功播放声音文件。
另外,我已经尝试了下面的代码(在上面的两个android api级别上)来读取文本文件,然后说出其中包含的字符
String toSay = "Error";
try {
InputStream in = new FileInputStream("/storage/emulated/0/Android/data/com.example.admin.machinelearning/files/associations/x.txt");
toSay = FileUtil.getContentsOfReader(new BufferedReader(new InputStreamReader(in)));
} catch (IOException e) {
e.printStackTrace();
}
然后
tts.speak(toSay, queueMode, params);
哪个正常,并且说出了文本文件中的文字。
首先:如果这是读取权限的问题,那么为什么我在这里没有得到同样的错误?
第二:我尝试使用下面的代码在运行中(在PreferenceFragment内)添加读取和写入权限。 “已授予”正在显示,但仍然没有改变(我仍然得到上面的错误)。
private static final int PERMISSION_REQUEST = 0;
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE , Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQUEST);
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == PERMISSION_REQUEST) {
if (grantResults.length == 2 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
tts.addSpeech("Android", "/storage/emulated/0/Android/data/com.example.admin.machinelearning/files/associations/androidcalm.wav");
tts.speak("Android", queueMode, params);
Toast.makeText(getActivity(),"Granted",Toast.LENGTH_LONG).show();
} else {
getActivity().finish();
Toast.makeText(getActivity(),"Denied",Toast.LENGTH_LONG).show();
}
}
}
同样在Manifest中我声明了以下权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.admin.machinelearning">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
我是Android的新手,也许我犯了一个愚蠢的错误或者不明白这是如何工作的,所以任何帮助都会受到赞赏。
注意:测试是在真正的Android设备上完成的。