【问题标题】:Android camera photo comes back nullAndroid 相机照片返回 null
【发布时间】:2015-12-06 16:02:42
【问题描述】:

在我的 android 应用程序中,我使用了一个有时有效有时无效的相机活动。即使相机图片存储在手机上的图片目录中,大约 30% 的 uri 设置用于存储照片的时间都返回空值。下面是我的开始活动。

  Uri imageUri;       // These are defined at the global level
  Uri selectedImage;
     ...............
  String fileName = name.replace(" ", "");
            fileName = fileName + suffix + ".jpg";
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.TITLE, fileName);
            values.put(MediaStore.Images.Media.DESCRIPTION, "Image capture by camera");
                 imageUri = getContentResolver().insert(
                 MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
             Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

            if (intent.resolveActivity(getPackageManager()) != null) {
                 startActivityForResult(intent, RESULT_LOAD_IMAGE);
            }
            else
                Toast.makeText(getApplicationContext(), "Photo was not taken", Toast.LENGTH_SHORT).show();

下面是我的结果活动。

   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        Bitmap image1;
        if(requestCode == RESULT_CROP_IMAGE)
        {
            Bundle extras = data.getExtras();
             image1 = extras.getParcelable("data");
        }
        else {
            if (requestCode == RESULT_LOAD_IMAGE) {
               selectedImage = imageUri;   // returns null occassionally
          } else
                  selectedImage = data.getData();
        if(selectedImage == null)
            {
                Toast.makeText(getApplicationContext(), "Photo not captured correctly", Toast.LENGTH_LONG).show();
                return;
            }

问题是变量 imageUri 偶尔会返回 null 每个人,即使图片是拍摄的并且驻留在三星 S4 手机图片目录中。谁能解释为什么会发生这种情况以及如何解决?如果返回空值,还有其他方法可以捕获照片吗?我应该补充一下,我使用的是 Android SDK 版本 23。我以前没有遇到过这个问题。

我有更多关于这个问题的信息。我在 startactivity 中设置我的图像路径如下:

           String mCurrentPhotoPath;  // is stored at the global level
           .....
           String fileName = name.replace(" ", "");
            fileName = fileName + suffix + ".jpg";
            mCurrentPhotoPath = fileName;
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.TITLE, mCurrentPhotoPath);
            values.put(MediaStore.Images.Media.DESCRIPTION, "Image capture by camera");
                 imageUri = getContentResolver().insert(
                 MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

在我的结果活动中,mCurrentPhotoPath 为空。是什么原因导致这件事被淘汰?我没有在任何其他会导致它变为 null 的地方引用 mCurrentPhotoPath。

     if (requestCode == RESULT_LOAD_IMAGE) {
         if(imageUri != null)
             selectedImage = imageUri;
          else
          {
           if(mCurrentPhotoPath != null) {   // mCurrentPhotoPath returns null;
               File file = new File(Environment.getExternalStorageDirectory().getPath(), mCurrentPhotoPath);
                        selectedImage = Uri.fromFile(file);
                    }
                    else {
                        Toast.makeText(getApplicationContext(), "Photo not captured", Toast.LENGTH_LONG).show();
                        return;
                    }
                }

谁能解释为什么当我没有在除了开始活动和结果活动之外的任何其他地方引用它时,mCurrentPath 返回一个空值?

【问题讨论】:

    标签: android android-camera-intent


    【解决方案1】:

    谁能解释为什么会发生这种情况

    ACTION_IMAGE_CAPTURE 不返回Uri,根据the documentationdata.getData(),在您的代码中,应始终为 null。如果不是null,那么Uri 的含义是无证的。

    如何解决?

    您已经知道Uri 是什么。你把它放在EXTRA_OUTPUT。用那个。

    我以前没遇到过这个问题。

    是的,你做到了。有数千种 Android 设备型号。这些内置了数十个(如果不是数百个)相机应用程序。还有数十个(如果不是数百个)额外的支持ACTION_IMAGE_CAPTURE 的应用程序可供下载,从 Play 商店等地方下载。他们都不必返回Uri,因为文档没有说他们必须返回Uri(即使那样,相机应用程序中也存在错误)。

    【讨论】:

    • 我正在使用我放在 EXTRA_OUTPUT 中的 Uri。它是 imageUri,这就是 null。
    • @Dave:你需要坚持Uri。据推测,当您的应用程序处于后台时,您的进程正在终止,并且您没有将 Uri 保存为此活动或片段的已保存实例状态 Bundle。因此,新流程和新活动实例缺少Uri。将此Uri 添加到已保存的实例状态Bundle (onSaveInstanceState())。
    • 感谢您的反馈。这是有道理的,因为我的最新更新显示我的全球价值观正在被抹去。我不是一个真正有经验的 Android 人,但我会看看如何保存 Uri。
    • @Dave:“这是有道理的,因为我的最新更新显示我的全球价值观正在被抹去”——是的,您的流程已终止。当您从某些相机应用程序中看到这一点时,问题更大,因为当您不在前台时,您的进程可以随时终止。它仅在某些时候发生的原因是基于环境因素(可用系统 RAM 的数量、相机应用程序在前台运行多长时间、相机应用程序使用多少系统 RAM、Android 操作系统版本、月相、梅西今天是否进球等)。
    • 啊哈!我刚刚了解到旋转相机会破坏实例状态。这就是为什么我的 Uri 不见了!真是一个启示。
    【解决方案2】:

    感谢 CommonsWare,我通过实现 onSaveInstance 状态解决了这个问题。这应该是任何 android 相机文档中的必需信息,因为每当您更改相机的方向时,您都会丢失全局变量。

           @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save the user's current game state
        savedInstanceState.putParcelable("myURI", imageUri);
        // Always call the superclass so it can save the view hierarchy state
        super.onSaveInstanceState(savedInstanceState);
    }
    
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Always call the superclass so it can restore the view hierarchy
        super.onRestoreInstanceState(savedInstanceState);
        // Restore state members from saved instance
       imageUri = savedInstanceState.getParcelable("myURI");
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多