如何获得图像文件的绝对路径?



我正在创建一个绘图应用程序,并添加了一个保存图像功能,该功能将使用MediaStore在外部存储的图片文件夹中存储我的位图。现在我想添加一个共享图像的功能,并且需要保存图像的绝对路径。我很困惑如何获得图像的绝对路径。

注:-我使用了Philipp Lackner的代码在外部存储器中保存图像。

private fun saveImage(mbitmap:Bitmap?):Boolean/*String*/{ // to run code in Background Thread

val displayName = "Drawing" + System.currentTimeMillis() / 1000
val imageCollection = sdkVersion29andUp {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} ?: MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val contentValues = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "$displayName.jpeg")
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.WIDTH, mbitmap!!.width)
put(MediaStore.Images.Media.HEIGHT, mbitmap!!.height)
}
return try{
contentResolver.insert(imageCollection,contentValues)?.also { uri ->
contentResolver.openOutputStream(uri).use { outputstream->
if(!mbitmap!!.compress(Bitmap.CompressFormat.JPEG,95,outputstream))
throw IOException("Couldn't save Bitmap")
}
}?: throw IOException("Couldn't create MediaStore entry")
true
}catch (e:IOException){
e.printStackTrace()
false
}  
下面是共享图像功能的代码。这里savedImagePath是全局变量,用于存储保存的图像的绝对路径。
private fun shareImage(){
MediaScannerConnection.scanFile(this,arrayOf(savedImagePath!!),null){
path,uri-> val sharedIntent=Intent()
sharedIntent.action=Intent.ACTION_SEND
sharedIntent.putExtra(Intent.EXTRA_STREAM,uri)
sharedIntent.setType("image/jpeg")
startActivity(
Intent.createChooser(sharedIntent,"Share")
)
}
}

您可以使用以下命令从内容uri获取文件路径:

/**
* Parses out the real local file path from the file content URI
*/
fun getUriRealPath(context: Context, uri: Uri): String? {
var filePath: String? = ""
if (isContentUri(uri)) {
filePath = if (isGooglePhotoDoc(uri.authority)) {
uri.lastPathSegment
} else {
getFileRealPath(context.contentResolver, uri, null)
}
} else if (isFileUri(uri)) {
filePath = uri.path
} else if (DocumentsContract.isDocumentUri(context, uri)) {
// Get uri related document id
val documentId = DocumentsContract.getDocumentId(uri)
// Get uri authority
val uriAuthority = uri.authority
if (isMediaDoc(uriAuthority)) {
val idArr = documentId.split(":".toRegex()).toTypedArray()
if (idArr.size == 2) {
// First item is document type
val docType = idArr[0]
// Second item is document real id
val realDocId = idArr[1]
// Get content uri by document type
var mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
when (docType) {
"image" -> {
mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
"video" -> {
mediaContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
}
// Get where clause with real document id.
val whereClause = MediaStore.Images.Media._ID + " = " + realDocId
filePath = getFileRealPath(
context.contentResolver,
mediaContentUri,
whereClause
)
}
} else if (isDownloadDoc(uriAuthority)) {
// Build download uri.
val downloadUri = Uri.parse("content://downloads/public_downloads")
// Append download document id at uri end.
val downloadUriAppendId =
ContentUris.withAppendedId(downloadUri, java.lang.Long.valueOf(documentId))
filePath = getFileRealPath(
context.contentResolver,
downloadUriAppendId,
null
)
} else if (isExternalStoreDoc(uriAuthority)) {
val idArr = documentId.split(":".toRegex()).toTypedArray()
if (idArr.size == 2) {
val type = idArr[0]
val realDocId = idArr[1]
if ("primary".equals(type, ignoreCase = true)) {
filePath = Environment.getExternalStorageDirectory()
.toString() + "/" + realDocId
}
}
}
}
return filePath
}
/**
* Checks whether this uri is a content uri or not.
* Content uri like content://media/external/images/media/1302716
*/
private fun isContentUri(uri: Uri): Boolean {
var isContentUri = false
val uriSchema = uri.scheme
if ("content".equals(uriSchema, ignoreCase = true)) {
isContentUri = true
}
return isContentUri
}
/**
* Check whether this uri is a file uri or not.
* File uri like file:///storage/41B7-12F1/DCIM/Camera/IMG_20180211_095139.jpg
*/
private fun isFileUri(uri: Uri): Boolean {
var isFileUri = false
val uriSchema = uri.scheme
if ("file".equals(uriSchema, ignoreCase = true)) {
isFileUri = true
}
return isFileUri
}
/**
* Checks whether this document is provided by ExternalStorageProvider.
* @return true if the file is saved in external storage, false otherwise
*/
private fun isExternalStoreDoc(uriAuthority: String?): Boolean {
return "com.android.externalstorage.documents" == uriAuthority
}
/**
* Checks whether this document is provided by DownloadsProvider.
* @return true if this file is a download file, false otherwise
*/
private fun isDownloadDoc(uriAuthority: String?): Boolean {
return "com.android.providers.downloads.documents" == uriAuthority
}
/**
* Checks if MediaProvider provided this document
* @return true if this image is created in android media app, false otherwise
*/
private fun isMediaDoc(uriAuthority: String?): Boolean {
return "com.android.providers.media.documents" == uriAuthority
}
/**
* Checks whether google photos provided this document, if true means this image is created in google photos app
*/
private fun isGooglePhotoDoc(uriAuthority: String?): Boolean {
return "com.google.android.apps.photos.content" == uriAuthority
}
/**
* Return uri represented document file real local path
*/
private fun getFileRealPath(
contentResolver: ContentResolver,
uri: Uri,
whereClause: String?
): String {
var filePath = ""
// Query the uri with condition
val cursor = contentResolver.query(uri, null, whereClause, null, null)
if (cursor != null) { // if cursor is not null
if (cursor.moveToFirst()) {
// Get columns name by uri type.
var columnName = MediaStore.Images.Media.DATA
when (uri) {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI -> {
columnName = MediaStore.Images.Media.DATA
}
MediaStore.Video.Media.EXTERNAL_CONTENT_URI -> {
columnName = MediaStore.Video.Media.DATA
}
}
// Get column index.
val filePathColumnIndex = cursor.getColumnIndex(columnName)
// Get column value which is the uri related file local path.
filePath = cursor.getString(filePathColumnIndex)
}
cursor.close()
}
return filePath
}

如果你想要一个更短的版本,你可以只使用:getFileRealPath(),如果uri是一个内容uri,它会给你uri文件路径,就像你提供的代码中的情况一样。

p。S: DATA列可能被显示为已弃用,但它仍然可以读取。

最新更新