onActivityResult返回Intent data.getData();永远只有在棉花糖和棒棒糖

时间:2016-09-20 13:48:45

标签: android camera android-camera-intent onactivityresult

阅读我的整个代码。除了MarshmallowLollipop之外,它在每部手机上都能正常运行。在MarshmallowLollipop手机中data.getData()仅在图片捕获的情况下返回null时出现问题。如果我捕获视频,它工作正常。我有4个案例 -

  1. 从图库中选择图片并在Imageview中显示其缩略图 - 工作正常。

  2. 从相机中捕捉图片,并在ImageviewMarshmallowLollipop中的Imageview - 不工作中显示其缩略图。

  3. 从图库中选择视频并在Imageview中显示缩略图 - 工作正常。

  4. 3.从相机拍摄视频并在 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); int THUMBSIZE = 120; switch (requestCode){ case RESULT_LOAD_IMAGE: if (resultCode==RESULT_OK){ String column_Name= MediaStore.Images.Media.DATA; String picturePath=getPath(column_Name,data.getData()); Bitmap orientedBitmap = ExifUtil.rotateBitmap(picturePath, BitmapFactory.decodeFile(picturePath)); Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.extractThumbnail(orientedBitmap, THUMBSIZE, THUMBSIZE)); thumbnailview.setBackground(fullpic); editText.setText(picturePath); picker.setVisibility(View.VISIBLE); thumbnailview.setClickable(false); } break; case REQUEST_IMAGE_CAPTURE: if (resultCode==RESULT_OK){ String picturePath=""; String column_Name=MediaStore.Images.Media.DATA; picturePath=getPath(column_Name,data.getData()); //My app Crashes here because in Marshmallow data.getData() is always null. Bitmap orientedBitmap = ExifUtil.rotateBitmap(picturePath, BitmapFactory.decodeFile(picturePath)); Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.extractThumbnail(orientedBitmap, THUMBSIZE, THUMBSIZE)); thumbnailview.setBackground(fullpic); editText.setText(picturePath); picker.setVisibility(View.VISIBLE); thumbnailview.setClickable(false); } break; case RESULT_LOAD_VIDEO: if (resultCode==RESULT_OK){ String column_Name=MediaStore.Video.Media.DATA; String videoPath=getPath(column_Name,data.getData()); Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.createVideoThumbnail(videoPath,MediaStore.Video.Thumbnails.MINI_KIND)); thumbnailview.setBackground(fullpic); editText.setText(videoPath); picker.setVisibility(View.VISIBLE); thumbnailview.setClickable(false); } break; case REQUEST_VIDEO_CAPTURE: if (resultCode==RESULT_OK){ String column_Name=MediaStore.Video.Media.DATA; String videoPath=getPath(column_Name,data.getData()); Drawable fullpic=new BitmapDrawable(getResources(),ThumbnailUtils.createVideoThumbnail(videoPath,MediaStore.Video.Thumbnails.MINI_KIND)); thumbnailview.setBackground(fullpic); editText.setText(videoPath); picker.setVisibility(View.VISIBLE); thumbnailview.setClickable(false); } break; } if (picker != null) { picker.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { OpenDialog(); } }); } } private String getPath(String column_Name,Uri uri){ String[] projection = {column_Name}; String path = ""; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); int column_index_data ; if (cursor != null) { column_index_data = cursor.getColumnIndexOrThrow(column_Name); cursor.moveToFirst(); path = cursor.getString(column_index_data); cursor.close(); } return path; } private void OpenDialog(){ dialogBox.setTitle("Select an Action"); dialogBox.setMessage("Choose Picture or Video"); dialogBox.setPositiveButton("Picture", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (check_Permissions()){ OpenCameraDialog(); } else { request_Permissions(); CAMERA_DIALOG_PERMISSION=1; } } }); dialogBox.setNegativeButton("Video", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (check_Permissions()){ OpenVideoDialog(); } else { request_Permissions(); VIDEO_DIALOG_PERMISSION=1; } } }); dialogBox.show(); } private void OpenCameraDialog(){ dialogBox.setTitle("Select an Action"); dialogBox.setMessage("Choose Picture From"); dialogBox.setPositiveButton("Gallery", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final Intent galleryintent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryintent, RESULT_LOAD_IMAGE); } }); dialogBox.setNegativeButton("Camera", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } }); dialogBox.show(); } private void OpenVideoDialog(){ dialogBox.setTitle("Select an Action"); dialogBox.setMessage("Choose Video From"); dialogBox.setPositiveButton("Gallery", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final Intent galleryintent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryintent, RESULT_LOAD_VIDEO); } }); dialogBox.setNegativeButton("Camera", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE); } } }); dialogBox.show(); } private boolean check_Permissions(){ boolean GRANTED; if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) + ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) + ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO) + ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){ GRANTED=false; } else { GRANTED=true; } return GRANTED; } private void request_Permissions(){ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO}, REQUEST_FOR_PERMISSION); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case REQUEST_FOR_PERMISSION: if ((grantResults.length>0)&& (grantResults[0] +grantResults[1]+grantResults[2]+grantResults[3]== PackageManager.PERMISSION_GRANTED)){ if (CAMERA_DIALOG_PERMISSION==1){ OpenCameraDialog(); CAMERA_DIALOG_PERMISSION=0; } else if (VIDEO_DIALOG_PERMISSION==1){ OpenVideoDialog(); VIDEO_DIALOG_PERMISSION=0; } } else { Toast.makeText(this, "Please GRANT Permissions", Toast.LENGTH_SHORT).show(); } } } 中显示缩略图 - 工作正常。

  5. 现在有很多解决方案,但它们看起来都不令人满意,如果代码在视频捕获的情况下工作正常,那么为什么它不能用于图像捕获?这是一个Bug还是我在某处做错了?

    这是我的代码。我已经评论了崩溃发生的一条线 -

    frm_childForm obj_childForm = new frm_childForm(this);
    obj_childForm.ShowDialog();
    

4 个答案:

答案 0 :(得分:3)

当我们从Android中的Camera捕获图像时,Uridata.getdata()为空。我们有两个解决方案来解决这个问题。

  1. 我们可以从Bitmap Image获得Uri路径
  2. 我们可以从光标获得U​​ri路径。
  3. 我将在这里实施所有方法,请仔细观察并阅读: -

    首先我将讲述如何从Bitmap Image获取Uri: 完整的代码是:

    首先我们将通过Intent捕获图像,这两个方法都是相同的,所以这段代码我只会在这里写一次:

     // Capture Image
            captureImg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    if (intent.resolveActivity(getPackageManager()) != null) {
                        startActivityForResult(intent, reqcode);
                    }
    
                }
            });
    

    现在我们将实现OnActivityResult :-(对于以上两种方法都是一样的): -

    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
    
            if(requestCode==reqcode && resultCode==RESULT_OK)
            {
    
    Bitmap photo = (Bitmap) data.getExtras().get("data");
    ImageView.setImageBitmap(photo);
    
                // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
                Uri tempUri = getImageUri(getApplicationContext(), photo);
    
                \\ Show Uri path based on Image
                Toast.makeText(LiveImage.this,"Here "+ tempUri, Toast.LENGTH_LONG).show();
    
               \\ Show Uri path based on Cursor Content Resolver
                Toast.makeText(this, "Real path for URI : "+getRealPathFromURI(tempUri), Toast.LENGTH_SHORT).show();
    }
            else
            {
                Toast.makeText(this, "Failed To Capture Image", Toast.LENGTH_SHORT).show();
            }
        }
    

    \现在我们将创建以上所有方法,通过类:

    从Image和Cursor方法创建Uri

    现在来自位图图像的URI路径

      private Uri getImageUri(Context applicationContext, Bitmap photo) {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
            String path = MediaStore.Images.Media.insertImage(LiveImage.this.getContentResolver(), photo, "Title", null);
            return Uri.parse(path);
        }
    

    \ Uri来自保存图像的真实路径

      public String getRealPathFromURI(Uri uri) {
            Cursor cursor = getContentResolver().query(uri, null, null, null, null);
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            return cursor.getString(idx);
        }
    

    亲爱的朋友复制并粘贴此代码,然后尝试理解。 如果您正在制作企业应用程序,我百分百肯定这对您更有利。 如果你喜欢我的代码,那就投票给我....

