【问题标题】:Camera activity returning null android相机活动返回 null android
【发布时间】:2011-10-22 08:52:26
【问题描述】:

我正在构建一个应用程序,我想通过默认相机活动捕获图像并返回到我的活动并将该图像加载到 ImageView 中。问题是相机活动总是返回空值。在我的onActivityResult(int requestCode, int resultCode, Intent data) 方法中,我以null 获取数据。这是我的代码:

public class CameraCapture extends Activity {

    protected boolean _taken = true;
    File sdImageMainDirectory;
    Uri outputFileUri;

    protected static final String PHOTO_TAKEN = "photo_taken";
    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        try {

            super.onCreate(savedInstanceState);   
            setContentView(R.layout.cameracapturedimage);
                    File root = new File(Environment
                            .getExternalStorageDirectory()
                            + File.separator + "myDir" + File.separator);
                    root.mkdirs();
                    sdImageMainDirectory = new File(root, "myPicName");



                startCameraActivity();

        } catch (Exception e) {
            finish();
            Toast.makeText(this, "Error occured. Please try again later.",
                    Toast.LENGTH_SHORT).show();
        }

    }

    protected void startCameraActivity() {

        outputFileUri = Uri.fromFile(sdImageMainDirectory);

        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        switch (requestCode) {
        case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
        {
            if(resultCode==Activity.RESULT_OK)
            {
                try{
                ImageView imageView=(ImageView)findViewById(R.id.cameraImage);
                imageView.setImageBitmap((Bitmap) data.getExtras().get("data"));
                }
                catch (Exception e) {
                    // TODO: handle exception
                }
            }

            break;
        }

        default:
            break;
        }
    }

     @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) {
            _taken = true;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);
    }
}

我做错了什么吗?

【问题讨论】:

  • SD卡挂载了吗?您在哪里可以看到图像“myPicName”?你有清单中的权限吗?
  • usb调试时可以看到ddms中的文件。我也给予了许可。如果我在图像视图中加载图像时使用 outputFileUri 而不是数据,它可以工作。这意味着相机正在捕捉图像,但为什么我在 onactivityresult() 方法的数据参数中得到空值
  • 注意是否允许访问您的存储。

标签: android android-camera


【解决方案1】:

你做错了,因为你做错了。

如果您将额外参数MediaStore.EXTRA_OUTPUT 与相机意图一起传递,那么相机活动会将捕获的图像写入该路径,并且不会在onActivityResult 方法中返回位图。

如果您检查您所传递的路径,那么您将知道实际上相机已将捕获的文件写入该路径。

如需了解更多信息,您可以关注thisthisthis

【讨论】:

  • 如果您指定要保存到的 URI,Intent 会返回 null 是没有意义的。您应该仍然可以访问Intent 并从中获取照片的 URI,等等。
  • 就像你说的那样,指定一个 URI 会导致缩略图在 OnActivityResult 中变得不可用。但是,如果您的应用同时需要高分辨率和低分辨率,您可以关注this
  • 您可以将额外的参数MediaStore.EXTRA_OUTPUT 与相机意图一起传递,但您必须将fileUri 保存为成员变量,以便以后可以在onActivityResult() 中访问它。
  • 所有这一切都有可怕的记录。 Android 文档示例应用程序不起作用。 developer.android.com/training/camera/photobasics.html 产生与 OP 所说的相同的错误。
  • 这么简单的事情需要这么复杂的动作,这才是android开发中真正糟糕的地方。
【解决方案2】:

我正在以另一种方式进行。 data.getData() 字段不能保证返回 Uri,所以我正在检查它是否为空,如果是,则图像在附加组件中。所以代码是 -

if(data.getData()==null){
    bitmap = (Bitmap)data.getExtras().get("data");
}else{
    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
}

我在生产应用程序中使用此代码,它正在工作。

