I am making an app that will let users take photos and save them to the app, which will be password protected. So far, the app can take a picture, retrieve it, and set it to an image view. However, when I restart the app the image goes away. How can I save it?
int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
Uri imageUri;
public void takePic(View view){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "filename_" +
String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra("data", imageUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
Bundle extras = data.getExtras();
Log.e("URI", imageUri.toString());
Bitmap bmp = (Bitmap) extras.get("data");
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(bmp);
}
else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT);
}
}
}
That imageUri you pass to the Intent- the image file is saved there. Just save the URI in SharedPreferences or other persistant storage and check that storage next time you launch your app.
This code is working on me :
private void takePicture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
mImageCaptureUri = null;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mImageCaptureUri = Uri.fromFile(mFileTemp);
}
else {
mImageCaptureUri = InternalStorageContentProvider.CONTENT_URI;
}
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
} catch (Exception e) {
Log.d("error", "cannot take picture", e);
}
}
This is how to define mFileTemp
String state = Environment.getExternalStorageState();
File mFileTemp;
if (Environment.MEDIA_MOUNTED.equals(state)) {
//this is like that
//any folder name/you can add inner folders like that/your photo name122412414124.jpg
mFileTemp = new File(Environment.getExternalStorageDirectory()+File.separator+"any folder name"+File.separator+"you can add inner folders like that"
, "your photo name"+System.currentTimeMillis()+".jpg");
mFileTemp.getParentFile().mkdirs();
}
else {
mFileTemp = new File(getFilesDir()+"any folder name"+
File.separator+"myphotos")+File.separator+"profilephotos", "your photo name"+System.currentTimeMillis()+".jpg");
mFileTemp.getParentFile().mkdirs();
}
Your global variables
private Uri mImageCaptureUri;
private File mFileTemp;
1) Define your global variables
2) Then define mFileTemp
3)Then trigger takePicture() method
Related
i'm writing an android app on java and need to let my users select and crop images from the gallery.
There is no problem when choosing an image from any native gallery, but when a user chooses to eater crop or choose an image from google photos app the app crushes.
I cannot figure out what is the source of the problem so any answer will be helpful
this is the code i'm using
class fields:
private Uri imageUri;
opening the camera:
private void camOpen() {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory(), "file" + String.valueOf(System.currentTimeMillis()) + ".png");
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
imageUri = Uri.fromFile(f);
i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
i.putExtra("return-data", true);
startActivityForResult(i, CAMERA_CODE);
}
opening the gallery:
private void galleryOpen() {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(i, "select file"), SELECT_PHOTO_CODE);
}
cropping the image:
private void cropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(imageUri, "image/*");
cropIntent.putExtra("crop", true);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, CROP_CODE);
} catch (Exception e) {}
}
the result handler:
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_CODE && resultCode == Activity.RESULT_OK) {
cropImage();
} else if (requestCode == SELECT_PHOTO_CODE && resultCode == Activity.RESULT_OK) {
if (data != null) {
imageUri = data.getData();
cropImage();
}
} else if (requestCode == CROP_CODE && resultCode == Activity.RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap b = bundle.getParcelable("data");
hasImageChanged=true;
ivProfilePic.setImageBitmap(b);
capturedImage = b;
}
}
thank you for any useful help...
Android does not support crop intent because croping is not part of android api.
So i recommend you for Using library
the issue was with the crop intent. I ended up using the uCrop library and it fixed the problem.
I have these codes to get an image from gallery or take photo with camera and after cropping it i want to show it in a bitmap imageview.
My problem is they work good in some devices and don't work in others!
please tell me which part of my code is making the problem ! Thank you
For example:
On LG G4 i not able to crop , but the photo from gallery and camera shows on image view
On Samsung Galaxy Alpha i can crop , image from camera shows good but i cant choose from gallery!
What should i do to work fine in all devices?
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// ******** code for crop image
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("cropped-rect", "true");
try {
intent.putExtra("return-data", true);
startActivityForResult(Intent.createChooser(intent,
"Complete action using"), PICK_FROM_GALLERY);
} catch (ActivityNotFoundException e) {
// Do nothing for now
}
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
private void captureWithCamera() {
// call android default camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
// ******** code for crop image
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("cropped-rect", "true");
try {
intent.putExtra("return-data", true);
startActivityForResult(Intent.createChooser(intent,"Complete action using"), PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
// Do nothing for now
}
}
I think the problem must be in how i handle the returned data in onActivityResult method! Please take a look at my code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri filePath = data.getData();
try {
//Getting the Bitmap from Gallery
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
//Setting the Bitmap to ImageView
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
if (requestCode == PICK_FROM_CAMERA) {
Bundle extras = data.getExtras();
if (extras != null) {
//Bitmap photo = extras.getParcelable("data");
bitmap = extras.getParcelable("data");
imageView.setImageBitmap(bitmap);
}
}
}
Possible solutions would be to put uri with imageChooser's intent. Like this;
private void showCamera() {
try {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DCIM");
if (!file.exists()) {
file.mkdirs();
}
File localFile2 = new File(file + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
imageUri = Uri.fromFile(localFile2);
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
cameraIntent.setClipData(ClipData.newRawUri(null, Uri.fromFile(localFile2)));
}
startActivityForResult(cameraIntent, REQUEST_CAMERA);
} catch (Exception localException) {
Toast.makeText(ActivityAddMemory.this, "Exception:" + localException, Toast.LENGTH_SHORT).show();
}
}
On selecting from gallery, complete data is returned with intent. You can use uri by accessing intent.getData() or thumbnail Bitmap using intent.getExtras().get("data"). Don't use imageUri that you passed with that intent.
On capturing from camera, in some devices intent is not null, but it's data is null. And in some devices, intent is null. Check both in onActivityResult.
Uri uri;
if (intent == null || intent.getData() == null) {
uri = this.imageUri;
} else {
uri = intent.getData();
}
Use this uri to display/upload your image.
I'm making an Android application in Android studio where the user can take a photo and save it into a new folder in their gallery. Currently the application takes the pictures fine but doesn't save the image into the new "SOC" folder in my gallery. I'm not getting any errors and I have no idea why it's not saving the image. Any help would be appreciated.
My code is as fallows
static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
public void onClickbtnCamera(View v)
{
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
Uri uriSavedImage=Uri.fromFile(new File("/storage/emulated/0/DCIM/SOC","QR_"+timeStamp+ ".png"));
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(imageIntent, 1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
//Check for succesful result code
if (resultCode == -1) {
//Show your Toast when the result is a success.
Toast toast = Toast.makeText(getApplicationContext(),
"Picture is saved in your SOC gallery", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 100, 0);
toast.show();
}
}
}
I think you must manually add your new photo Uri to Media Content Provider.
take a look here
Call this method in your Activity for result
protected void addPhotoToGallery() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(getCurrentPhotoPath());
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.getActivity().sendBroadcast(mediaScanIntent);
}
you should save the photo path before launching the intent and then getCurrentPhotoPath() must get that path
I currently have an activity that hosts multiple fragments and I am on my third fragment of a collection.
In that fragment I use an Intent to launch either the Camera or Gallery. See code:
public Intent getImageIntent() {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = context.getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName,
res.activityInfo.name));
intent.setPackage(packageName);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
cameraIntents.toArray(new Parcelable[] {}));
// Calling activity should exeecute:
// startActivityForResult(chooserIntent, 1);
return chooserIntent;
}
After that the onActivityResult executes:
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mProductBitmap = (Bitmap) extras.get("data");
imgProduct.setImageBitmap(mProductBitmap);
}
Where mProductBitmap is a Bitmap Global Variable and imgProduct is an ImageView already initialized.
For some reason, first: The Camera option force closes the app, and gets a null pointer from the actual fragment itself, like the fragment items are all null again.
Second: The gallery options (More then one) don't error out but don't show the image either.
Any help would be appreciated. I've looked at every response possible, but not many people call an intent from a fragment that isn't the initial fragment that the activity is hosting.
Thanks!
EDIT:
Found out sometimes my Context is Null after the onActivityResult. If anyone has encountered this help is appreciated. Thanks.
EDIT: Below is by onActivityResult method, most of the time the first if should be executed.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_OK) {
handleSmallCameraPhoto(intent);
} else {
if (requestCode == 1) {
InputStream stream = null;
if (intent == null) {
System.out.println("DATA IS NULL..");
} else {
try {
if (mProductBitmap != null) {
mProductBitmap.recycle();
}
stream = getActivity().getContentResolver().openInputStream(
intent.getData());
mProductBitmap = BitmapFactory.decodeStream(stream);
System.out.println(mProductBitmap);
System.out.println("Setting image result");
imgProduct.setImageBitmap(mProductBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
}
}
}
Your photo is saved in PATH_TO_SAVE location.
You should in onActivityResult do something like this:
File file = new File(PATH_TO_SAVE);
Bitmap bmp = BitmapFactory.decodeFile(file.getPath());
Right now I've got an app that takes a photo via an intent. After taking the photo, I want the user to be able to confirm it and push the photo to another activity where they can add details. I'm struggling to find the correct way to pass the photo from activity to activity.
Right now, confirming the photo brings the user back to the main activity.
Here's my relevant code:
Main Activity
public void takePhoto(View view) {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
Log.d("MySecondApp",fileUri.toString());// create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
if (data!=null) {
// 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 {
// Image capture failed, advise user
}
}
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MySecondApp");
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MySecondApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
I would try something like
if(resultCode == Activity.RESULT_OK)
handleCameraPhoto(data);
handle method:
private void handleCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
Bitmap mImageBitmap = (Bitmap) extras.get("data");
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", mImageBitmap);
startActivity(intent);
}
and then, retrieve it in your other activity
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
and assign it to your ImageView
ImageView iv = (ImageView)findViewById(R.id.myImageView);
iv.setImageBitmap(bitmap);
Make a constructor in your new class that takes an intent or even the image:
class newClass {
public newClass(Intent intent){
...
}
...
}
And then just make the intent the size of a thumbnail in this new class where you can do the confirmation in a popup or something similar and then have the information to be filled on the page for this class. This will also be better because if they wanted to retake the picture you could have this class which they are taken to after the picture is taken if not accepted go to take another picture.
Take a look at this blog post I wrote on how to take a full size image and a thumbnail version as well:
Use Camera Activity for Thumbnail and Full Size Image
after you did that you can extract the file path of the saved file from the file instance using getAbsolutePath() method and pass it to the following Activity.