当前位置: 首页 > 知识库问答 >
问题:

在Android 10上从URI获取真实的文件路径,此外,在Android 10中,URI的内容后缀为msf: docentid

邹齐智
2023-03-14

我试图从Xamarin Android中的intent chooser获得真正的路径,它在除Android 10之外的所有Android版本中都能正常工作。在Android10中,内容uri如下

content://com.android.providers.downloads.documents/document/msf:180

共有3个答案

林玮
2023-03-14

您可以查询文件名,然后构建路径。

>

  • 查询文件名:

      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;
    

  • 郑俊材
    2023-03-14

    在得到图像文件的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更大或相等,使用我的方法,否则使用你的旧方法。

    宗政霄
    2023-03-14

    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,我不知道为什么。请帮忙