【问题标题】:MediaStore.Images.Media.insertImage is returning null when trying to get image uriMediaStore.Images.Media.insertImage 在尝试获取图像 uri 时返回 null
【发布时间】:2018-12-24 12:21:40
【问题描述】:

我需要从图像位图中获取uri所以我使用这个方法来获取uri

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    fixMediaDir();
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

MediaStore.Images.Media.insertImage 在某些设备中返回 null

注意:我已向清单添加权限

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

并为相机和存储添加了运行时权限

我还在清单中添加了FileProvider

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.mvc.imagepicker.provider"
        android:exported="false"
        android:grantUriPermissions="true"
        tools:replace="android:authorities">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"
            tools:replace="android:resource"/>
    </provider>

注意,提供者的权限是 "com.mvc.imagepicker.provider",因为我使用 Mariovc/ImagePicker 并使用与他相同的权限。

我在其他帖子中看到,有人提到在调用之前添加此代码

MediaStore.Images.Media.insertImage

public void fixMediaDir() {
    File sdcard = Environment.getExternalStorageDirectory();
    Log.d("a111", "sdcard: "+sdcard);
    if (sdcard != null) {
        File mediaDir = new File(sdcard, "DCIM/Camera");
        if (!mediaDir.exists()) {
            mediaDir.mkdirs();
        }
    }
}

所以如果不存在,它会创建一个目录,但它没有帮助我。

所以我在这里发布这个也许我错过了其他东西,有人可以帮助我。

【问题讨论】:

  • 请使用FileProvider
  • 我忘了提,但我在清单中添加了文件提供程序
  • 好吧,那么也许使用FileProvider,而不是insertImage()
  • 我正在使用 ImagePicker,它返回一个 bitmp 图像,我正在尝试从位图中获取 uri。但正如我所说,我从 getImageUri 方法中得到了一个异常。 @CommonsWare 你能告诉我如何使用 FileProvider 而不是 insertImage 来获取图像 uri 吗?
  • 将位图写入文件。使用FileProvider 提供文件。使用FileProvider.getUriForFile()Uri 交给其他应用程序。

标签: java android image uri


【解决方案1】:

由于您说它在某些设备中返回 null,我认为这是因为未提供权限。在清单中设置权限仅指定所需的权限。由设备或操作系统授予它们。在某些操作系统中默认不提供WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE。试试这个:

private final String[] permissions = new String[]{Manifest.permission.CAMERA, 
                                                Manifest.permission.READ_EXTERNAL_STORAGE, 
                                                Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static final int REQUEST_CODE = 12345; //Some random number


...
...

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...

    if (ActivityCompat.checkSelfPermission(SplashScreenActivity.this, permissions[0]) != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(SplashScreenActivity.this, permissions[1]) != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(SplashScreenActivity.this, permissions[2]) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(SplashScreenActivity.this, permissions, REQUEST_CODE);
    }

    ...
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_CODE) {
        if (grantResults.length == 3 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED && grantResults[2] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(SplashScreenActivity.this, "Permission granted!!!", Toast.LENGTH_LONG).show();
        }
        else {
            Toast.makeText(SplashScreenActivity.this, "Necessary permissions not granted...", Toast.LENGTH_LONG).show();
            finish();
        }
    }
}

将此添加到您应用中的第一个活动中。如果尚未提供权限,这将要求用户授予权限。

【讨论】:

  • 我说我也添加了运行时权限。运行时权限不是我的问题。
  • 我的错,在检查存储权限后,我发现我缺少提供 WRITE_EXTERNAL_STORAGE。所以在授予 WRITE_EXTERNAL_STORAGE 之后它起作用了。
  • 已经有 但还是不行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 2022-01-01
相关资源
最近更新 更多