My Android app I'm building is having difficulty reading any file from inside my app's directories, including internal storage (using filesDir
).
Because it's internal storage, I shouldn't need any read/write permissions added to my manifest, but just to troubleshoot, I've added:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Additionally, I'm targeting devices from Marshmallow up, so I have successfully implemented Runtime permissions as well (in a different activity)... so permissions of any type should not be an issue.
Here's my Kotlin code, which upon the Activity being started, is supposed to start playing an MP3 file. (The fileName
is passed by the previous activity)
class RecordingManager : AppCompatActivity() {
var audioPlayer: MediaPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recording_manager)
actionBar?.title = getString(R.string.recording_manager_actionbar_title)
supportActionBar?.title = getString(R.string.recording_manager_actionbar_title)
actionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val typedValue = TypedValue()
theme.resolveAttribute(R.attr.colorPrimary, typedValue, true)
val color = typedValue.data
supportActionBar?.setBackgroundDrawable(ColorDrawable(color))
val recordingsDir = File(filesDir, "recordings")
val fileName = intent.getStringExtra("fileName")
txtTitle.text = fileName
val audioFile = File(recordingsDir, fileName!!)
audioFile.setReadable(true)
audioFile.setWritable(true)
var mediaPlayer: MediaPlayer? = MediaPlayer.create(this, Uri.parse(audioFile.absolutePath))
mediaPlayer?.start() // no need to call prepare(); create() does that for you
}
Reading the Logcat, I can clearly see that the MP3 file exists, however, MediaPlayer is unable to read it:
2019-08-05 14:03:21.360 993-20629/? E/ClearFileSource: Failed to open file '/data/user/0/dev.oliverm.materialvoicerecorder/files/recordings/recording2019-08-0323:35:55.97500.mp3'. (Permission denied)
2019-08-05 14:03:21.360 993-20629/? E/GenericSource: Failed to create data source!
2019-08-05 14:03:21.357 993-993/? W/generic: type=1400 audit(0.0:566): avc: denied { read } for name="0" dev="sda45" ino=524291 scontext=u:r:mediaserver:s0 tcontext=u:object_r:system_data_file:s0 tclass=lnk_file permissive=0
2019-08-05 14:03:21.360 20593-20610/dev.oliverm.materialvoicerecorder E/MediaPlayerNative: error (1, -2147483648)
2019-08-05 14:03:21.361 20593-20593/dev.oliverm.materialvoicerecorder D/MediaPlayer: create failed:
This line right here:
W/generic: type=1400 audit(0.0:566): avc: denied { read } for name="0" dev="sda45" ino=524291
leads me to believe it's an SELinux issue.
I've tested this using multiple emulators & devices. I've used my own Pixel phone to test it, and I've used multiple emulators (M, N, O, P, Q beta) to no avail.
I have no idea why SELinux is not permitting my app to read files from inside my internal app's directory. Any help is greatly appreciated.
Uri.parse(audioFile.absolutePath)
audioFile.absolutePath
is not a URI, its a path. URIs would start with a scheme (file:). Paths start from a directory. So you're parsing a non URI as a URI, ending with an exception. Use Uri.fromFile(audioFile)
instead