I'm downloading an apk from s3 and storing it in a directory named SAMPLE_APK. When I try to execute the apk present in the directory, I get an error.
2022-03-01 15:44:20.773 21867-21867/com.test.digitaloceanspaces D/Main Activity -: File
path - /data/user/0/com.test.digitaloceanspaces/app_SAMPLE_APK/debug.apk
2022-03-01 15:44:20.774 21867-21867/com.test.digitaloceanspaces D/AndroidRuntime:
Shutting down VM
--------- beginning of crash
2022-03-01 15:44:20.779 21867-21867/com.test.digitaloceanspaces E/AndroidRuntime: FATAL
EXCEPTION: main
Process: com.test.digitaloceanspaces, PID: 21867
java.lang.IllegalArgumentException: Failed to find configured root that contains
/data/data/com.test.digitaloceanspaces/app_SAMPLE_APK/debug.apk
at
androidx.core.content.FileProvider$SimplePathStrategy
.getUriForFile(FileProvider.java:800)
at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:442)
But If I read the apk from filesDir, I'm able to execute it.
Below the two different directory structure
Unable to read the apk present in the file parameter of the callback method.
fun downloadLatestApk(callback: (File?, Exception?) -> Unit) {
//using a custom directory named sample apk
val directoryName = "SAMPLE_APK"
val directory = if (appContext.getDir(directoryName, Context.MODE_PRIVATE).exists())
{
Log.d("Local directory", "APK directory Already exists")
appContext.getDir(directoryName, Context.MODE_PRIVATE)
} else {
Log.d("Local directory", "New Directory")
File(appContext.filesDir, directoryName).apply {
this.mkdir()
}
}
val file = File(**directory**, "debug.apk")
val listener = transferUtility.download(spacename, "debug.apk", file)
listener.setTransferListener(object : TransferListener {
override fun onStateChanged(id: Int, state: TransferState?) {
if (state == TransferState.COMPLETED) {
callback(file, null)
}
}
}
Able to execute the apk present in the file parameter of the callback method. Here I'm reading the apk present in the filesDir.
fun downloadLatestAPk(callback: (File?, Exception?) -> Unit) {
//using files dir
val file = File(**appContext.filesDir**, "debug.apk")
val listener = transferUtility.download(spacename, "debug.apk", file)
listener.setTransferListener(object : TransferListener {
override fun onStateChanged(id: Int, state: TransferState?) {
if (state == TransferState.COMPLETED) {
callback(file, null)
}
}
}
This happens only for apk. I'm able to read image files from either of the directories. Unable to fathom this behavior.
Folder structure - Folder Structure
The file provider has the following paths.
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
File from the callback method is sent to the below method for execution.
private fun handleInstallation(file: File) {
Log.d("Main Activity - ", "File path - ${file.path}")
val contentUri =
FileProvider.getUriForFile(
this,
"com.test.digitaloceanspaces" ".provider", file
)
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
startActivity(intent)
}
App crashes after printing the log statement. Any help is deeply appreciated.
CodePudding user response:
path - /data/user/0/com.test.digitaloceanspaces/app_SAMPLE_APK/debug.apk
That is a path not covered by FileProvider.
From getFilesDir()
is covered by entry <files-path
.
You could make it:
/data/user/0/com.test.digitaloceanspaces/files/app_SAMPLE_APK/debug.apk
Not covered by FileProvider: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.test.digitaloceanspaces/app_SAMPLE_APK/debug.apk
Unable to read an apk file from an internal directory
No. Unable to use FileProvider for not allowed path.