Using sound files in TTS on Marshmallow (Android 6) fails with permissions

Using addSpeech () in android TTS, you can link specific text to a sound file. Then the TTS engine plays the file instead of synthesizing the sound of the text (also in the question addSpeech () for Android TTS (Text to Speech) and saying () cannot play the sound file in external storage from marshmallows (api 23) above, with Google TTS ) This does not work on Android 6.0 with TTS version 3.9.14 (and 3.10.10). So far I have not seen the ant message with an answer about why this does not work in Android 6.0. So I thought I would provide more data on this issue that could help someone figure out the problem. (I added this to the question in the link above, but the moderators deleted it, saying that this is not the answer. They did not offer a way to add more such data than to ask another question. Therefore, this question. Additional data on the same question, on which has not yet been answered). so here it goes.

In the manifest, I granted read and write permissions to the application using TTS (which, in turn, uses Media Player) to play the provided voice files.

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

Please note that this works fine before Android 5.0, but does not work on Android version 6.0 (except when res / raw files are used as voice files). Also, when it fails, it seems to give a slightly different error in logcat depending on whether the voice file is in internal or external storage.

  • When the speech file is in the res / raw folder, TTS works fine, playing the necessary voice file using the resource identifier (addSpeech (word, pkgName, resId))

  • When the voice file is in external storage (/ storage / sdcard0 / pkgName / soundFiles / .. playback using TTS gives the error log EACCES (for amr and mp3 files).

     09-08 16:57:17.514 1549-7830/? D/MediaPlayer: create failed: java.io.FileNotFoundException: /storage/emulated/0/pkgName/soundFiles/voice1.amr: open failed: EACCES (Permission denied) at libcore.io.IoBridge.open(IoBridge.java:487) at java.io.FileInputStream.(FileInputStream.java:76) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1115) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1066) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1003) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:983) at android.media.MediaPlayer.create(MediaPlayer.java:890 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:473) at java.io.FileInputStream.(FileInputStream.java:76) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1115) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1066) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1003) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:983) at android.media.MediaPlayer.create(MediaPlayer.java:890) 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 
  • When the voice file is in the internal storage (/data/.../pkgName/soundFiles/ .. playing a word using TTS gives the following error log (for amr and mp3 files).

     09-08 17:24:23.103 1549-32732/? D/MediaPlayer: create failed: java.io.IOException: setDataSource failed. at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1120) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1066) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1003) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:983) at android.media.MediaPlayer.create(MediaPlayer.java:890) 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) 

As an experiment, a MediaPlayer object was created in the same class that uses TTS and plays the same sound files that do not work with TTS. They played great without any problems. Thus, it seems that only the MediaPlayer instance in TTS has file resolution issues.

Any help is appreciated.

Edit: Please note that execution permissions have been executed, so this is not a problem. The problem is limited to the Google Text to Speech engine. Other engines are working correctly.

+5
source share
1 answer

I think this fails because you need to add permissions at runtime (for example, you should ask for permissions when using this feature) on Android phones compared to lollipop 5.1 OS,

 https://developer.android.com/training/permissions/requesting.html 

Check out this link to better understand this problem. And if you need to know how to do this, just simply check this code below.

 https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/ 

here is the code:

 if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); // MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE is an // app-defined int constant. The callback method gets the // result of the request. } } 
-1
source

Source: https://habr.com/ru/post/1271655/


All Articles