即使目标 Sdk 设置为 28,在 Android 10 上存储位图时应用程序也会崩溃?

Gop*_*thi 5 android mediastore xamarin.android xamarin

我通过存储在 MediaStore 中将位图附加到 Imageview。它在 android 10 以下的所有设备上都可以正常工作,但是当像素发生崩溃时。我的 android id 定位到 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();
            }
Run Code Online (Sandbox Code Playgroud)

{Java.Lang.IllegalStateException:无法构建唯一文件:/storage/emulated/0/Pictures Title image/jpeg at Java.Interop.JniEnvironment+StaticMethods.CallStaticObjectMethod(Java.Interop.JniObjectReference 类型,Java.Interop.JniMethodInfo 方法, Java.Interop.JniArgumentValue *参数)[0x00069]在<205bc242eb64455b94479843fca3eeb7>:0在Java.Interop.JniPeerMembers + JniStaticMethods.InvokeObjectMethod(System.String encodedMember,Java.Interop.JniArgumentValue *参数)[0x00018]在<205bc242eb64455b94479843fca3eeb7>:0在 Android.Provider.MediaStore+Images+Media.InsertImage (Android.Content.ContentResolver cr, Android.Graphics.Bitmap source, System.String title, System.String description) [0x0008d] 在 <072ebd6d3ae947ac8b3980f8fd1aeee1>:0 在 EventApp.ProfileListActivity .OnActivityResult (System.Int32 requestCode,Android.App.Result resultCode, Android.Content.Intent data) [0x00200] in D:\EventApp\EventApp\Activity\ProfileListActivity.cs:1310 --- 托管 Java.Lang.IllegalStateException 堆栈跟踪结束--- java. lang.IllegalStateException:无法构建唯一文件:/storage/emulated/0/Pictures Title image/jpeg at android.os.Parcel.createException(Parcel.java:2079) at android.os.Parcel.readException(Parcel.java: 2039) 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188) 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140) 在 android.content.ContentProviderProxy.insert(ContentProviderNative.java:481) 在 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)

gca*_*oni 7

让我们考虑一下:

MediaStore.Images.Media.insertImage(ContentResolver cr, Bitmap source, String title, String description)
Run Code Online (Sandbox Code Playgroud)

让我们把它应用到一个真实的例子中:

MediaStore.Images.Media.insertImage(context.getContentResolver(), imageToSave, "ThisIsImageTitleString", null);
Run Code Online (Sandbox Code Playgroud)

您会注意到这可以安全地将任何类型的位图保存在内存中。但是输出位图名称如何?

第一次:

这是图像标题字符串

第二次:

ThisIsImageTitleString(2)

...

第32次:

ThisIsImageTitleString(32)

第33次:

java.lang.IllegalStateException:无法构建唯一文件:/storage/emulated/0/Pictures ThisIsImageTitleString image/jpeg

简单的解决方案:添加时间戳

将此声明为常量(根据您的需要静态或非静态)

static Date currentTime;
Run Code Online (Sandbox Code Playgroud)

然后更改 MediaStore 方式以将位图保存到:

MediaStore.Images.Media.insertImage(context.getContentResolver(), imageToSave, "ThisIsImageTitleString" + " - " + (currentTime = Calendar.getInstance().getTime()), null);
Run Code Online (Sandbox Code Playgroud)

请注意: (currentTime = Calendar.getInstance().getTime())


小智 3

使用数学随机函数而不是时间戳来更改/创建文件,并确保 FileOutputStream 对象将被刷新。供参考,

 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();
        }
    }
Run Code Online (Sandbox Code Playgroud)