I am creating an app where I want the user to pick which folder to save their images in. I first want to see if I could figure out how to save the images in another folder besides the default folder but I keep getting an error and can't figure out why.
Here is the code I have to start the camera intent and to get the file directory name
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smart_wardrobe);
camera = (Button)findViewById(R.id.cameraBtn);
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
file = getOutputMediaFileUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, file);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE );
}
});
}
Here is the code for the uriFileDirectory
private static Uri getOutputMediaFileUri(){
return Uri.fromFile(getOutputMediaFile());
}
private static File getOutputMediaFile(){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (! mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
return mediaFile;
}
Here is my onActivityResult method
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
Toast.makeText(this, "There is someting wrong with your code", Toast.LENGTH_LONG).show();
}
}
if (requestCode == SELECT_PICTURE){
if (resultCode == RESULT_OK) {
images = data.getData();
selectedImagePath = getPath(images);
}
}
}
Can someone please help fix my code?
Check first your permission in Manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and onActivityResult method check that is it returning a file path or not. add the line in this method
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" +
file, Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
Toast.makeText(this, "There is someting wrong with your code", Toast.LENGTH_LONG).show();
}
}
the problem was in your toast. In Camera Intent we get intent as null and you are trying to taking data from there. you have to use Uri.
Related
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;
}
}
}
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
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
i have:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foto);
Intent intentFotocamera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); //creo un timestamp univoco
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
imagesFolder.mkdirs(); //creo un nuovo album
File image = new File(imagesFolder, "QR_" + timeStamp + ".png"); //concateno
Uri uriSavedImage = Uri.fromFile(image);
intentFotocamera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(intentFotocamera, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
Now, when the user presses the photo confirmation button (and then is saved locally) I would like to create a new activity because I want to print this photo in my app.
How do I create new activity?
In the override method onActivityResult() start the new activity.
https://developer.android.com/training/basics/intents/result.html
Example:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
// Check which request we're responding to
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
}
Do you want to open new activity and show the photo which is taken recently?
Here is how you can do it.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
"handle here"
}
} catch (Exception ex) {
}
}
In my app, I am using an intent to start the phone's camera, take a picture and save it locally on the phone. This is all working fine, however, once I press save (to save the picture) the the app quits and it takes me back to the home screen of my phone. I'm not sure what I'm missing so that after I press save, it goes back to my app rather than the home screen? Below is my code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//other code, removed as its unrelated
btnAddExpense.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(context, "List Item Clicked.", Toast.LENGTH_LONG).show();
// create intent with ACTION_IMAGE_CAPTURE action
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// this part to save captured image on provided path
File file = new File(Environment.getExternalStorageDirectory(), "AutoTracker_" + System.currentTimeMillis() + ".jpg");
Uri photoPath = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoPath);
// start camera activity
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
});
return rowView;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(context, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(context, "Video saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the video capture
} else {
// Video capture failed, advise user
}
}
}
Thanks!
I'm switching from using the default camera to finally growing a pair and deciding to make a custom camera. It's only showing me how much I don't fully understand.
Here is basically way I have been doing things in the main activity as far as photos go, but it will no longer work:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PICK_PHOTO_REQUEST) {
if (data == null) {
Toast.makeText(this, "General Error!", Toast.LENGTH_LONG).show();
}
else {
mMediaUri = data.getData();
}
Log.i(TAG, "Media URI: " + mMediaUri);
}
else {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(mMediaUri);
sendBroadcast(mediaScanIntent);
}
(...)
Here is the picture saving function along with a couple others of the new camera:
(...)
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d("Picture taken");
String path = savePictureToFileSystem(data);
setResult(path);
finish();
}
private static String savePictureToFileSystem(byte[] data) {
File file = getOutputMediaFile();
saveToFile(data, file);
return file.getAbsolutePath();
}
private void setResult(String path) {
Intent intent = new Intent();
intent.putExtra(EXTRA_IMAGE_PATH, path);
setResult(RESULT_OK, intent);
}
*Credit to Paul Blundell
(...)
What do I need to do so that the main activity can receive the image's URI in the onactivityresult instead of the path String? Are URIs even applicable when it comes to custom cameras?
Please and thanks.
You use custom camera, but want to do it via Intent? OK, you have the absolute file path in
String abspath = data.getExtras().getString(EXTRA_IMAGE_PATH);
mMediaUri = Uri.fromFile(new File(abspath));
Hi can anyone help me fix this. I'm getting an error on this line File imageFile = new File(photoUri); saying that the constructor File(photoUri) is undefined even I have that contructor on the method that will call that. here is my code.
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQ){
if (resultCode == RESULT_OK) {
Uri photoUri = null;
if (data == null){
Toast.makeText(this, "Image saved successfully", Toast.LENGTH_LONG).show();
photoUri = fileUri;
} else {
photoUri = data.getData();
Toast.makeText(this, "Image saved successfully in: " + data.getData(), Toast.LENGTH_LONG).show();
}
showPhoto(photoUri);
} else if (resultCode == RESULT_CANCELED)
{
Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show();
} else
{
Toast.makeText(this, "Callout for image capture failed!", Toast.LENGTH_LONG).show();
}
}
}
private void showPhoto(Uri photoUri)
{
File imageFile = new File(photoUri);
if (imageFile.exists())
{
Drawable oldDrawable = photoImage.getDrawable();
if (oldDrawable != null) { ((BitmapDrawable)oldDrawable).getBitmap().recycle();
}
Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
BitmapDrawable drawable = new BitmapDrawable(this.getResources(), bitmap);
photoImage.setScaleType(ImageView.ScaleType.FIT_CENTER);
photoImage.setImageDrawable(drawable);
}
}
call toString() on the photoUri instance
showPhoto(photoUri.toString());
Uri.toString() returns the encoded string representation of this URI.