Reputation: 433
I am attaching the Bitmap to the Imageview by storing in the MediaStore. It works fine in all the device below android 10, but when crash occured in pixel. My android id targeted to sdk 28
try {
Bitmap thePic = MediaStore.Images.Media.GetBitmap(ContentResolver, croppedPicUri);
if(thePic != null){
imgProfileIcon.SetImageBitmap(thePic);
//mediaStorageDir = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDcim);
mediaStorageDir = GetExternalFilesDir(Environment.DirectoryPictures);
if (!mediaStorageDir.Exists())
{
mediaStorageDir.Mkdirs();
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").Format(new Java.Util.Date());
sendFile = new File(mediaStorageDir.Path + File.Separator + "IMG_" + timeStamp + ".png");
String path_ = MediaStore.Images.Media.InsertImage(this.ContentResolver, thePic, "Title", null);
if (path_ != null){
Uri tempUri = Uri.Parse(path_);
path = GetPathToImage(tempUri);
}
}
} catch (Exception ex) {
Toast.MakeText(this, "Bundle extras : " + ex.Message, ToastLength.Short).Show();
}
{Java.Lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures Title image/jpeg at Java.Interop.JniEnvironment+StaticMethods.CallStaticObjectMethod (Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <205bc242eb64455b94479843fca3eeb7>:0 at Java.Interop.JniPeerMembers+JniStaticMethods.InvokeObjectMethod (System.String encodedMember, Java.Interop.JniArgumentValue* parameters) [0x00018] in <205bc242eb64455b94479843fca3eeb7>:0 at Android.Provider.MediaStore+Images+Media.InsertImage (Android.Content.ContentResolver cr, Android.Graphics.Bitmap source, System.String title, System.String description) [0x0008d] in <072ebd6d3ae947ac8b3980f8fd1aeee1>:0 at EventApp.ProfileListActivity.OnActivityResult (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data) [0x00200] in D:\EventApp\EventApp\Activity\ProfileListActivity.cs:1310 --- End of managed Java.Lang.IllegalStateException stack trace --- java.lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures Title image/jpeg at android.os.Parcel.createException(Parcel.java:2079) at android.os.Parcel.readException(Parcel.java:2039) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140) at android.content.ContentProviderProxy.insert(ContentProviderNative.java:481) at android.content.ContentResolver.insert(ContentResolver.java:1828) at android.provider.MediaStore.createPending(MediaStore.java:616) at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:1771)
Upvotes: 5
Views: 4288
Reputation: 787
Let's consider:
MediaStore.Images.Media.insertImage(ContentResolver cr, Bitmap source, String title, String description)
Let's apply it to a real example:
MediaStore.Images.Media.insertImage(context.getContentResolver(), imageToSave, "ThisIsImageTitleString", null);
You will notice that this safely saves any type of bitmap in memory. But how is the output bitmap name?
First time:
ThisIsImageTitleString
Second time:
ThisIsImageTitleString(2)
...
32th time:
ThisIsImageTitleString(32)
33th time:
java.lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures ThisIsImageTitleString image/jpeg
Simple solution: add a timestamp.
Declare this as constant ( static or non static according to what you need )
static Date currentTime;
and then change MediaStore way to save bitmaps to:
MediaStore.Images.Media.insertImage(context.getContentResolver(), imageToSave, "ThisIsImageTitleString" + " - " + (currentTime = Calendar.getInstance().getTime()), null);
Please note: (currentTime = Calendar.getInstance().getTime())
Upvotes: 8
Reputation: 58
replace "Title" to File.separator + "IMG_" + timeStamp + ".png
eg.String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, File.separator + "IMG_" + timeStamp + ".png", null);
Upvotes: 1
Reputation: 21
I figured out that while saving image via MediaStore.Images.Media.insertImage(ContentResolver cr, Bitmap source, String title, String description)
method, title
param must be specified explicitly on Android 10. In other way file name will look like this: Image
. Every next image will be saved as Image (n)
. App throws an error after n
reaches value of 32.
Upvotes: 2
Reputation: 378
As far as I know, this method is deprecated in API 29.
https://developer.android.com/reference/android/provider/MediaStore.Images.Media
insertImage(ContentResolver cr, String imagePath, String name, String description)
This method was deprecated in API level 29. inserting of images should be performed using MediaColumns#IS_PENDING, which offers richer control over lifecycle.
You should use MediaColumns#IS_PENDING for the devices using API 29+.
More info: https://developer.android.com/training/data-storage/files/media#pending-media-files
Upvotes: -1
Reputation: 31
Change/Create file with the use of math's random function rather then time stamp and make sure it FileOutputStream object is going to flush. for the reference,
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
if (!myDir.exists()) {
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();
}
}
Upvotes: 3