答案 1 :(得分:2)

  

除了Marshmallow和Lollipop之外,它在每部手机上都能完美运行

不,不是。当用户选择编写良好的相机应用程序来处理ACTION_IMAGE_CAPTURE请求时,它会在许多Android版本上失败。

你的问题在于:

            if (data.getData()!=null){
            picturePath=getPath(column_Name,data.getData());}
            else {
                //My app Crashes here because in Marshmallow data.getData() is always null.
            }

这里至少有两个缺陷。

最重要的是假设您从Uri获得了ACTION_IMAGE_CAPTUREThat is not documented,相机应用无需返回Uri。特别是,在您的结构中,您只能通过getExtra("data")返回缩略图。如果您想要一张全尺寸的图片,请在EXTRA_OUTPUT上使用Intent,在这种情况下,您可以知道图片的存储位置 - 无论您在EXTRA_OUTPUT中指示哪个位置。

另一个原因是您认为您获得的Uri来自MediaStore或其他MediaStore.Video.Media.DATA列。相机应用不仅不必返回Uri,而且Uri不是来自MediaStore或具有此类列。

答案 2 :(得分:0)

正如@CommonsWare所建议的那样 -

  

相机应用程序不需要返回uri。

此外,

  

您需要告诉Camera app在哪里写图像。

所以,我用 -

替换了我的代码
 final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            pictureUri=getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri);
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);

并在onActivityResult -

 case REQUEST_IMAGE_CAPTURE:

            if (resultCode==RESULT_OK){
                String picturePath="";
                String column_Name= MediaStore.Images.Media.DATA;
                if (data!=null){
                if (data.getData()!=null){
                picturePath=getPathfromUri(column_Name,data.getData());}

                else {
                    picturePath= pictureUri.getPath();

                }
                }
                else {
                    picturePath= pictureUri.getPath();

                }}

答案 3 :(得分:0)

您可以从 Bitmap 中获取 Uri

private Uri getImageUri(Context applicationContext, Bitmap bitmapImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        photo.compress(Bitmap.CompressFormat.PNG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(MainActivity.this.getContentResolver(), bitmapImage, "Some Title", null);
        return Uri.parse(path);
    }



protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode==CAPTURE_IMAGE_CODE){

                Bitmap bitmapImage = (Bitmap) data.getExtras().get("data");
                //ImageView.setImageBitmap(photo);

                Uri inputImageUri = getImageUri(getApplicationContext(),bitmapImage); 
            }
        }
    }

并添加调用此 onClick

private void takeImage(){

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, CAPTURE_IMAGE_CODE);
        }

    }