ACTION_IMAGE_CAPTURE - 在默认位置拍照后获取URI

6

我正在拍摄一张如下的图片:

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;
            }
        }
    }
}
1个回答

1

注意: 如果目标是api-24或更高版本,请参见此处

如果目标是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
        }
    }
}

1
我知道这个解决方案...我读到过,预先创建一个新的媒体存储条目并将其传递而不是文件会更可靠...但是,这将导致通过我的应用程序拍摄的所有图像可能存储在与直接通过相机拍摄时不同的位置...这是我默认情况下真正不想要的。我希望图像保存在相机的默认位置。 - prom85
最好的做法是将它们存储在外部存储器的图片目录中,使用 Environment.DIRECTORY_PICTURES。这样它们就可以像所有其他照片一样在相册中查看。 - Daniel Nugent
1
这不是关于可视性的问题...我编辑了我的第一篇帖子并展示了我的备选方案...我希望图像存储在DCIM/CameraDCIM/100Andro或相机使用的任何目录下。我认为我的应用程序用户期望,如果他使用相机1拍摄图像,则图像将保存在相机1的目录中,如果使用相机2,则应将图像保存在相机2的目录中。我不希望直接通过相机或通过我的应用程序打开相机会影响生成的图像路径(名称也是如此,但这是可以接受的)... - prom85
从Android 24+开始,它将失败https://dev59.com/zVoT5IYBdhLWcg3wvRpk - DayDayHappy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接