【问题标题】:ACTION_IMAGE_CAPTURE - get URI after taking a photo at the default locationACTION_IMAGE_CAPTURE - 在默认位置拍照后获取 URI
【发布时间】:2026-02-13 22:30:02
【问题描述】:

我正在拍一张像下面这样的照片:

activity.startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), BaseDef.REQUEST_CODE_CAMERA);

之后,我只想获取新的图像路径,uri 或类似的(不是位图或图像数据),以便我知道新图像的位置。因此,我尝试检索 uri,如下所示:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == BaseDef.REQUEST_CODE_CAMERA)
    {
        if (resultCode == RESULT_OK)
        {
            Uri uri = data.getData();
        }
    }
}

但有时 uri 是 null。如何在此类设备上获取图像路径/uri?

编辑

我真的很想保留使用哪个相机应用程序创建的默认文件名!

当前的解决方法(我不知道这是否总是有效):

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == BaseDef.REQUEST_CODE_CAMERA)
    {
        if (resultCode == RESULT_OK)
        {
            String path = null;
            Uri uri = data.getData();
            if (uri != null)
                path = MediaUtil.getRealPathFromURI(uri);
            else
            {
                L.d(this, "URI == NULL => trying to get last image path directly");
                // here I just sort mediastore by id desc and get the first image's path
                // can I be sure this ALWAYS works? 
                // When the camera returns, the image SHOULD be already in the media store
                // If not, I would get a wrong image...
                path = MediaStoreUtil.getLastImagePath(); 
            }

            if (path == null)
            {
                L.d(this, "Path of camera image could not be retrieved");
                return;
            }
        }
    }
}

【问题讨论】:

    标签: android image camera uri


    【解决方案1】:

    注意:针对 api-24 或更高版本,see here

    针对 api-23 或更低版本:

    最好的方法是发送带有用于打开相机的 Intent 的 Uri。 您需要创建一个临时文件,该文件将被拍摄的照片覆盖。

    首先,声明一个成员变量来存储Uri:

    public class MyPhotoActivity extends AppCompatActivity {
    
        Uri uri;
        //.............
    

    设置临时文件并将 Uri 传递给相机应用:

    public void takePhoto() {
      counter++; //this is an int
      String imageFileName = "JPEG_" + counter; //make a better file name
      File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
      File image = File.createTempFile(imageFileName, 
                                       ".jpg", 
                                       storageDir
                                      );
    
      uri = Uri.fromFile(image);
      Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
      startActivityForResult(takePhotoIntent, BaseDef.REQUEST_CODE_CAMERA);
    }
    

    然后,如果您在 onActivityResult() 中获得成功结果,则创建的临时文件具有捕获的图像,您可以使用uri 来满足您的任何需求:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode == BaseDef.REQUEST_CODE_CAMERA)
        {
            if (resultCode == RESULT_OK)
            {
                //use uri member variable...
                //it has the image that was captured
            }
        }
    }
    

    【讨论】:

    • 我知道这个解决方案......我读到,预先创建一个新的媒体存储条目并提交它而不是文件更加可靠......不过,这将导致所有图像通过我的应用程序拍摄的内容可能会存储在与直接通过相机拍摄的位置不同的位置……这是默认情况下真正不想要的。我希望将图像保存在相机的默认位置
    • @prom85 最好的办法是使用Environment.DIRECTORY_PICTURES 将它们存储在外部存储的图片目录中。这样它们就可以像所有其他照片一样在图库中查看。
    • 这与可视性无关...我编辑了我的第一篇文章并展示了我的替代解决方案...我希望将图像存储在DCIM/CameraDCIM/100Andro 或相机使用的任何目录下。我认为我的应用程序的用户期望如果他使用相机 1 拍摄图像,则图像将保存在相机 1 的目录中,如果使用相机 2,则图像应保存在相机 2 的目录中。我不希望直接或通过我的应用打开相机会影响生成图像的路径(也不是名称,但这是可以接受的)......
    • 启动android 24+,会失败*.com/questions/38200282/…