Capture and crop image in Android 11 (R) - android

As per android R privacy policy changes, I want to perform the capture and crop image feature for android R devices. I tried the below method but it saving the empty file (file is creating in a specified folder but having a size of 0kb).
I'm using Android-image-cropper library to crop images.
public static File createImageFile(Context context) throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + ".jpg";
File storageDir, image;
if(SDK_INT >= Build.VERSION_CODES.Q){
OutputStream outputStream;
ContentResolver contentResolver = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, imageFileName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + File.separator + SD_FOLDER_NAME);
Uri imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
outputStream = contentResolver.openOutputStream(Objects.requireNonNull(imageUri));
Objects.requireNonNull(outputStream);
storageDir = new File(Environment.DIRECTORY_PICTURES + File.separator + SD_FOLDER_NAME);
}else{
storageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + SD_FOLDER_NAME);
}
if (!storageDir.exists()) {
storageDir.mkdirs();
}
image = new File(storageDir, imageFileName);
if (image.createNewFile()) {
Log.d(TAG, ":Image file created");
} else {
Log.d(TAG, ":Image file not created");
}
return image;
}
Below are my camera open and capture functions:
private void openCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri photoURI = null;
try {
fileUri = Utils.createImageFile(requireContext());
if(SDK_INT >= Build.VERSION_CODES.Q)
photoURI = FileProvider.getUriForFile(requireActivity(), requireActivity().getPackageName(), fileUri);
else
photoURI = FileProvider.getUriForFile(requireActivity(), requireActivity().getPackageName() + ".com.enrich.salonapp.provider", fileUri);
} catch (IOException e) {
e.printStackTrace();
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, REQUEST_CODE_CAMERA_PICTURE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PictureSelectorDialog.REQUEST_CODE_CAMERA_PICTURE && resultCode == Activity.RESULT_OK) {
imageCapture.onImageCaptured(fileUri.getAbsolutePath(), false);
} else if (requestCode == PictureSelectorDialog.REQUEST_CODE_GALLERY_PICTURE && resultCode == Activity.RESULT_OK) {
if (FileUtils.getPath(getActivity(), data.getData()) == null) {
imageCapture.onImageCaptured(data.getData().toString(), true);
} else {
imageCapture.onImageCaptured(FileUtils.getPath(getActivity(), data.getData()), false);
}
}
this.dismissAllowingStateLoss();
}
Also, I didn't found how to get URI using file provider.
if(SDK_INT >= Build.VERSION_CODES.Q)
photoURI = FileProvider.getUriForFile(requireActivity(), requireActivity().getPackageName(), fileUri);

After seeing multiple answers, developer docs, and many more. I ended up with this below working solution, Hope this will help someone.
AndroidManifest
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"/>
android:requestLegacyExternalStorage="true"
<provider
android:name=".util.GenericFileProvider"
android:authorities="${applicationId}.provider.profile"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
PictureSelectorDialog.java
public static final int REQUEST_CODE_CAMERA_PICTURE = 1232;
public static final int REQUEST_CODE_GALLERY_PICTURE = 1233;
private File fileUri;
private ImageCapture imageCapture;
private boolean isDenied = false;
private void openGallery() {
Intent intent;
intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(intent, getString(R.string.choose_from_gallery)), REQUEST_CODE_GALLERY_PICTURE);
}
private void openCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri photoURI = null;
try {
fileUri = Utils.createImageFile(requireContext());
photoURI = FileProvider.getUriForFile(requireContext(), BuildConfig.APPLICATION_ID + ".provider.profile", fileUri);
} catch (IOException e) {
e.printStackTrace();
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, REQUEST_CODE_CAMERA_PICTURE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PictureSelectorDialog.REQUEST_CODE_CAMERA_PICTURE && resultCode == Activity.RESULT_OK) {
imageCapture.onImageCaptured(fileUri.getAbsolutePath(), false);
} else if (requestCode == PictureSelectorDialog.REQUEST_CODE_GALLERY_PICTURE && resultCode == Activity.RESULT_OK) {
if (FileUtils.getPath(getActivity(), data.getData()) == null) {
Uri uri = data.getData();
ParcelFileDescriptor parcelFileDescriptor;
try {
parcelFileDescriptor = requireContext().getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
File tempFile = createImageFile(requireContext());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100 , bos);
byte[] bitmapData = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(bitmapData);
imageCapture.onImageCaptured( tempFile.getAbsolutePath(), true);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
imageCapture.onImageCaptured(FileUtils.getPath(getActivity(), data.getData()), false);
}
}
this.dismissAllowingStateLoss();
}
public interface ImageCapture {
void onImageCaptured(String path, boolean isGooglePhotoURI);
}
Utils.java
public static File createImageFile(Context context) throws IOException {
String timeStamp = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS_FOR_IMAGE_NAMING, Locale.getDefault()).format(new Date());
String imageFileName = "PROFILE_PICTURE_" + timeStamp;
File image, storageDir;
if (SDK_INT < Build.VERSION_CODES.Q) {
storageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + YOUR_FOLDER_NAME);
if (!storageDir.exists()) {
storageDir.mkdirs();
}
image = new File(storageDir, imageFileName + ".jpg");
image.createNewFile();
} else {
storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES + File.separator + YOUR_FOLDER_NAME);
image = File.createTempFile(imageFileName, ".jpg", storageDir);
String currentPhotoPath = image.getAbsolutePath();
}
return image;
}

