在Android 4.3中将位图保存到磁盘/图库

7

我一直使用系统保存截图的方式来保存位图到磁盘和相册。这在Android 4.2及之前的版本中可以工作,但在Android 4.3中不能工作。

相关代码:

Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
OutputStream out = resolver.openOutputStream(uri);

完整代码在这里

然而,在4.3(新的Nexus 7)中,我在第二行得到了FileNotFoundException。我在网站上没有看到任何与此相关的4.3更改。

那么,将图像保存到磁盘和图库的正确方法是什么?

已验证:

  • 使用此方法挂载存储
  • imageUri不为null(通常类似于“content://media/external/images/media/2034”)
  • 清单具有android.permission.WRITE_EXTERNAL_STORAGE权限

你在使用HTC进行测试吗? - Pulkit Sethi
你的模拟器是否已经挂载了SD卡?我的意思是,有时候会忘记启用SD卡模拟。 :) 你能否检查文件是否存在,如果不存在,则创建临时文件并将其写入从ContentResolver获取的输出流中? - Nikola Despotoski
logcat 有没有告诉你任何相关的信息? - Yusuf X
你解决了吗?MediaStore.Images.Media.insertImage(ContentResolver cr,Bitmap source,String title,String description)用于存储位图,Nexus 7上的错误相同。 - Yar
为了临时解决问题,我明确调用folder.mkdirs()来保存路径。 - f2prateek
显示剩余5条评论
4个回答

1
这是我将位图保存到画廊的方式:

bitmaps :

Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri; //instantiate Uri with location of image
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);

这与在相册中存储位图相关吗?我的意思是 MediaStore.Images.Media.insertImage (ContentResolver cr, Bitmap source, String title, String description)。 - Yar
@Yar,是的 - 这做的是完全相同的事情,只是以不同的方式 - 通过广播一个意图,告诉系统将包含图像位置的给定 URI 添加到相册中。 - Phil
那么,如果我有一个原始位图,我应该将其存储在SD卡的某个位置,然后广播意图吗?将Uri设置为我的新文件? - Yar
@Yar 是的,那正是你应该做的。 - Phil

0

我在我的清单文件中拥有这些权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

但我正在使用目标SDK版本15。是否有必须使用目标SDK 18的要求?

另外:

下面是一个从Facebook下载个人资料图片的示例代码:

private class DownloadProfilePicTask extends AsyncTask<Void,String,String> {
    Bitmap profilePic;
    String fileName;
    String id;
    String type;
    URL img_value;
    public DownloadProfilePicTask(String i,String ty)
    {
        id = i;
        if(id==null)
        {
            //Log.v("Id is null", "Error");
        }
        //Log.v("Download Profile Pic Task initialized for id:",id);
        type = ty;
    }
    @Override
    protected String doInBackground(Void...param) {
         String root = Environment.getExternalStorageDirectory().toString();
         if(root==null)
         {
             return null;
         }
         try{
         profilePic = BitmapFactory.decodeStream(img_value.openConnection().getInputStream());
         }
         catch (IOException e) {
             e.printStackTrace();

         }

        if(profilePic == null)
        {
            //Log.v("profilePic is null", "Error");
        }
         //Log.v("Root for saving images",root );
         File myDir = new File(root + "/saved_images");
         myDir.mkdirs();
        fileName = root + "/saved_images/" + id + ".png";
        //Log.v("filename is ",fileName);
         File file = new File (fileName); 
         fileName = file.getPath();
         if (file.exists ()) file.delete (); 
         try {
                FileOutputStream out = new FileOutputStream(file);
                profilePic.compress(Bitmap.CompressFormat.PNG, 90, out);
                out.flush();
                out.close();
         } catch (Exception e) {
                e.printStackTrace();
         }
         return id;
    }
    @Override
    protected void onPreExecute()
    {
        try
        {
            img_value = new URL("http://graph.facebook.com/"+id+"/picture?type=" + type);
        }
         catch (MalformedURLException e) {
                e.printStackTrace();

        } 

    }
    @Override
    protected void onPostExecute(String result) {
    }
}

然后我只需要调用:

new DownloadProfilePicTask(id,type).execute();

用于下载和自动保存图像。

注意:要精确确定filePath的位置,您需要进行一些调整。


0
在你的清单文件中尝试将目标 SDK 更改为 18。
  <uses-sdk android:minSdkVersion="7" 
    android:targetSdkVersion="18"/>

它可能会解决你的问题(也可能不会)。在4.3 JELLY_BEAN_MR2中,android做了一些更改,并明确指出您的应用程序可能无法在受限制的配置文件环境中正常工作。因此,请参阅http://developer.android.com/about/versions/android-4.3.html


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接