如何在安卓系统中使用SharedPreference存储图片?

40

我想在Android中使用SharedPreference保存图片。 我有两个Activity类,当我点击第一个Activity的按钮时,它会调用第二个Activity,并且第二个Activity会在列表视图中显示我偏爱的名称,并将Android壁纸重置为我在第一个Activity中设置为首选壁纸的图片。

第二个Activity的代码如下:

public class PreferencesActivityTest extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


            SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
            String prefName = myPrefs.getString("PREF_USERNAME", "nothing");
            String wallPaper = myPrefs.getString("PREFS_NAME", null);


            if(wallPaper != null) {

                try {

                      Bitmap bm = BitmapFactory.decodeFile("/data/misc/wallpaper/"+wallPaper);
                      Log.d(getClass().getSimpleName(),"Wallpaper name is: "+ wallPaper);
                      setWallpaper(bm);
                      Toast.makeText(this, "Wall paper has been changed." +
                                  "You may go to the home screen to view the same", Toast.LENGTH_LONG).show();
                } 

                catch (FileNotFoundException fe){
                      Log.e(getClass().getSimpleName(),"File not found");
                } catch (IOException ie) {
                      Log.e(getClass().getSimpleName()," IO Exception");
                }

    }


        ArrayList<String> results = new ArrayList<String>();
        results.add("Your Preferred name is: " + prefName);
      this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,results));
    }
第一个活动调用第二个活动,但它没有调用if(wallPaper != null){}。为什么不起作用?

你之前是否使用SharedPreferences.Editor设置过一个名为“PREFS_NAME”的首选项字符串,并确保你调用了commit()方法?为什么要使用MODE_WORLD_READABLE模式?你是希望允许其他应用程序使用你的首选项吗? - Martin Foot
是的,我已经在我的第一个活动类中声明了所有这些。但它仍然没有工作。 - Laxmipriya
请查看此解决方案 https://dev59.com/QWw05IYBdhLWcg3wUAM0#59501186 - VasanthRavichandran
3个回答

87

你需要做的是将图像转换为其 Base64 字符串表示:

Bitmap realImage = BitmapFactory.decodeStream(stream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
realImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);   
byte[] b = baos.toByteArray(); 

String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
textEncode.setText(encodedImage);

SharedPreferences shre = PreferenceManager.getDefaultSharedPreferences(this);
Editor edit=shre.edit();
edit.putString("image_data",encodedImage);
edit.commit();

然后,在检索时,将其转换回位图:

SharedPreferences shre = PreferenceManager.getDefaultSharedPreferences(this);
String previouslyEncodedImage = shre.getString("image_data", "");

if( !previouslyEncodedImage.equalsIgnoreCase("") ){
    byte[] b = Base64.decode(previouslyEncodedImage, Base64.DEFAULT);
    Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
    imageConvertResult.setImageBitmap(bitmap);
}

然而,我必须告诉你 Base64 只在 API8 最近才被包含。如果要针对较低版本的 API 进行开发,您需要先添加它。幸运的是,这个人 已经有了所需的教程。

此外,我在 github 上创建了一个快速且简单的示例


8
尽管帖子似乎是在询问如何做到的,但大量数据存储在SharedPreferences中并非其设计初衷,这一点应该更加明确。尽管在SharedPreferences中存储相当大量的数据是可能的,但文档指出应“仅将SharedPreferences用于基本数据类型”。可以在此处找到关于数据存储的良好概述:http://developer.android.com/guide/topics/data/data-storage.html。 - Martin Foot
3
@MartinFoot,在回答这个问题之前,我完全意识到了这一点。 - ariefbayu

32

不建议将图片存储在共享首选项中,而应将其存储到SD卡中。然后像这样将图像路径(从SD卡)存储到Share preferences中--

    SharedPreferences shre = PreferenceManager.getDefaultSharedPreferences(this);
    Editor edit=shre.edit();
    edit.putString("imagepath","/sdcard/imh.jpeg");
    edit.commit();

然后通过使用这个路径从SD卡中获取图像


4
可以使用图像的base64字符串表示来实现。 - ariefbayu
7
这是一个非常复杂的过程,而SharePreference仅用于存储少量数据,例如用户名和密码。 - Tofeeq Ahmad
8
@Sameer,密码正是你不应该储存在那里的内容。 - Langusten Gustel

3

大家好,我解决了上述问题。我在这里发布我的完整源代码,以便其他人可以使用这个解决方案。

这是我对这个问题的第二种解决方案,我之前发布过一个答案,这是针对同一问题的不同答案。 Android中如何将图像保存到共享偏好设置中 | 具有图像的Android共享偏好设置问题

请按照以下步骤操作:

  1. Declare bitmap and String as static

    public static final String PRODUCT_PHOTO = "photo";
    public static Bitmap product_image;
    
  2. In onCreate() write some code.

    //---------set the image to bitmap
    product_image= BitmapFactory.decodeResource(getResources(), .drawable.logo);
    //____________convert image to string
    String str_bitmap = BitMapToString(product_image);
    //__________create two method setDefaults() andgetDefaults()
    setDefaults(PRODUCT_PHOTO, str_bitmap, this)  
    getDefaults(PRODUCT_PHOTO, this);
    
    1. write below code in methods

    setDefaults();

    public static void setDefaults(String str_key, String value, Context    context)
    {
     SharedPreferences shre = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor edit=shre.edit();
    edit.putString(str_key, value);
    edit.apply();
    }
    

3.2.setDefaults();

   public static String getDefaults(String key, Context context)
   {
    SharedPreferences preferences =            PreferenceManager.getDefaultSharedPreferences(context);
    return preferences.getString(key, null);

   }
  1. BitMapToString();

    public static String BitMapToString(Bitmap bitmap)
    {
    ByteArrayOutputStream baos=new  ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
    byte[] arr = baos.toByteArray();
    return Base64.encodeToString(arr, Base64.DEFAULT);
    }
    

    Now,If You want access this image file in another activity,follow below steps.

  2. Declare String as static

    public static final String PRODUCT_PHOTO = "photo";
    String str_bitmap;
    private  Bitmap bitmap;
    private ImageView  imageView_photo;
    

    In onCreate() :

      //--------get image form previous activity,here ProductActivity is my previous activity.
     str_bitmap =ProductActivity.getDefaults(PRODUCT_PHOTO, this);
     //-------------- decode the string to the bitmap
     bitmap=decodeBase64(str_bitmap);
     //----------- finally set the this image to the Imageview.
     imageView_photo.setImageBitmap(bitmap);
    

用于解码Base64的函数;

     public static Bitmap decodeBase64(String input)
     {
     byte[] decodedByte = Base64.decode(input, 0);
     return BitmapFactory.decodeByteArray(decodedByte, 0,   decodedByte.length);
     }

你的 BitMapToString 方法处理时间非常长。 - fix

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