I've written a method that creates a directory in my apps cache directory and then prompts the user to take a photo or select a photo from the gallery.
if the user takes a new photo, the photo is saved to the cache as profile.jpg
I'm trying to get the intent that returns a photo from the gallery to save the returned photo in the cache directory of my app as profile.jpg.
I'm having trouble achieving this.
public void selectImage(View v) {
File newDir = new File(getExternalCacheDir(), "RecruitSwift");
if(!newDir.isDirectory())
newDir.mkdirs();
else
Toast.makeText(this, "Dir already exist", Toast.LENGTH_LONG).show();
if(newDir.canWrite())
imageFile = new File(newDir, "profile.jpg");
else
Toast.makeText(this, "Dir not writable", Toast.LENGTH_LONG).show();
final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(UserProfileInterviewScreenActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Take Photo")){
Intent takeProfileImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takeProfileImage.resolveActivity(getPackageManager()) != null) {
Uri imageUri = Uri.fromFile(imageFile);
takeProfileImage.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(takeProfileImage, 1);
}
}
else if (options[item].equals("Choose from Gallery")){
Intent takeProfileImage = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Uri selectedImage = takeProfileImage.getData();
imageFile = selectedImage;
startActivityForResult(takeProfileImage, 2);
}
else if (options[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
If you want to take a photo or pick a picture, you need to call startActivityForResult and then override onActivityResult. Here are some codes to take a photo, take a look:
startActivityForResult:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(AVATAR_FILE_TMP));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
startActivityForResult(intent, CODE_TAKE_PHOTO);
then override onActivityResult:
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CODE_TAKE_PHOTO) {
cropImage(Uri.fromFile(AVATAR_FILE_TMP));
}
}
As pointed out by #greenapps the intent it's self doesn't return anything, you have to get the returned content provider path in your onActivityResult method and convert it into a file system path.
This is the code I wrote in the end:
Uri selectedImage = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Log.w("path of profileImage.setImageBitmap(thumbnail);
try{
String file_path = getExternalCacheDir() + "/MyWebsiteDir";
File dir = new File(file_path);
if(!dir.exists())
dir.mkdirs();
File file = new File(dir, "profile.jpg");
FileOutputStream fOut = new FileOutputStream(file);
thumbnail.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
}
catch (Exception e) {
e.printStackTrace();
}
Related
I am trying to get an image from the camera or gallery to upload on the server. My code is working perfectly in Android 9 or lower but I cannot able to access the image path in Android 10. I don't know much about Android 10’s Scoped Storage, Please review my code and help.
private void selectImage(Context context, final int cameraRequestCode, final int galleryRequestCode) {
if (!hasPermissions(context, PERMISSIONS)) {
ActivityCompat.requestPermissions(requireActivity(), PERMISSIONS, PERMISSION_ALL);
} else {
final CharSequence[] options = {"Take Photo", "Choose from Gallery", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose your profile picture");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Take Photo")) {
/* Intent takePicture = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, cameraRequestCode);*/
Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, cameraRequestCode);
} else if (options[item].equals("Choose from Gallery")) {
Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto, galleryRequestCode);
} else if (options[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
}
public File convertBitmaptoFile(Bitmap bitmap, String filename) throws IOException {
File f = new File(requireContext().getCacheDir(), filename);
f.createNewFile();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();
return f;
}
'Here is my onActivity code'
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_CANCELED) {
switch (requestCode) {
case 0:
try {
String millisecond = String.valueOf(Calendar.getInstance().getTimeInMillis());
// logo_file = new File(String.valueOf(convertBitmaptoFile(fileToBitmap(sdImageMainDirectory.getPath()), "IMAGE_" + millisecond + ".jpg")));
// img_logo.setImageURI(Uri.parse(logo_file.getAbsolutePath()));
img_logo.setImageURI(Uri.parse(getPath(Uri.fromFile(logo_file = new File(String.valueOf(convertBitmaptoFile(fileToBitmap(sdImageMainDirectory.getPath()), "IMAGE_" + millisecond + ".jpg")))))));
Log.e("logo file path","" + logo_file.getPath());
Log.e("logo file absolute path","" + logo_file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
// fa_image.setImageURI(Uri.parse(fa_image_file.getPath()));
break;
case 1:
if (resultCode == RESULT_OK && data != null) {
Uri selectedImage = Uri.parse(data.getData().getEncodedPath());
String[] filePathColumn = {MediaStore.Images.Media.DATA};
if (selectedImage != null) {
Cursor cursor = getActivity().getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
logo_file = new File(picturePath);
Log.e("IMAGE", "ja_image :" + logo_file);
img_logo.setImageBitmap(BitmapFactory.decodeFile(picturePath));
cursor.close();
}
}
}
break;
}
}
}
Have you used android:requestLegacyExternalStorage="true" in AndroidManifest.xml
<application
android:name="com.xyz"
android:allowBackup="true"
android:exported="false"
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning"
tools:targetApi="q">
In Android 10, you cannot access image using the uri provided in onActivityResult. Try this. I'm sure it will work for you. This is will work when you are selecting an image from gallery. For taking pictures from camera photo, the approach is a little different.
Kotlin Solution :
val imageType = contentResolver.getType(data.data!!)
data.data!!.let {
application.contentResolver.openInputStream(it).use { inputStream ->
filePartImage = MultipartBody.Part.createFormData(
"image", //should be same as the key of your parameter
"filename" + ".jpg", // extension of file name is must
inputStream!!.readBytes().toRequestBody(imageType.toMediaTypeOrNull())
)
}
}
Later pass this filePartImage as your image parameter for uploading image to server.
So the app I have, takes a photograph (or uses from library) and brings the captured photo into an editing view. The code for the camera capture is;
public void cameraClicked(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 2);
}
The camera view opens, allows me to take a photo, but when it moves to EditorActivity.class the photo is not there, just a black screen. The editor view is fine, but it does not seem to be taking what I capture with the camera. I have set the correct permissions, this works fine in versions prior to Level 23
SDK version.
Edit - updated code methods below;
boolean SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
return false;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case 2:
if (resultCode == RESULT_OK) {
Log.e("TAG", "work here");
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
SaveImage(thumbnail);
Intent intent = new Intent(this, EditorActivity.class);
startActivity(intent);
}
break;
}
}
I am capturing an image and store it in storage in mobile but when I get this image it cannot show any thing in Image View. I have tried a lot of code to get images from file but none of them are working in my emulator or real Samsung device.
enter code here
imageHolder = (ImageView)findViewById(R.id.captured_photo);
Button capturedImageButton = (Button)findViewById(R.id.photo_button);
capturedImageButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent photoCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(photoCaptureIntent, requestCode);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(this.requestCode == requestCode && resultCode == RESULT_OK){
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
String partFilename = currentDateFormat();
storeCameraPhotoInSDCard(bitmap, partFilename);
// display the image from SD Card to ImageView Control
String storeFilename = "photo_" + partFilename + ".jpg";
Bitmap mBitmap = getImageFileFromSDCard(storeFilename);
imageHolder.setImageBitmap(mBitmap);
}
}
private String currentDateFormat(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
String currentTimeStamp = dateFormat.format(new Date());
return currentTimeStamp;
}
private void storeCameraPhotoInSDCard(Bitmap bitmap, String currentDate){
File outputFile = new File(Environment.getExternalStorageDirectory(), "photo_" + currentDate + ".jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Bitmap getImageFileFromSDCard(String filename){
/* Bitmap bitmap = null;
File imageFile = new File(Environment.getExternalStorageDirectory() + filename);
try {
FileInputStream fis = new FileInputStream(imageFile);
bitmap = BitmapFactory.decodeStream(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap; */
File imageFile = new File(Environment.getExternalStorageDirectory() + filename);
// File imgFile = new File(filename);
//("/sdcard/Images/test_image.jpg");
Bitmap myBitmap;
if(imageFile.exists()){
myBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
// ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
// myImage.setImageBitmap(myBitmap);
return myBitmap;
}
return null;
}
First of All make sure you have declared the "Access External Storage" and "Access Hardware Camera" permissions in "AndroidManifest" and if you are using Android version 23 or 23+ then you have to take permissions on run-time.
If this is not the problem then use this code given below, it's working fine for me.
For Camera:
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, ACTION_REQUEST_CAMERA);
For Gallery:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
Intent chooser = Intent.createChooser(intent, "Choose a Picture");
startActivityForResult(chooser, ACTION_REQUEST_GALLERY);
OnActivityResultMethod:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ACTION_REQUEST_GALLERY:
Uri galleryImageUri = data.getData();
try{
Log.e("Image Path Gallery" , getPath(getActivity() , galleryImageUri));
selectedImagePath = getPath(getActivity() , galleryImageUri);
} catch (Exception ex){
ex.printStackTrace();
Log.e("Image Path Gallery" , galleryImageUri.getPath());
selectedImagePath = galleryImageUri.getPath();
}
break;
case ACTION_REQUEST_CAMERA:
// Uri cameraImageUri = initialURI;
Uri cameraImageUri = data.getData();
Log.e("Image Path Camera" , getPath(cameraImageUri));
selectedImagePath = getPath(cameraImageUri);
break;
}
}
}
Method to get path of Image returned from Camera:
/**
* helper to retrieve the path of an image URI
*/
public String getPath(Uri uri) {
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}
Good Day
I'm trying to make app that capture image and then display it in gridview
but i when i click the button to start capture this error appear.
Logcat:
java.lang.SecurityException: Permission Denial: starting Intent {
act=android.media.action.IMAGE_CAPTURE flg=0x3
cmp=com.android.camera2/com.android.camera.CaptureActivity
clip={text/uri-list
U:file:///storage/emulated/0/Pictures/MyInvoice/IMG_20160223_032401.jpg}
(has extras) } from ProcessRecord{8f9b88f
1356:com.example.labon.invoicemanger/u0a62} (pid=1356, uid=10062) with
revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1599)
My Code:
myLists = new ArrayList<Images>();
adapter = new ImageListAdapter(getActivity(), R.layout.img_list_view, myLists);
Button myButton = (Button) view.findViewById(R.id.camerabutton);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);// create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE); // start the image capture Intent
}
});
myGridView = (GridView) view.findViewById(R.id.gridView);
myGridView.setAdapter(adapter); /**
* Create a file Uri for saving an image or video
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image /
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
// if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
//return null;
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//file path of captured image
String filePath = cursor.getString(columnIndex);
//file path of captured image
File f = new File(filePath);
String filename = f.getName();
cursor.close();
//Convert file path into bitmap image using below line.
Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
//put bitmapimage in your imageview
ImageView imageView = (ImageView) view.findViewById(R.id.imageListView);
imageView.setImageBitmap(BitmapFactory.decodeByteArray(images.getImageBlob(), 0, images.getImageBlob().length));
//newImageView.setImageBitmap(yourSelectedImage); }
if (resultCode == getActivity().RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getActivity(), "User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getActivity(), "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
} }
Are you running this on marshmallow? Because if you are, the permission structure has changed. And you should read the documentation # http://developer.android.com/training/permissions/index.html .
The user must grant the permission explicitly.
you need to add user permission to androidmanifest.xml
<uses-permission android:name="android.permission.CAMERA" />
if you need to store the image to storage you have to add :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I can load the picture to the background then I have also been able to "sketchify" it but when I try to save it so that I can email it as an attachment I can only figure out haw to grab the original image and what I have here makes the activity close
public void startCamera(View v) {
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
seek.setVisibility(View.GONE);
if (takePicture.resolveActivity(getPackageManager()) != null) {
picSpot = new File(Environment.getExternalStorageDirectory(),
"sketch.png");
outputFileUri = Uri.fromFile(picSpot);
takePicture.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(takePicture, REQUEST_IMAGE_CAPTURE);
}
}
public void sendPic(View v) {
Intent sharePic = new Intent(Intent.ACTION_SEND);
if (didsketch == false) {
sharePic.setType("image/png");
sharePic.putExtra(Intent.EXTRA_STREAM, outputFileUri);
sharePic.putExtra(Intent.EXTRA_SUBJECT, "Check This Out!");
sharePic.putExtra(Intent.EXTRA_TEXT,
"I did this on my Sketchify App!");
startActivity(Intent.createChooser(sharePic, "Send Email"));
} else {
try {
FileOutputStream out = new FileOutputStream(finalSpot);
back.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
outputFileUri = Uri.fromFile(finalSpot);
sharePic.setType("image/png");
sharePic.putExtra(Intent.EXTRA_STREAM, outputFileUri);
sharePic.putExtra(Intent.EXTRA_SUBJECT, "Check This Out!");
sharePic.putExtra(Intent.EXTRA_TEXT,
"I did this on my Sketchify App!");
startActivity(Intent.createChooser(sharePic, "Send Email"));
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
sketchit.setEnabled(true);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
screenHeight = metrics.heightPixels;
screenWidth = metrics.widthPixels;
location = Environment.getExternalStorageDirectory()
+ "/sketch.png";
back = Camera_Helpers.processImage(location, screenHeight,
screenWidth);
taken = true;
sketchit.setEnabled(taken);
shareit.setEnabled(taken);
image.setImageBitmap(back);
}
}
back is the modified bitmap i am trying to eventually attach to the email
Thanks!!!
Create Folder Directory and Save image into it: create directory where you want to save your images. Suppose the folder name is ImageFolder.
String location = Environment.getExternalStorageDirectory() + "/ImageFolder/";
//Creating Folder Directory
File imageDir = new File(location);
dir.mkdirs();
//Creating Image file
String imageName = "sketch.png";
File imageFile = new File(imageDir, imageName);
//If image file already exists then delete it.
if (imageFile.exists()) {
imageFile.delete();
}
//Writing the image to SDCard
try {
FileOutputStream out = new FileOutputStream(imageFile);
back.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}