从Intent.ACTION_GET_CONTENT到文件的URI

时间:2011-12-27 15:22:36

标签: android

  1. 使用Intent.ACTION_GET_CONTENT
  2. 启动照片选择器
  3. 检索所选项目的URI
  4. 检索URI的PATH,以便我可以将其发布到我的网络服务器

    启动浏览的代码

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    startActivityForResult(intent, BROWSE_IMAGE_REQUEST_CODE);
    

    检索所选图片的代码

    if (RESULT_OK == resultCode &&
                 BROWSE_IMAGE_REQUEST_CODE == requestCode) {
    Uri uri = data.getData();
    

    要发送到网络服务器的代码

    File file = new File(uri.getPath());
    new FileSystemResourceFile(file);
    
  5. 我目前能够从URI没有概率/external/images/media/24检索PATH但是由于一些奇怪的原因,文件总是为空,请帮忙吗?

3 个答案:

答案 0 :(得分:19)

我已经使用此方法将UriIntent.ACTION_GET_CONTENT转换为实际路径:

public static String getRealPathFromUri(Activity activity, Uri contentUri) {
    String[] proj = { MediaStore.Images.Media.DATA };
    Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

又转换为File

Uri filePathFromActivity = (Uri) extras.get(Intent.EXTRA_STREAM);
filePathFromActivity = Uri.parse(FileUtil.getRealPathFromUri( (Activity) IntentActivity.this, filePathFromActivity));
File imageFile = new File(filePathFromActivity.getPath());

答案 1 :(得分:0)

我知道答案以来已经有很长的时间了,但是我面对的是同一堵墙,这就是我最终得到的解决方案。这段代码的主要好处是,可以避免在所有不同的android版本中对所有可能的提供程序类型和位置进行参数化(和硬编码)。

    val act = getActivity() as Activity
    object: AsyncTask<Uri, Void, File?>() {
        override fun doInBackground(uris: Array<Uri>): File? {
            if(act.isFinishing()) return null
            try {
                val dir = act.getCacheDir()
                val file = File.createTempFile("PREFIX", "SUFFIX", dir)
                val inputStream = act.getContentResolver().openInputStream(uris[0])
                val fos = FileOutputStream(file)
                BitmapFactory.decodeStream(inputStream)
                        .compress(Bitmap.CompressFormat.JPEG, 90, fos)
                return file
            } catch(e: Exception) { e.printStackTrace() }
            return null
        }
        override fun onPostExecute(result: File?) {
            result?.let { doSomethingWithFile(it) }
        }
    }.execute(uri)

我将其包装在AsyncTask内,目的是在位图压缩期间保留不阻塞的ui线程。请注意,使用Bitmap.CompressFormat.JPEG意味着失去alpha通道。

希望有帮助!

答案 2 :(得分:0)

使用系统文件选择器选择任何文件:

val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
startActivityForResult(intent, 1)

onActivityResult:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
        val file = data?.data?.let {
            getFileFromUri(requireContext().contentResolver, uri, requireContext().cacheDir)
        }
    }
}

获取文件:

private fun getFileFromUri(contentResolver: ContentResolver, uri: Uri, directory: File): File {
    val file =
        File.createTempFile("suffix", "prefix", directory)
    file.outputStream().use {
        contentResolver.openInputStream(uri)?.copyTo(it)
    }

    return file
}