【讨论】:

  • 如果data 为空,如何调用getData()
  • data 是一个始终不为空的意图。不保证意图对象的 Uri 部分具有非空值。因此,如果 uri 为 null,我们可以从 getExtras() 方法获取位图,如果不是,则使用 Uri 获取文件。
  • 哦,这个“数据”键在我需要 Uri 路径时返回了位图。好的,我可以通过这些代码获得Uri from imagepublic static Uri getImageUri(Context inContext, Bitmap inImage) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes); String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); return Uri.parse(path); }
  • 请注意,使用 data.getExtras().get("data") 您将无法获得完整大小的位图!这将是一个缩略图。在生产应用程序中它似乎很丑......
【解决方案3】:

我遇到了类似的问题。我在清单文件中注释掉了一些导致缩略图数据返回为空的行。

您需要以下内容才能使其工作:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

希望这能解决您的问题

如果你的手机是三星的,可能和这个http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/有关

还有另一个open question 可能会提供更多信息

【讨论】:

  • 我也有同样的问题,我担心这些权限不会改变任何东西。至少对我来说不是,似乎没有解决办法。找了好几天,怎么会这样?无法使用应用程序拍摄单张照片让我感到非常沮丧。
  • @cubsink 是三星吗...?
  • 抱歉@Merlin 回复晚了。但是,是的,它是三星设备。那是一年多以前的事了,我想现在情况已经改变了。
  • @cubsink,只有一年左右;)
  • OP 正在使用相机意图,而不是在他/她自己的应用程序中使用相机硬件。所以这些权限实际上不是必需的。(WRITE_EXTERNAL_STORAGE 可能需要,但不是其他权限)。在 android 文档中提到
【解决方案4】:

如果你使用 ImageView 来显示 Camera Intent 返回的 Bitmap 您需要将 imageview 引用保存在 onSaveInstanceState 中,并稍后在 onRestoreInstanceState 中恢复它。查看下面的 onSaveInstanceState 和 onRestoreInstanceState 代码。

public class MainActivity extends Activity {

    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1;
    String mCurrentPhotoPath;
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        imageView = (ImageView) findViewById(R.id.imageView1);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public void startCamera(View v) throws IOException {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File photoFile = null;

        photoFile = createImageFile();
        //intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
        }

    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE
                && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            System.out.println(imageBitmap);
            imageView.setImageBitmap(imageBitmap);
        }
    }

    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
                .format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(imageFileName, /* prefix */
                ".jpg", /* suffix */
                storageDir /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        System.out.println(mCurrentPhotoPath);
        return image;
    }

    private void setPic() {
        // Get the dimensions of the View
        int targetW = imageView.getWidth();
        int targetH = imageView.getHeight();

        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        imageView.setImageBitmap(bitmap);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
        System.out.println(mCurrentPhotoPath);
        imageView = (ImageView) findViewById(R.id.imageView1);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onRestoreInstanceState(savedInstanceState);
        System.out.println(mCurrentPhotoPath);
        imageView = (ImageView) findViewById(R.id.imageView1);
    }
}