Related

How to not save image captured with camera in an self made folder?

Hello everyone! I am using a camera which saves photo's in the phones gallery. But I don't want to save the photo in the gallery. I want to save it somewhere else. So all i need is not to save it automatically in the gallery.
This is my code:
public class MainActivity extends AppCompatActivity {
ImageView photo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button click = (Button)findViewById(R.id.btnPhoto);
photo = (ImageView) findViewById(R.id.imgPhoto);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
photo.setImageBitmap(bitmap);
}
}
If my question is not good enough, please ask me! And please help me out.
This method for open camera and path is File declare global.
private void openCamera() {
Logger.i("openCamera");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(this.getPackageManager()) != null) {
File rootPath = new File(Environment.getExternalStorageDirectory(), "folderName");
if (!rootPath.exists())
rootPath.mkdirs();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd-kk-mm-ss");
String snapshotImage = df.format(new Date()) + ".jpg";
rootPath = new File(rootPath + "/" + snapshotImage);
path = rootPath;
takePictureIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(path));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
get result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
FileOutputStream fos = null;
try {
// Float Latitude=0.0f, Longitude=0.0f;
imageDvr.setImageURI(Uri.parse(path.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
}
}
}
}
and also give per\mission in manifest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
You will get the bitmap of image in onActivityResult(), and you will store that Image by bitmap.
Use below function to store image on your self made folder. you need to make that folder and need to use path of that.
like this.
public void SaveImage(Bitmap showedImgae){
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/YourSelfMadeFolder");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "FILENAME-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
showedImgae.compress(Bitmap.CompressFormat.JPEG, 100, out);
Toast.makeText(activityname.this, "Image Saved", Toast.LENGTH_SHORT).show();
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
getApplicationContext().sendBroadcast(mediaScanIntent);
}
You can add intent android.provider.MediaStore.EXTRA_OUTPUT with your URI:
private File getOutputMediaFile() {
File mediaStorageDir = null;
String state = Environment.getExternalStorageState();
if (state.contains(Environment.MEDIA_MOUNTED)) {
mediaStorageDir = new File(Environment
.getExternalStorageDirectory().toString() + "/yourFolderName");
} else {
mediaStorageDir = new File(Environment
.getExternalStorageDirectory().toString() + "/yourFolderName");
}
if (!mediaStorageDir.exists()) {
Logger.d("Desc", "File dir " + mediaStorageDir.mkdirs());
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"Image_" + timeStamp + ".jpg");
return mediaFile;
}
your button click:
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Uri mImageCaptureUri = null;
File mediaFile = getOutputMediaFile();
mImageCaptureUri = Uri.fromFile(mediaFile);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
this.startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
}}0;
on activity result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("FilePath","Path"+mediaFile.getAbsolutePath();)
}

Android Studio save image into new directory [duplicate]

