I can currently save an image in my app using the Es File explorer to a shared windows folder.
But what I want to know is, how can I eliminate the process of selecting the folder and specify it in code?
public void SaveToNetwork() {
Intent shareIntent = new Intent(Android.Content.Intent.ActionSend);
shareIntent.SetType("*/*");
shareIntent.PutExtra(Android.Content.Intent.ExtraStream, Android.Net.Uri.FromFile(new File(App._dir, App._file.Name)));
shareIntent.SetPackage("com.estrongs.android.pop");
StartActivity(shareIntent);
}
I don't want to use the file explorer. I just want to directly save it to the folder, or at least change the default selected folder to the correct one.
android provides File class and outpustream class for this purpose following is a sample code which recives the bitmap and save it to specified folder and then add you image to gallery content provider
private String savePic(Bitmap bitmapImage) {
try {
//bitmapImage=drawView.getmCanvasBitmap();
File dir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"youfoldername");
dir.mkdir();
Calendar c = Calendar.getInstance();
if (dir.isDirectory()) {
String path = dir.getAbsolutePath() + "/youfilename"
+ c.getTimeInMillis() + ".Jpg";
FileOutputStream fos = new FileOutputStream(path);
// Use the compress method on the BitMap object to write image
// to
// the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, path);
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/Jpg");
intent.putExtra(android.content.Intent.EXTRA_STREAM,
Uri.parse("file://" + path));
startActivity(intent);
return path;
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
Related
I created an example app, which takes pictures and saves them, by following this tutorial. Unfortunately the "Add the photo to a gallery" part is not working. I get no error in logcat. The image is just simply not visible in the gallery. Original code:
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
I tried to solve it, by calling MediaScannerConnection.scanFile:
MediaScannerConnection.scanFile(
getApplicationContext(),
new String[]{f.getAbsolutePath()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.v("MyActivity", "file " + path + " was scanned successfully: " + uri);
}
});
I get this result in logcat:
file /storage/emulated/0/Android/data/com.example.myapplication/files/Pictures/JPEG_20200804_104708_4760605263689075696.jpg was scanned successfully: content://media/external/file/3524
Unfortunately the picture is still not available in the gallery. What do I wrong? How is it possible to debug something like this?
Your link tells you:
Note: If you saved your photo to the directory provided by getExternalFilesDir(), the media scanner cannot access the files because they are private to your app..
Well everybody -until Q- can get access to that dir but apparently the media scanner closes its eyes for it.
But strange that an uri is returned. Try to open it.
You can use this to save the image to the gallery and it will be visible immediately after it is saved
String name = "image_name";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, "Pictures/" + "App Name");
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
OutputStream outputStream = resolver.openOutputStream(Objects.requireNonNull(imageUri));
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream);
outputStream.flush();
outputStream.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, imageUri));
}catch (Exception e){
e.printStackTrace();
Snackbar.make(v, "Unable to Save image " + e.getMessage(), Snackbar.LENGTH_SHORT).show();
}
}else {
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/App Name";
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
}
File imageFile = new File(fullPath, name);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream);
outputStream.flush();
outputStream.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(imageFile)));
}
I got a camera application where, after the user takes an image, I save it to the internal storage in a directory I have made.
All that works fine, the image gets saved there and I can load it and show afterwards, but I'm having trouble saving the image to the Android gallery too.
What I want to, is after saving the image to the internal directory, copy it to the gallery.
I have tried this:
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.Images.Media.SIZE, file.length());
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Where the file is the image I saved in internal storage.
With this method all I get is a broken image in the gallery.
copy it to gallery or show it in android gallery?
if you want the image show in android gallery? you can do this by scan media, this is how to scan:
Uri uri = Uri.fromFile(file);
Intent scanFileIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
sendBroadcast(scanFileIntent);
if you want just copy the file just do this :
in = new FileInputStream(sourceFile);
out = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
You can use this method for saving image:
public void saveToSD(Bitmap outputImage){
File storagePath = new File(Environment.getExternalStorageDirectory() + "/MyPhotos/");
storagePath.mkdirs();
File myImage = new File(storagePath, Long.toString(System.currentTimeMillis()) + ".jpg");
try {
FileOutputStream out = new FileOutputStream(myImage);
outputImage.compress(Bitmap.CompressFormat.JPEG, 80, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
This is what might help :
Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
After getting the path u can store the image by this :
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.Images.Media.SIZE, file.length());
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
context.getContentResolver().insert(imageFile, values);
Hope this helps.
I save an image to the sdcard and it doesn't appear in the Phone's Gallery. I can see saved image in a folder, but it folder doesn't apper in gallery.
My codes here, how fix it?
img_icon.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
img_resim.buildDrawingCache();
Bitmap bm = img_resim.getDrawingCache();
OutputStream fOut = null;
Uri outputFileUri;
try {
root = new File(Environment.getExternalStorageDirectory()
+ File.separator + "folder_name" + File.separator);
root.mkdirs();
File sdImageMainDirectory = new File(root, "myPicName.jpg");
outputFileUri = Uri.fromFile(sdImageMainDirectory);
fOut = new FileOutputStream(sdImageMainDirectory);
} catch (Exception e) {
Toast.makeText(context.getActivity(),
"Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
try {
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
}
context.getActivity()
.sendBroadcast(
new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://"
+ Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES))));
return true;
}
});
return rowView;
}
Thanks for helping..
Your problem lies here:
context.getActivity()
.sendBroadcast(
new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://"
+ Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES))));
You are asking Android to re-index all of the files in Environment.DIRECTORY_PICTURES.
Asking to scan a whole directory tree is wasteful. In your case, it it even more wasteful, since you are not writing your file to that directory. Instead, you are writing that file to:
root = new File(Environment.getExternalStorageDirectory()
+ File.separator + "folder_name" + File.separator);
root.mkdirs();
File sdImageMainDirectory = new File(root, "myPicName.jpg");
Hence, your scan will not pick up this file, which you are writing to some random spot on external storage.
You need to decide the proper place to store your file, then index that one file.
I have a piece of code which basically crops an image selected by the user and is supposed to overwrite the image "CurrentProfilePic.jpg" with the new image.It does so by first deleting the image if it exists and then creating it again.but the image doesnt get deleted.So the no. of times the code is run, that many no. of images are created WITH THE SAME NAME. I used logs to see if the file.delete(); returns true, and it does return true.
public void cropImage(View v) {
bitmap=cropImageView.getCroppedImage();
boolean imageSaved = false;
String imageName="CurrentProfilePic";
//to save current image to directory
if (bitmap != null && !bitmap.isRecycled()) {
File storagePath = new File(
Environment.getExternalStorageDirectory() + "/SimpleMessaging/");
if (!storagePath.exists()) {
storagePath.mkdirs();
}
File temp= new File(Environment.getExternalStorageDirectory() + "/SimpleMessaging/CurrentProfilePic.jpg");
if(temp.exists()){
boolean x= temp.delete();
Log.d("PICS", "Inside if exist of pic");
if(x)
Log.d("bool", "x true");
else
Log.d("bool", "x false");
}
FileOutputStream out = null;
File imageFile = new File(storagePath, String.format("%s.jpg",
imageName));
try {
out = new FileOutputStream(imageFile);
imageSaved = bitmap.compress(Bitmap.CompressFormat.JPEG,
100, out);
out.flush();
out.close();
} catch (Exception e) {
Log.e("SaveToSD ", "Unable to write the image to gallery" + e);
}
ContentValues values = new ContentValues(3);
values.put(Images.Media.TITLE, imageName);
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put("_data", imageFile.getAbsolutePath());
getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
}
startActivity(new Intent(getBaseContext(), EditProfilePic.class));
finish();
}
The thing to stress upon is that the latest image is overwritten on each of those files, but their sizes are unchanged, their original sizes.
Delete getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values); and its supporting code. Use MediaScannerConnection or ACTION_MEDIA_SCANNER_SCAN_FILE to index your file.
I am working on Android for saving multiple image in sd card but its getting save in gallery also and specific folder also...
any one can help on this
thanks..
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
// 2
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
mImage.setImageBitmap(thumbnail);
CharSequence time2 = android.text.format.DateFormat.format(
"yymmddhhmmss", new java.util.Date());
String date1 = time2.toString();
//ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try {
thumbnail .compress(CompressFormat.JPEG, 100, new FileOutputStream(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/mypics/img" + date1 + ".png"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
Toast.makeText(getBaseContext(), "Please take snap again",
Toast.LENGTH_LONG).show();
}
try like this::
Use this function to save your bitmap in SD card
private void SaveIamge(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().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();
}
}
and add this permision in manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
to save in gallery just add this one:
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
If you do not want images inside the /mypics/img/ folder to be shown in the gallery. All you need to do is:
Include an empty file named .nomedia in your /mypcis/img/
directory (note the dot prefix in the filename). This will prevent
Android's media scanner from reading your media files and including
them in apps like Gallery or Music.
Note: For some devices, this only works for new folders (not those which are already scanned) So my recommendation would be to create a new folder with the .nomedia file and store your images to that. Now they will not appear in the gallery. Only in the external SD card folder.