【问题标题】:Convert file uri to content uri将文件 uri 转换为内容 uri
【发布时间】:2011-11-10 10:54:38
【问题描述】:

我想从 astro 管理器(在我的例子中是 *.pdf 或 *.doc)中选择一个文件(通过文件选择器),但 uri 只包含文件路径("sdcard/my_folder/test.pdf")。对于我的应用程序,我需要来自图像选择器的内容路径(content://media/external/images/media/2 )。有没有办法将"file:///" 转换为"content://" uri?

或者有其他人知道如何解决这个问题吗?

最好的问候

更新:主要问题是在我使用 filechooser valuecallback.onReceiveValue(uri) 方法选择我的文件后,在路径后面添加了一个“/”。所以我得到一个这样的uri:“sdcard/my_folder/test.pdf/”,我的应用程序认为pdf是一个文件夹。当我使用图像选择器中的内容 uri 时,它可以工作。

【问题讨论】:

  • sdcard/my_folder/test.pdf 这是从移动设备中的 sdcard 读取数据的正确 url

标签: android


【解决方案1】:

就像@CommmonsWare 所说,没有简单的方法可以将任何类型的文件转换为 content:// 。
但这是我将图像文件转换为内容的方法://

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));
        Uri baseUri = Uri.parse("content://media/external/images/media");
        return Uri.withAppendedPath(baseUri, "" + 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;
        }
    }
}

【讨论】:

  • 我试过这个 - file:///storage/emulated/0/Android/data/com.pkg_name/files/out.mp4,但它返回 null。我也尝试将MediaStore.Images.Media 更改为MediaStore.Video.Media,但仍然没有运气
  • 谢谢,这是唯一适用于我的 Android-N 设备的解决方案。我的应用面向 API 24。
  • @Ben Lee 当我尝试在位图中解码此图像时,它返回 null。
  • 这项工作!在哪里可以了解有关 Android 光标和 .query() 的更多信息?你是怎么学的?我在 Android 文档中找不到它。
【解决方案2】:

这里有一个更简单的方法可以考虑,它可能适合你。

我用它来分享从我的 android 应用下载到 google plus 上的图片:

/**
 * Converts a file to a content uri, by inserting it into the media store.
 * Requires this permission: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 */
protected static Uri convertFileToContentUri(Context context, File file) throws Exception {

    //Uri localImageUri = Uri.fromFile(localImageFile); // Not suitable as it's not a content Uri

    ContentResolver cr = context.getContentResolver();
    String imagePath = file.getAbsolutePath();
    String imageName = null;
    String imageDescription = null;
    String uriString = MediaStore.Images.Media.insertImage(cr, imagePath, imageName, imageDescription);
    return Uri.parse(uriString);
}

【讨论】:

    【解决方案3】:

    实现此目的的一种简单方法是使用 MediaScannerConnection

    File file = new File("pathname");
    MediaScannerConnection.scanFile(getContext(), new String[]{file.getAbsolutePath()}, null /*mimeTypes*/, new MediaScannerConnection.OnScanCompletedListener() {
                @Override
                public void onScanCompleted(String s, Uri uri) {
                    // uri is in format content://...
                }
            });
    

    【讨论】:

      【解决方案4】:

      这适用于我以及我在共享文件夹应用中使用的内容:

      1. 在resources下创建一个名为xml的文件夹

      2. 向其中添加一个 file_paths.xml,其中包含以下行:

      <files-path name="internal" path="/"/>
      
      1. 在清单中添加文件提供者权限,如下:
      <provider android:name="android.support.v4.content.FileProvider"
                     android:authorities="com.dasmic.filebrowser.FileProvider"
                     android:windowSoftInputMode="stateHidden|adjustResize"
                     android:exported="false"
                     android:grantUriPermissions="true">
                     <meta-data
                          android:name="android.support.FILE_PROVIDER_PATHS"
                          android:resource="@xml/file_paths" />
      </provider>
      

      4. 使用 'content://' 将文件传输到不同的意图,如下所示:

      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //Required for Android 8+
      Uri data = FileProvider.getUriForFile(this, "com.dasmic.filebrowser.FileProvider", file);
      intent.setDataAndType(data, type);
      startActivity(intent);
      

      【讨论】:

      • 什么是 com.dasmic.filebrowser.FileProvider?代码在哪里?
      【解决方案5】:

      你可以使用 FileProvider 来实现它

      第 1 步: 创建一个java 文件和extends 它与FileProvider

      public class MyFileProvider extends FileProvider {
      
      }
      

      第 2 步:res/xml/目录下创建一个xml资源文件并将这段代码复制进去

      <?xml version="1.0" encoding="utf-8"?>
      <paths xmlns:android="http://schemas.android.com/apk/res/android">
          <external-path name="external_files" path="."/>
      </paths>
      

      第 3 步: 在您的manifest 文件中,在&lt;Application&gt; 标签下添加此代码

      <provider
                  android:name="MyFileProvider" <!-- java file created above -->
                  android:authorities="${applicationId}.MyFileProvider"
                  android:exported="false"
                  android:grantUriPermissions="true">
                  <meta-data
                      android:name="android.support.FILE_PROVIDER_PATHS"
                      android:resource="@xml/provider_paths"/> <!-- xml file created above -->
              </provider>
      

      第 4 步: 使用此代码以content:// 格式获取Uri

      Uri uri = FileProvider.getUriForFile(CameraActivity.this, "your.package.name.MyFileProvider", file /* file whose Uri is required */);
      

      注意: 您可能需要添加读取权限

      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      

      【讨论】:

        【解决方案6】:

        试试这个:

        Uri myUri = Uri.fromFile(new File("/sdcard/cats.jpg"));
        
        

        或与:

        
        Uri myUri = Uri.parse(new File("/sdcard/cats.jpg").toString());
        

        【讨论】:

          猜你喜欢
          • 2014-08-13
          • 1970-01-01
          • 2023-04-06
          • 1970-01-01
          • 2014-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-06
          相关资源
          最近更新 更多