Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/206.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在android中从文件路径获取内容uri_Android_Image - Fatal编程技术网

在android中从文件路径获取内容uri

在android中从文件路径获取内容uri,android,image,Android,Image,我知道图像的绝对路径(例如,/sdcard/cats.jpg)。有没有办法获取此文件的内容uri 实际上,在我的代码中,我下载了一个图像并将其保存在特定的位置。为了在ImageView实例中设置图像,目前我使用路径打开文件,获取字节并创建位图,然后在ImageView实例中设置位图。这是一个非常缓慢的过程,相反,如果我可以获取内容uri,那么我可以非常轻松地使用方法imageView.setImageUri(uri)尝试: ImageView.setImageURI(Uri.fromFile(n

我知道图像的绝对路径(例如,/sdcard/cats.jpg)。有没有办法获取此文件的内容uri

实际上,在我的代码中,我下载了一个图像并将其保存在特定的位置。为了在ImageView实例中设置图像,目前我使用路径打开文件,获取字节并创建位图,然后在ImageView实例中设置位图。这是一个非常缓慢的过程,相反,如果我可以获取内容uri,那么我可以非常轻松地使用方法
imageView.setImageUri(uri)
尝试:

ImageView.setImageURI(Uri.fromFile(new File("/sdcard/cats.jpg")));
或与:

ImageView.setImageURI(Uri.parse(new File("/sdcard/cats.jpg").toString()));

//此代码适用于2.2上的图像,不确定是否有任何其他媒体类型

   //Your file path - Example here is "/sdcard/cats.jpg"
   final String filePathThis = imagePaths.get(position).toString();

   MediaScannerConnectionClient mediaScannerClient = new
   MediaScannerConnectionClient() {
    private MediaScannerConnection msc = null;
    {
        msc = new MediaScannerConnection(getApplicationContext(), this);
        msc.connect();
    }

    public void onMediaScannerConnected(){
        msc.scanFile(filePathThis, null);
    }


    public void onScanCompleted(String path, Uri uri) {
        //This is where you get your content uri
            Log.d(TAG, uri.toString());
        msc.disconnect();
    }
   };

对于您的目的来说,公认的解决方案可能是最佳选择,但要真正回答主题行中的问题:

在我的应用程序中,我必须从URI获取路径,并从路径获取URI。前者:

/**
 * Gets the corresponding path to a file from the given content:// URI
 * @param selectedVideoUri The content:// URI to find the file path from
 * @param contentResolver The content resolver to use to perform the query.
 * @return the file path as a string
 */
private String getFilePathFromContentUri(Uri selectedVideoUri,
        ContentResolver contentResolver) {
    String filePath;
    String[] filePathColumn = {MediaColumns.DATA};

    Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    filePath = cursor.getString(columnIndex);
    cursor.close();
    return filePath;
}
后者(我用于视频,但也可以用于音频、文件或其他类型的存储内容,方法是用MediaStore.Audio(etc)代替MediaStore.Video):


基本上,
MediaStore
DATA
列(或您正在查询的子部分)存储了文件路径,因此您可以使用该信息进行查找。

更新

这里假设您的媒体(图像/视频)已添加到内容媒体提供商。如果没有,那么您将无法获得 内容URL完全符合您的要求。取而代之的是文件Uri

我的文件浏览器活动也有同样的问题。您应该知道,文件的contenturi只支持mediastore数据,如图像、音频和视频。我给你的代码,获取图像内容uri从SD卡选择图像。试试这个代码,也许对你有用

public static Uri getImageContentUri(Context context, File imageFile) {
  String filePath = imageFile.getAbsolutePath();
  Cursor cursor = context.getContentResolver().query(
      MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
      new String[] { MediaStore.Images.Media._ID },
      MediaStore.Images.Media.DATA + "=? ",
      new String[] { filePath }, null);
  if (cursor != null && cursor.moveToFirst()) {
    int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
    cursor.close();
    return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id);
  } else {
    if (imageFile.exists()) {
      ContentValues values = new ContentValues();
      values.put(MediaStore.Images.Media.DATA, filePath);
      return context.getContentResolver().insert(
          MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    } else {
      return null;
    }
  }
}
支持android Q

public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        new String[]{MediaStore.Images.Media._ID},
        MediaStore.Images.Media.DATA + "=? ",
        new String[]{filePath}, null);
if (cursor != null && cursor.moveToFirst()) {
    int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
    cursor.close();
    return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id);
} else {
    if (imageFile.exists()) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ContentResolver resolver = context.getContentResolver();
            Uri picCollection = MediaStore.Images.Media
                    .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
            ContentValues picDetail = new ContentValues();
            picDetail.put(MediaStore.Images.Media.DISPLAY_NAME, imageFile.getName());
            picDetail.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
            picDetail.put(MediaStore.Images.Media.RELATIVE_PATH,"DCIM/" + UUID.randomUUID().toString());
            picDetail.put(MediaStore.Images.Media.IS_PENDING,1);
            Uri finaluri = resolver.insert(picCollection, picDetail);
            picDetail.clear();
            picDetail.put(MediaStore.Images.Media.IS_PENDING, 0);
            resolver.update(picCollection, picDetail, null, null);
            return finaluri;
        }else {
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.DATA, filePath);
            return context.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        }

    } else {
        return null;
    }
  }
}

