Reputation: 198
I am trying to allow users to select an image from camera and gallery and update an image view with the selected image. I am successful in doing so if a user selects a picture from their gallery, however if they choose to take a picture with their camera I keep getting a null value. I am unsure as to why, I have all the necessary permission in my manifest file such as write and from read external storage.
//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;
}
}
}
Upvotes: 0
Views: 46
Reputation: 498
try this in your code
case 0:
if (resultCode == RESULT_OK) {
Bundle extras = imageReturnedIntent.getExtras();
bitmap = (Bitmap)extras.get("data");
bookImage.setImageBitmap(bitmap);
}
there is another approach which is, store image into external file directory before you load image. check this
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();
}
});
to save to location and fetch the path of the image
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;
}
and at last, in 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*/
}
}
and for getting permission to access a local file storage directory, in your manifest file add these
<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>
you have to create a resource file 'paths' specifying your external-path in 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>
now the images will be stored to an external path so you can use the file path to print the image into the image view
Upvotes: 1
Reputation: 1385
To get proper image from camera you have to provide File that camera app can write to:
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);
}
}
}
And then on activity result with REQUEST_TAKE_PHOTO just read file that you created with createImageFile
or thumbnail Bitmap object that will be in returned as extras 'data' field
You can find all answers here: https://developer.android.com/training/camera/photobasics#java
Upvotes: 0