I need to save the pictures taken with my app in an specific folder. I've read many solutions to this problem but I couldn't make any of them work so I ask for help.
MainActivity.java
public void onClick(View v) {
Intent camera = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//Folder is already created
String dirName = Environment.getExternalStorageDirectory().getPath()
+ "/MyAppFolder/MyApp" + n + ".png";
Uri uriSavedImage = Uri.fromFile(new File(dirName));
camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(camera, 1);
n++;
}
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Go through the following code , its working fine for me.
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File("/sdcard/DirName/", fileName);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I have used mdDroid's code like this:
public void startCamera() {
// Create photo
newPhoto = new Photo();
newPhoto.setName(App.getPhotoName());
//Create folder !exist
String folderPath = Environment.getExternalStorageDirectory() + "/PestControl";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdirs();
}
//create a new file
newFile = new File(folderPath, newPhoto.getName());
if (newFile != null) {
// save image here
Uri relativePath = Uri.fromFile(newFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, relativePath);
startActivityForResult(intent, CAMERA_REQUEST);
}
}
Use Like this. It will work for you.
public void onClick(View v) {
Intent camera = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera, 1);
}
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 1:
if(resultCode == RESULT_OK) {
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//file path of captured image
filePath = cursor.getString(columnIndex);
//file path of captured image
File f = new File(filePath);
filename= f.getName();
Toast.makeText(getApplicationContext(), "Your Path:"+filePath, 2000).show();
Toast.makeText(getApplicationContext(), "Your Filename:"+filename, 2000).show();
cursor.close();
//Convert file path into bitmap image using below line.
// yourSelectedImage = BitmapFactory.decodeFile(filePath);
Toast.makeText(getApplicationContext(), "Your image"+yourSelectedImage, 2000).show();
//put bitmapimage in your imageview
//yourimgView.setImageBitmap(yourSelectedImage);
Savefile(filename,filePath);
}
}
}
public void Savefile(String name, String path) {
File direct = new File(Environment.getExternalStorageDirectory() + "/MyAppFolder/MyApp/");
File file = new File(Environment.getExternalStorageDirectory() + "/MyAppFolder/MyApp/"+n+".png");
if(!direct.exists()) {
direct.mkdir();
}
if (!file.exists()) {
try {
file.createNewFile();
FileChannel src = new FileInputStream(path).getChannel();
FileChannel dst = new FileOutputStream(file).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope this will help you. for reference to use camera intent.
Here You Go. I tried the above solution they save the image to gallery but the image is not visible , a 404 error is visible on the image , and i figured it out .
public void addToFav(String dirName, Bitmap bitmap) {
String resultPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES)+
dirName + System.currentTimeMillis() + ".jpg";
Log.e("resultpath",resultPath);
new File(resultPath).getParentFile().mkdir();
if (Build.VERSION.SDK_INT < 29){
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Photo");
values.put(MediaStore.Images.Media.DESCRIPTION, "Edited");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put("_data", resultPath);
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try {
OutputStream fileOutputStream = new FileOutputStream(resultPath);
bitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
if(fileOutputStream != null){
Toast.makeText(this, "Image Saved", Toast.LENGTH_SHORT).show();
}
} catch (IOException e2) {
e2.printStackTrace();
}
}else {
OutputStream fos = null;
File file = new File(resultPath);
final String relativeLocation = Environment.DIRECTORY_PICTURES;
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation+"/"+dirName);
contentValues.put(MediaStore.MediaColumns.TITLE, "Photo");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
contentValues.put(MediaStore.MediaColumns.DATE_TAKEN, System.currentTimeMillis ());
contentValues.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis());
contentValues.put(MediaStore.MediaColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
contentValues.put(MediaStore.MediaColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
final ContentResolver resolver = getContentResolver();
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri uri = resolver.insert(contentUri, contentValues);
try {
fos = resolver.openOutputStream(uri);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
if(fos != null){
Toast.makeText(this, "Image Saved", Toast.LENGTH_SHORT).show();
}
}
}
I have found an easier code to do it.
This is the code for creating the image folder:
private File createImageFile(){
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/App Folder/";
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "AppName_" + timeStamp;
String file = dir +imageFileName+ ".jpg" ;
File imageFile = new File(file);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = imageFile.getAbsolutePath();
return imageFile;
}
,And this is the code for launching the camera app and take the photo:
public void lunchCamera() {
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 = createImageFile();
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.ziad.sayit",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
Useful link for different ways of doing it: https://www.programcreek.com/java-api-examples/?class=android.os.Environment&method=getExternalStoragePublicDirectory

Save Custom name for picture via camera intent in DCIM/pictures

I have followed and literally picked up code from other answers but its still not working.
When a picture is clicked, it's saved by default in DCIM/camera with name such as 20150910_111841.jpg (date_timeInMilliseconds) but I want to save it as "myName_date.jpg".
public void OnClick(){
if (items[item].equals("Take Photo")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
f = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
mMediaUri=Uri.fromFile(new File(f, "MEDIT"+System.currentTimeMillis()+"jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==RESULT_OK){
switch(requestCode) {
case REQUEST_IMAGE_CAPTURE:
Bitmap bm = BitmapFactory.decodeFile(mMediaUri.getPath());
//imgVIew.setImageBitmap(bm);
Bitmap scaledBitmap=ScaleImage(bm);
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
scaledBitmap.compress(Bitmap.CompressFormat.JPEG,100, bos);
//Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(bos.toByteArray()));
imgVIew.setImageBitmap(scaledBitmap);
imageView.setImage(ImageSource.bitmap(scaledBitmap));
imageView1.setImage(ImageSource.bitmap(bm));
break;
case REQUEST_GALLERY:
//Uri selectedImage = imageReturnedIntent.getData();
//imageview.setImageURI(selectedImage);
break;
}//Close switch statement
}else {
Log.d("Error ", "user canceled !");
}
}
I have not yet added code for the gallery part but that shouldn't be a problem. As of now no matter what I do its being saved as default but I realized if people don't have an SD card then it can cause an issue. I'd rather have this picture available, in the default DCIM location but with a custom name. Thanks!
Try the below code to save the image with the name you want:
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
/*
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
*/
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "the_name_of_directory");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("canberra trailpass", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"myName"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
To use a custom name, replace this -
mMediaUri=Uri.fromFile(new File(f, "MEDIT"+System.currentTimeMillis()+"jpg"));
With this -
mMediaUri=Uri.fromFile(new File(f, "MEDIT"+"Your Custom Name"+System.currentTimeMillis()+"jpg"));
It will like, this
File fPath = getAlbumStorageDir("myName_date");
File f = new File(fPath, "myName_date" + Calendar.getInstance().getTimeInMillis() + ".jpg");
It's not a device problem,
as example my working code, i have achieve like this,
public static Uri getUri(String filePath) {
File media = new File(filePath);
Uri uri = Uri.fromFile(media);
return uri;
}
public static File getAlbumStorageDir(String albumName) {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (file.exists()) {
Log.d(LOGTAG, "storeage file exists");
}
if (!(file.mkdirs() || file.isDirectory())) {
Log.e(LOGTAG, "Directory not created");
}
return file;
}
public static class SaveImageTask extends AsyncTask<Bitmap, Void, String> {
private SaveImageListener listener;
public SaveImageTask(SaveImageListener listener) {
this.listener = listener;
}
#Override
protected String doInBackground(Bitmap... params) {
Bitmap bitmapToSave = params[0];
File fPath = getAlbumStorageDir("AppName");
File f = new File(fPath, "AppName" + Calendar.getInstance().getTimeInMillis() + ".jpg");
String filePath = null;
try {
FileOutputStream strm = new FileOutputStream(f);
bitmapToSave.compress(Bitmap.CompressFormat.JPEG, 100, strm);
strm.close();
filePath = f.getPath();
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
#Override
protected void onPostExecute(String filePath) {
super.onPostExecute(filePath);
listener.onImageSaved(filePath);
}
interface SaveImageListener {
void onImageSaved(String filePath);
}
}
Uri mImageCaptureUri;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mImageCaptureUri = Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "example.jpg"));
takePictureIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
startActivityForResult(takePictureIntent, 1);
onActivityResult :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK) {
switch (requestCode) {
case 1:
if(mImageCaptureUri!=null) {
imageName = "";
Bitmap bitmap = getCameraImage(activity, mImageCaptureUri);
imgView.setImageBitmap(bitmap );
removeFile(mImageCaptureUri.getPath());
break;
}
}
}
get camera image :
public static Bitmap getCameraImage(Activity activity, Uri mImageCaptureUri){
if(mImageCaptureUri==null) {
return null;
} else {
activity.getContentResolver().notifyChange(mImageCaptureUri, null);
ContentResolver cr = activity.getContentResolver();
Bitmap bitmap = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 6;
AssetFileDescriptor fileDescriptor =null;
fileDescriptor =
cr.openAssetFileDescriptor( mImageCaptureUri, "r");
bitmap
= BitmapFactory.decodeFileDescriptor(
fileDescriptor.getFileDescriptor(), null, options);
//bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageCaptureUri);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}

why does mediastore take the last-1th picture from the gallery

Hello!
I have a problem between the picture gallery and the mediastore in my android application when i use the camera intent in my fragment.
I checked on the android website to learn how to take a picture in a fragment and on some forums to know how to get the last picture took but the media store always give me the last-1th picture as if it was not able to find the last picture.
This is my code :
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.i(LOG_TAG,"ERRRRROR: "+ex.toString());
}
if (photoFile != null) {
mCurrentPhotoPath = "file:" +photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQ_CAMERA_PICTURE);
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mCurrentPhotoUri = contentUri;
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
Log.d(LOG_TAG,"Photo SAVED");
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
mCurrentPhotoAbsolutePath = image.getAbsolutePath();
Log.i(LOG_TAG,"image path : "+image.getAbsolutePath());
return image;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQ_CAMERA_PICTURE)
{
if (resultCode == Activity.RESULT_OK)
{
galleryAddPic();
String filePath = getActivity().getPreferences(Context.MODE_PRIVATE).getString(TMP_PHOTO_FILE_LATEST_KEY, null);
handleCameraPicture(mCurrentPhotoUri.toString());
}
else
{
clearCurrentActionData();
}
}
}
private String getLastImagePath() {
String[] projection = new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE
};
final Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
if (cursor.moveToFirst()) {
String imageLocation = cursor.getString(1);
File imageFile = new File(imageLocation);
Bitmap bm = BitmapFactory.decodeFile(imageLocation);
return imageFile.getPath().toString();
}
else{
return "";
}
}
The problem occurs HERE when i try to get the last image path
private void handleCameraPicture(String pictureFileUri)
{
_currentDataObjectBuilder.addParameter(DataObject.Parameter.IMAGE, String.valueOf(getFileCount()));
//create a copy of the file into the internal storage
final File pictureFile = new File(pictureFileUri);
Log.d(LOG_TAG,"picture file uri : "+pictureFileUri.toString());
FileOutputStream fos =null;
byte[] pictureData = new byte[0];
try
{
pictureData = compressImage(getLastImagePath());
fos = getActivity().openFileOutput(String.valueOf(getFileCount()), Context.MODE_PRIVATE);
fos.write(pictureData);
Log.i(LOG_TAG,"SETTING FILE OUTPUT STREAM");
}
catch (IOException e)
{
e.printStackTrace();
}
finally {
try {
fos.close();
pictureFile.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
if (_currentAction.equals(Action.PICTURE_CAPTION) || _currentAction.equals(Action.ARCHIVE))
{
showMessageView();
}
else
{
sendCurrentActionData();
}
}
The handleCameraPicture function allows me to send the "last picture" to an external website.
I don't know what i do wrong so please help me! I'm gonna lose my mind else...
Thank you!
Thomas
Wouw!
I finally found the solution, actually the uri when i created the picture was different from the one when i tried to save the picture in the gallery so my cursor dropped a null pointer exception.
I updated my GalleryAddPic function to
private void galleryAddPic(Uri uri) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mCurrentPhotoUri = uri;
mediaScanIntent.setData(uri);
getActivity().sendBroadcast(mediaScanIntent);
Log.d(LOG_TAG,"Photo SAVED");
}
And now everything works fine!

Android - Save images in an specific folder

I need to save the pictures taken with my app in an specific folder. I've read many solutions to this problem but I couldn't make any of them work so I ask for help.
MainActivity.java
public void onClick(View v) {
Intent camera = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//Folder is already created
String dirName = Environment.getExternalStorageDirectory().getPath()
+ "/MyAppFolder/MyApp" + n + ".png";
Uri uriSavedImage = Uri.fromFile(new File(dirName));
camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(camera, 1);
n++;
}
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Go through the following code , its working fine for me.
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File("/sdcard/DirName/", fileName);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I have used mdDroid's code like this:
public void startCamera() {
// Create photo
newPhoto = new Photo();
newPhoto.setName(App.getPhotoName());
//Create folder !exist
String folderPath = Environment.getExternalStorageDirectory() + "/PestControl";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdirs();
}
//create a new file
newFile = new File(folderPath, newPhoto.getName());
if (newFile != null) {
// save image here
Uri relativePath = Uri.fromFile(newFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, relativePath);
startActivityForResult(intent, CAMERA_REQUEST);
}
}
Use Like this. It will work for you.
public void onClick(View v) {
Intent camera = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera, 1);
}
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 1:
if(resultCode == RESULT_OK) {
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//file path of captured image
filePath = cursor.getString(columnIndex);
//file path of captured image
File f = new File(filePath);
filename= f.getName();
Toast.makeText(getApplicationContext(), "Your Path:"+filePath, 2000).show();
Toast.makeText(getApplicationContext(), "Your Filename:"+filename, 2000).show();
cursor.close();
//Convert file path into bitmap image using below line.
// yourSelectedImage = BitmapFactory.decodeFile(filePath);
Toast.makeText(getApplicationContext(), "Your image"+yourSelectedImage, 2000).show();
//put bitmapimage in your imageview
//yourimgView.setImageBitmap(yourSelectedImage);
Savefile(filename,filePath);
}
}
}
public void Savefile(String name, String path) {
File direct = new File(Environment.getExternalStorageDirectory() + "/MyAppFolder/MyApp/");
File file = new File(Environment.getExternalStorageDirectory() + "/MyAppFolder/MyApp/"+n+".png");
if(!direct.exists()) {
direct.mkdir();
}
if (!file.exists()) {
try {
file.createNewFile();
FileChannel src = new FileInputStream(path).getChannel();
FileChannel dst = new FileOutputStream(file).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope this will help you. for reference to use camera intent.
Here You Go. I tried the above solution they save the image to gallery but the image is not visible , a 404 error is visible on the image , and i figured it out .
public void addToFav(String dirName, Bitmap bitmap) {
String resultPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES)+
dirName + System.currentTimeMillis() + ".jpg";
Log.e("resultpath",resultPath);
new File(resultPath).getParentFile().mkdir();
if (Build.VERSION.SDK_INT < 29){
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Photo");
values.put(MediaStore.Images.Media.DESCRIPTION, "Edited");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put("_data", resultPath);
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try {
OutputStream fileOutputStream = new FileOutputStream(resultPath);
bitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
if(fileOutputStream != null){
Toast.makeText(this, "Image Saved", Toast.LENGTH_SHORT).show();
}
} catch (IOException e2) {
e2.printStackTrace();
}
}else {
OutputStream fos = null;
File file = new File(resultPath);
final String relativeLocation = Environment.DIRECTORY_PICTURES;
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation+"/"+dirName);
contentValues.put(MediaStore.MediaColumns.TITLE, "Photo");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
contentValues.put(MediaStore.MediaColumns.DATE_TAKEN, System.currentTimeMillis ());
contentValues.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis());
contentValues.put(MediaStore.MediaColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
contentValues.put(MediaStore.MediaColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
final ContentResolver resolver = getContentResolver();
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri uri = resolver.insert(contentUri, contentValues);
try {
fos = resolver.openOutputStream(uri);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
if(fos != null){
Toast.makeText(this, "Image Saved", Toast.LENGTH_SHORT).show();
}
}
}
I have found an easier code to do it.
This is the code for creating the image folder:
private File createImageFile(){
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/App Folder/";
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "AppName_" + timeStamp;
String file = dir +imageFileName+ ".jpg" ;
File imageFile = new File(file);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = imageFile.getAbsolutePath();
return imageFile;
}
,And this is the code for launching the camera app and take the photo:
public void lunchCamera() {
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 = createImageFile();
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.ziad.sayit",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
Useful link for different ways of doing it: https://www.programcreek.com/java-api-examples/?class=android.os.Environment&method=getExternalStoragePublicDirectory

Categories

Resources