用户为什么不显示相机中的图像?

时间:2019-10-31 07:58:58

标签: android

我正在尝试允许用户从相机和图库中选择图像,并使用所选图像更新图像视图。如果用户从他们的画廊中选择一张图片,我这样做会很成功,但是如果他们选择使用相机拍摄照片,我会得到一个空值。我不确定为什么,清单文件中有所有必要的权限,例如写入和读取外部存储。

//Creates popup and allows user to select book image from gallery or camera.
public void selectImageMenu(final View v) {
    PopupMenu popup = new PopupMenu(v.getContext(), v);
    popup.getMenuInflater().inflate(R.menu.gallery_menu, popup.getMenu());
    popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.openCamera:
                    openCamera();
                    return true;

                case R.id.openGallery:
                    openGallery();
                    return true;

                default:
                    return true;
            }
        }
    });
    popup.show();
}


//checks permission and if it's granted allows user the choice of choosing an image from gallery or camera
public void uploadImagePost(View view) {

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
    } else {
        selectImageMenu(view);

    }

}

//opens camera to allow user to take a picture.
public void openCamera() {
    Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(takePicture, 0);//zero can be replaced with any action code
}

//opens gallery to allow user to choose a book image
public void openGallery() {
    Intent pickPhoto = new Intent(Intent.ACTION_PICK,  android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(pickPhoto, 1);//one can be replaced with any action code

}

protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch (requestCode) {
        case 0:
            if (resultCode == RESULT_OK) {
                selectedImageUri = imageReturnedIntent.getData();
                Glide
                    .with(CreatePostActivity.this)
                    .load(selectedImageUri)
                    .placeholder(R.drawable.bookshelf)
                    .into(bookImage);
            }

            break;
        case 1:
            if (resultCode == RESULT_OK) {
                selectedImageUri = imageReturnedIntent.getData();
                Glide
                    .with(CreatePostActivity.this)
                    .load(selectedImageUri)
                    .placeholder(R.drawable.bookshelf)
                    .fitCenter()
                    .into(bookImage);

                break;
            }
    }

}

2 个答案:

答案 0 :(得分:0)

在您的代码中尝试

case 0:
            if (resultCode == RESULT_OK) {
                   Bundle extras = imageReturnedIntent.getExtras();
                   bitmap = (Bitmap)extras.get("data");
                   bookImage.setImageBitmap(bitmap);

            }

还有另一种方法,即在加载图像之前将图像存储到外部文件目录中。 检查一下

btnCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
    File pictureFile = null;
    pictureFile = getPictureFile();
    if (pictureFile != null) {
        Uri photoURI = FileProvider.getUriForFile(activity,
                        "com.xyx.yourproject",pictureFile);
                                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                                startActivityForResult(cameraIntent,CAMERA_REQUESTCODE);
                            }
                        }
                        dialog.dismiss();


                    }
                });

保存到位置并获取图像的路径

private File getPictureFile() {

        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String pictureFile = "pic_" + timeStamp;
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = null;
        try {
            image = File.createTempFile(pictureFile,  ".jpg", storageDir);
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(activity,
                    "Photo file can't be created, please try again",
                    Toast.LENGTH_SHORT).show();
        }
        pictureFilePath = image.getAbsolutePath();
        return image;
    }

最后是onActivityResult

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


        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == CAMERA_REQUESTCODE && resultCode == RESULT_OK) {

            File imgFile = new  File(pictureFilePath);

            /** use imgFile to print into your image view---code to print the image*/

        } else if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK) {


          /**-------your code*/


        }
    } 

要获得访问本地文件存储目录的权限,请在清单文件中添加这些文件

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.xyz.yourpath"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/paths" />
        </provider>

您必须创建一个资源文件“路径”,以在res / xml中指定您的外部路径

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="yourfiles"
    path="Android/data/com.xyz.yourpackagename/files/Pictures" />
</paths>

现在图像将存储到外部路径,因此您可以使用文件路径将图像打印到图像视图中

答案 1 :(得分:0)

要从相机中获取正确的图像,您必须提供相机应用可以写入的文件:

static final int REQUEST_TAKE_PHOTO = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            ...
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                                                  "com.example.android.fileprovider",
                                                  photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
}

然后在带有REQUEST_TAKE_PHOTO的活动结果上,只需读取您使用createImageFile创建的文件或缩略图位图对象,这些文件将作为额外的“数据”字段返回

您可以在这里找到所有答案:https://developer.android.com/training/camera/photobasics#java