仅使用adb shell CLI命令,无需编写任何代码即可获取文件ID:

adb shell content query --uri "content://media/external/video/media" | grep FILE_NAME | grep -Eo " _id=([0-9]+)," | grep -Eo "[0-9]+"

你可以试试下面的代码片段

    public Uri getUri(ContentResolver cr, String path){
    Uri mediaUri = MediaStore.Files.getContentUri(VOLUME_NAME);
    Cursor ca = cr.query(mediaUri, new String[] { MediaStore.MediaColumns._ID }, MediaStore.MediaColumns.DATA + "=?", new String[] {path}, null);
    if (ca != null && ca.moveToFirst()) {
        int id = ca.getInt(ca.getColumnIndex(MediaStore.MediaColumns._ID));
        ca.close();
        return  MediaStore.Files.getContentUri(VOLUME_NAME,id);
    }
    if(ca != null) {
        ca.close();
    }
    return null;
}

从文件创建内容Uri
Content://
的最简单、最可靠的方法是使用。FileProvider提供的Uri也可以用于提供与其他应用程序共享文件的Uri。要从
File
的绝对路径获取文件Uri,可以使用DocumentFile.fromFile(新文件(路径、名称)),它添加到Api 22中,并在下面的版本中返回null

File imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = FileProvider.getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);

您可以根据使用情况使用这两种方法

Uri=Uri.parse(“字符串文件位置”)

Uri=Uri.fromFile(新文件(“字符串文件位置”)


我已经尝试了两种方法,两种方法都有效。

已经很晚了,但将来可能会帮助别人

要获取文件的内容URI,可以使用以下方法:

FileProvider.getUriForFile(上下文、字符串权限、文件文件)

它返回内容URI


最好使用验证来支持Android N之前的版本,例如:

  if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
     imageUri = Uri.parse(filepath);
  } else{
     imageUri = Uri.fromFile(new File(filepath));
  }


谢谢!第二种方法适用于1.6、2.1和2.2,但第一种方法仅适用于2.2。这两种方法中的任何一种都会将文件路径解析为内容URI。我知道它解决了眼前的问题。不要硬编码“/sdcard/”;使用Environment.getExternalStorageDirectory().getPath()代替上述两种解决方案返回的结果:1。file:///storage/emulated/0/DCIM/Camera/VID_20140312_171146.mp4 2. /存储/模拟/0/DCIM/Camera/VID_20140312_171146.mp4但我要找的是不同的东西。我需要内容://格式URI。Jinal的答案似乎很好。fromFile
在android 26+上不起作用,你应该使用file Provider,帮助我分享到Google+,因为该应用程序需要一个带有内容Uri的媒体流——绝对路径不起作用。太好了!我可以确认这也适用于音频媒体类型。Uri=Uri.parse(“file:///sdcard/img.png");+1对于注释,只需Uri.parse(“文件:/”+filePath)就可以执行trickUri.parse被折旧和“待添加”@pollaris Uri.parse被添加到API 1中,并且没有标记为deprecation.Uri.parse(“某物”);在我身上不起作用,我找不到原因…我正在寻找一种方法来查找我录制的视频文件的content://URI,上面的代码在Nexus 4(Android 4.3)上似乎工作得很好。如果您能解释一下代码,那就太好了。我已经尝试了这个方法来获取绝对路径为“/sdcard/Image-Depo/picture.png”的文件的内容Uri。它不起作用,所以我调试了代码路径,发现游标是空的,当条目被添加到ContentProvider时,它将null作为内容Uri。请帮忙。我有文件路径-file:///storage/emulated/0/Android/data/com.packagename/files/out.mp4,但当我尝试获取contentUri时,将获取null。我还尝试将
MediaStore.Images.Media
更改为
MediaStore.Video.Media
,但仍然没有成功。这在android Pie api 28上不起作用。游标返回Null由于Android 10中无法访问数据列,您能否为Android 10更新此方法?谷歌“adb从内容uri获取真实路径”,此问题位于前1位,搜索结果摘要中包含您的0票答案内容。所以让我第一个投票。谢谢你,兄弟!这很酷。但您似乎会得到:
权限拒绝:在调用getContentProviderExternal()时没有权限,pid=15660,uid=10113需要android.Permission.ACCESS\u CONTENT\u PROVIDERS\u external
,除非您是根用户。所以这不需要根用户访问phone?并非总是这样,返回两个半保证列,这就是
OpenableColumns.DISPLAY\u NAME&OpenableColumns.SIZE
如果发送应用程序甚至遵循“规则”。我发现一些主要的应用程序只返回这两个字段,并不总是返回
\u data
字段。如果没有通常包含内容直接路径的数据字段,则必须首先读取内容并将其写入文件或内存,然后
  if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
     imageUri = Uri.parse(filepath);
  } else{
     imageUri = Uri.fromFile(new File(filepath));
  }
  if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
     ImageView.setImageURI(Uri.parse(new File("/sdcard/cats.jpg").toString()));         
  } else{
     ImageView.setImageURI(Uri.fromFile(new File("/sdcard/cats.jpg")));
  }