I desire to access media files from C code in android application.
I use this method to get file path by file uri:
fun getFileNameThatICanUseInNativeCode(uri: Uri?, applicationContext: Context): String? {
val mParcelFileDescriptor =
applicationContext.contentResolver.openFileDescriptor(uri!!, "r")
if (mParcelFileDescriptor != null) {
val fd: Int = mParcelFileDescriptor.fd
val file = File("/proc/self/fd/$fd")
var path: String? = null
try {
path = Os.readlink(file.absolutePath).toString()
mParcelFileDescriptor.close()
} catch (e: ErrnoException) {
e.printStackTrace()
}
return path
} else {
return null
}
}
This method return generally this path, which could be accessed from C code
/mnt/user/0/emulated/0/DCIM/Camera/{fileName}
but for some phones it seems that the user folder is not found (maybe persmission issue, because the user
folder is not acceable from adb shell (for example).
From adb shell, my file is also located here : /storage/emulated/0/DCIM/Camera/$fileName
, this native_file_path also does not work
How to access this file from C code? For some phones i can access for others no:
if((file = fopen(native_file_path,"a"))!=NULL)
I desire to access media files from C code in android application.
I use this method to get file path by file uri:
fun getFileNameThatICanUseInNativeCode(uri: Uri?, applicationContext: Context): String? {
val mParcelFileDescriptor =
applicationContext.contentResolver.openFileDescriptor(uri!!, "r")
if (mParcelFileDescriptor != null) {
val fd: Int = mParcelFileDescriptor.fd
val file = File("/proc/self/fd/$fd")
var path: String? = null
try {
path = Os.readlink(file.absolutePath).toString()
mParcelFileDescriptor.close()
} catch (e: ErrnoException) {
e.printStackTrace()
}
return path
} else {
return null
}
}
This method return generally this path, which could be accessed from C code
/mnt/user/0/emulated/0/DCIM/Camera/{fileName}
but for some phones it seems that the user folder is not found (maybe persmission issue, because the user
folder is not acceable from adb shell (for example).
From adb shell, my file is also located here : /storage/emulated/0/DCIM/Camera/$fileName
, this native_file_path also does not work
How to access this file from C code? For some phones i can access for others no:
if((file = fopen(native_file_path,"a"))!=NULL)
Share
Improve this question
edited Nov 20, 2024 at 11:58
Артемий Величко
asked Nov 20, 2024 at 11:46
Артемий ВеличкоАртемий Величко
491 silver badge8 bronze badges
2
|
1 Answer
Reset to default 0Android 13 and higher:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
The code I used:
class ImageInDcim(private val context: Context) {
fun listImagesInDCIM() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.READ_MEDIA_IMAGES), 100)
return
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 100)
return
}
}
val uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val projection = arrayOf(
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA
)
val selection = "${MediaStore.Images.Media.DATA} LIKE ?"
val selectionArgs = arrayOf("%/DCIM/%")
val cursor = context.contentResolver.query(
uri,
projection,
selection,
selectionArgs,
"${MediaStore.Images.Media.DATE_ADDED} DESC"
)
cursor?.use {
val columnIndexDisplayName = it.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME)
val columnIndexData = it.getColumnIndex(MediaStore.Images.Media.DATA)
while (it.moveToNext()) {
val displayName = it.getString(columnIndexDisplayName)
val dataPath = it.getString(columnIndexData)
println("Image found: $displayName at $dataPath")
}
}
}
}
emulated/0
is not a native path, but it's emulated ...calling to Java through JNI might be an alternative: stackoverflow/a/29695982/549372 ...while the difference is single vs. multi-user filesystem layout. – Martin Zeitler Commented Nov 20, 2024 at 12:14