【讨论】:

    【解决方案5】:

    经过多次搜索:

    private static final int TAKE_PHOTO_REQUEST = 1;
    private ImageView mImageView;
    String mCurrentPhotoPath;
    private File photoFile;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_saisir_frais);
        mImageView = (ImageView) findViewById(R.id.imageViewPhoto);
        dispatchTakePictureIntent();
    }
    
    
    
    
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TAKE_PHOTO_REQUEST && resultCode == RESULT_OK) {
    
                // set the dimensions of the image
                int targetW =100;
                int targetH = 100;
    
                // Get the dimensions of the bitmap
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                bmOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(photoFile.getAbsolutePath(), bmOptions);
                int photoW = bmOptions.outWidth;
                int photoH = bmOptions.outHeight;
    
                // Determine how much to scale down the image
                int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
    
                // Decode the image file into a Bitmap sized to fill the View
                bmOptions.inJustDecodeBounds = false;
                bmOptions.inSampleSize = scaleFactor;
                bmOptions.inPurgeable = true;
    
               // stream = getContentResolver().openInputStream(data.getData());
                Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath(),bmOptions);
                mImageView.setImageBitmap(bitmap);
        }
    
    }
    
    
    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
    
        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        return image;
    }
    
    
    private void dispatchTakePictureIntent() {
    
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        try {
            photoFile = createImageFile();
            takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    【讨论】:

    • BitmapFactory.decodeFile(photoFile.getAbsolutePath(), bmOptions);我的 photoFile 参数面临 Null 值,你知道为什么吗?我正在测试 android Api-23,请帮我解决这个问题。
    【解决方案6】:

    试试下面的代码

                {
                    final String[] imageColumns = { MediaStore.Images.Media._ID,MediaStore.Images.Media.DATA };
    
                    final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
                    Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
                    imageCursor.moveToFirst();
                    do {
                        String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                        if (fullPath.contains("DCIM")) {
    
                            //get bitmap from fullpath here.
                            return;
                        }
                    }
                    while (imageCursor.moveToNext());
    

    【讨论】:

      【解决方案7】:

      您可以从发送到相机意图的文件中生成位图。请使用此代码...

      @Override
      
      public void onActivityResult(int requestCode, int resultCode, Intent data){
          switch (requestCode) {
      
          case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
           {
              if(resultCode==Activity.RESULT_OK)
                 {
      
                      int orientation = getOrientationFromExif(sdImageMainDirectory);// get orientation that image taken
      
                      BitmapFactory.Options options = new BitmapFactory.Options();
      
                      InputStream is = null;
                      Matrix m = new Matrix();
                      m.postRotate(orientation);//rotate image
      
                      is = new FileInputStream(sdImageMainDirectory);
      
                      options.inSampleSize = 4 //(original_image_size/4);
                      Bitmap bitmap = BitmapFactory.decodeStream(is,null,options);
                      bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                              bitmap.getHeight(), m, true);
      
                       // set bitmap to image view    
      
                       //bitmap.recycle();    
                 }
      
              break;
          }
      
          default:
              break;
          }
      
      }
      
      private int getOrientationFromExif(String imagePath) {
              int orientation = -1;
              try {
                  ExifInterface exif = new ExifInterface(imagePath);
                  int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
                          ExifInterface.ORIENTATION_NORMAL);
      
                  switch (exifOrientation) {
                      case ExifInterface.ORIENTATION_ROTATE_270:
                          orientation = 270;
                          break;
                      case ExifInterface.ORIENTATION_ROTATE_180:
                          orientation = 180;
                          break;
                      case ExifInterface.ORIENTATION_ROTATE_90:
                          orientation = 90;
                          break;
                      case ExifInterface.ORIENTATION_NORMAL:
                          orientation = 0;
                          break;
                      default:
                          break;
                  }
              } catch (IOException e) {
                  //Log.e(LOG_TAG, "Unable to get image exif orientation", e);
              }
              return orientation;
          }
      

      【讨论】:

        【解决方案8】:
        File cameraFile = null;
        
        public void openChooser() {
            Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        
            Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            cameraFile = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
            takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
        
            String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
            Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,new Intent[]{takePhotoIntent});
            startActivityForResult(chooserIntent, SELECT_PHOTO);
        }
        
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            switch (requestCode) {
                case SELECT_PHOTO:
                    if (resultCode == Activity.RESULT_OK) {
                        Uri selectedImage = data.getData();
                        if (selectedImage != null) {
                            //from gallery 
                        } else if (cameraFile != null) {
                            //from camera
                            Uri cameraPictureUri = Uri.fromFile(cameraFile);
                        }
                    }
                    break;
            }
        }
        

        【讨论】:

          【解决方案9】:

          试试这个教程。它对我有用,并且在宣言中照常使用许可 检查权限

          https://androidkennel.org/android-camera-access-tutorial/

          【讨论】:

            【解决方案10】:

            经过大量的深入研究,我终于得出了一个结论。 为此,您应该将捕获的图像保存到外部存储中。 然后,在上传时检索。 这样图像资源不会降级,您也不会得到 NullPointerException! 我已经使用时间戳来命名文件,所以我们每次都会得到一个唯一的文件名。

             private void fileChooser2() {
                    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
                    StrictMode.setVmPolicy(builder.build());
                Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                String pictureName=getPictureName();
                fi=pictureName;
                File imageFile=new File(pictureDirectory,pictureName);
                Uri pictureUri = Uri.fromFile(imageFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri);
                startActivityForResult(intent,PICK_IMAGE_REQUEST2);
            }
            

            创建文件名的功能:

            private String getPictureName() {
                SimpleDateFormat adf=new SimpleDateFormat("yyyyMMdd_HHmmss");
                String timestamp = adf.format(new Date());
                return "The New image"+timestamp+".jpg";//give a unique string so that the imagename cant be overlapped with other apps'image formats
            }
            

            和onActivityResult:

            @Override
                protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                    super.onActivityResult(requestCode, resultCode, data);
                     
                    if(requestCode==PICK_IMAGE_REQUEST2 && resultCode==RESULT_OK )//&& data!=null && data.getData()!=null)
                    {
                        final ProgressDialog progressDialog = new ProgressDialog(this);
                        progressDialog.setTitle("Uploading");
                        progressDialog.show();
                        Toast.makeText(getApplicationContext(),"2",Toast.LENGTH_SHORT).show();
                            File picDir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                        File imageFile=new File(picDir.getAbsoluteFile(),fi);
                        filePath=Uri.fromFile(imageFile);
                        try {
                        }catch (Exception e)
                        {
                            e.printStackTrace();
                        }
            
            
            
                        StorageReference riversRef = storageReference.child(mAuth.getCurrentUser().getUid()+"/2");
                        riversRef.putFile(filePath)
                                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                                    @Override
                                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                        progressDialog.dismiss();
                                        Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();
                                    }
                                })
                                .addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception exception) {
                                        progressDialog.dismiss();
                                        Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
                                    }
                                })
                                .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                                    @Override
                                    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                                        double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                                        progressDialog.setMessage("Uploaded " + ((int) progress) + "%...");
                                    }
                                });
            

            编辑:授予相机权限以及从清单中的存储空间写入和读取。

            【讨论】:

              【解决方案11】:

              从相机拍摄时,很少有手机会返回 null。以下解决方法将解决。确保检查数据为空:

                        private int  CAMERA_NEW = 2;
                        private String imgPath;
              
                        private void takePhotoFromCamera() {
                             Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                             intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
                             startActivityForResult(intent, CAMERA_NEW);
                        }
              
                       // to get the file path 
                       private  Uri setImageUri() {
                         // Store image in dcim
                            File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".png");
                            Uri imgUri = Uri.fromFile(file);
                            this.imgPath = file.getAbsolutePath();
                            return imgUri;
                         }
                        
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, Intent data) 
                        {
                               super.onActivityResult(requestCode, resultCode, data);
                          if (requestCode == CAMERA_NEW) {
              
                            try {
                               Log.i("Crash","CAMERA_NEW");
                               if(data!=null &&(Bitmap) data.getExtras().get("data")!=null){
                                   bitmap = (Bitmap) data.getExtras().get("data");
                                   personImage.setImageBitmap(bitmap);
                                   Utils.saveImage(bitmap, getActivity());
                                             
                               }else{
                                     File f= new File(imgPath);
                                     BitmapFactory.Options options = new BitmapFactory.Options();
                                     options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                                     options.inSampleSize= 4;
                                     bitmap = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
                                     personImage.setImageBitmap(bitmap);
                                            
                                  }
                              } catch (Exception e) {
                              e.printStackTrace();
                              Toast.makeText(getActivity(), "Failed!", Toast.LENGTH_SHORT).show();
                           }
                    }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-11-06
                • 1970-01-01
                • 2012-06-09
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多