我试图从Xamarin Android中的intent chooser获得真正的路径,它在除Android 10之外的所有Android版本中都能正常工作。在Android10中,内容uri如下
content://com.android.providers.downloads.documents/document/msf:180
您可以查询文件名,然后构建路径。
>
查询文件名:
public static string getFileName(Context context, Android.Net.Uri uri)
{
ICursor cursor = null;
string[] projection = {
MediaStore.MediaColumns.DisplayName
};
try
{
cursor = context.ContentResolver.Query(uri, projection, null, null,
null);
if (cursor != null && cursor.MoveToFirst())
{
int index = cursor.GetColumnIndexOrThrow(MediaStore.MediaColumns.DisplayName);
return cursor.GetString(index);
}
}
finally
{
if (cursor != null)
if (cursor != null)
{
cursor.Close();
}
}
return null;
}
构建路径:
string fileName = getFileName(context, uri);
string filePath = Android.OS.Environment.ExternalStorageDirectory + "/Download/" + fileName;
在得到图像文件的URI之后,我们当然需要通过压缩来编辑这个文件,然后得到一个真实的文件路径。如果您的目标是SDK 30,这是我使用作用域存储的实现;)别忘了给我的答案投票。
import android.content.ContentValues
import android.content.Context
import android.content.res.AssetFileDescriptor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageDecoder
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import androidx.annotation.RequiresApi
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileOutputStream
/**
* Created by Mostafa Anter on 11/5/20.
*/
object PhotoHelper{
@RequiresApi(Build.VERSION_CODES.Q)
/**
* mContext: context from activity or fragment,
* imageSelectedUri: uri that return from any pick picture library it usually return inside on activity response method
* appFolderName: name of folder that will generate to save compressing images ;)
* createdImageCompressedName : random name of new compressed image
*/
fun compressGetImageFilePath(
mContext: Context,
imageSelectedUri: Uri,
appFolderName: String,
createdImageCompressedName: String = System.currentTimeMillis().toString()
): String {
//region Getting the photo to process it
val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(mContext.contentResolver, imageSelectedUri))
} else {
mContext.contentResolver.openInputStream(imageSelectedUri)?.use { inputStream ->
BitmapFactory.decodeStream(inputStream)
}
}
// endregion
//region save photo to gallery using Scoped storage
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, createdImageCompressedName)
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/$appFolderName/")
put(MediaStore.Images.Media.IS_PENDING, 1)
}
val collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val imageUri = mContext.contentResolver.insert(collection, values)
//endregion
//region save image
mContext.contentResolver.openOutputStream(imageUri!!).use { out ->
bitmap!!.compress(Bitmap.CompressFormat.PNG, 100, out)
}
values.clear()
values.put(MediaStore.Images.Media.IS_PENDING, 0)
mContext.contentResolver.update(imageUri, values, null, null)
//endregion
//region get file path of content uri
val file = File(mContext.cacheDir, "$createdImageCompressedName.png")
try {
val assetFileDescriptor: AssetFileDescriptor = mContext.contentResolver.openAssetFileDescriptor(imageUri, "r")!!
val inputStream = FileInputStream(assetFileDescriptor.fileDescriptor)
val outputStream = FileOutputStream(file)
inputStream.copyTo(outputStream)
inputStream.close()
outputStream.close()
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
//endregion
return file.path
}
}
所以,如果你想瞄准新旧设备,简单地做一个if语句来检查Android版本,如果AndroidQ更大或相等,使用我的方法,否则使用你的旧方法。
Android 10默认启用了作用域存储。这意味着您无法直接访问外部存储路径——请看这里。
通过在应用程序的AndroidManifest中将requestLegacyExternalStorage设置为true
,可以执行建议的操作。xml,但请记住,这只适用于targetSdk 29,而不适用于30。
如果你试图访问媒体,这应该通过MediaStore完成。否则,请查看作用域存储文档。
我们正在从文件uri安装apk,它工作到Android Pie(9),在Android10移动中它显示“在解析时出现问题”(There was problem while parsing)。我们只在应用程序存储中存储了文件,构建版本为4.4 我已经分享了下面的代码。多谢好处。 清单中的提供程序 Provider_Paths
我正在尝试获取内容URI的文件路径。URL如下所示:content://com.android.providers.downloads.documents/document/31 游标对象不是null,但cursor.getString(column_index)返回null。 列索引始终为0。 编辑:内容URI是从文件管理器返回的,因此它应该表示实际的文件。
我正在尝试使用隐式意图操作_SEND将其他应用程序中的图像共享到我的应用程序中。 当从chrome浏览器共享搜索图像时,应用程序接收到一个内容URI,如下所示: 如何从这种类型的内容URI获取文件路径?所有其他应用,比如Facebook、谷歌都在这么做。我使用FileChooser获取其他类型内容URI的文件路径(例如,从Gallery)。 试着到处寻找,但没有太多帮助。有人能建议如何使用这些内容
我想从URI中获得完整的文件路径。URI不是图像,而是音乐文件,但如果我像纵隔解决方案那样做,如果应用程序用户选择eg Astro作为浏览器,而不是音乐播放器,它就不会工作。我怎么解决这个?
我想从图库中选择一个图像,然后使用它将图像加载到ImageView项中。 但是图像没有以正确的方式旋转,所以我应该使用ExifInterface类,并且exif构造函数希望文件的路径是字符串,而不是URI。 为了将URI转换为字符串,我编写了以下方法: 问题从这里开始... 结果变量总是返回null。我尝试了stackoverflow中的许多解决方案,如下所示: 我试图用null值查询投影。仍然返
因此,我使用Reformation将图像上传到我们的服务器,并使用gallery chooser选择图像。我试图获取图像的路径,因为uri。getPath()返回未找到的文件作为异常。我几乎看过关于这个主题的每一篇stackoverflow文章,但仍然没有答案。下面的代码与我在网上看到的所有代码都类似,它总是返回null,我不知道为什么。请帮忙