Android 将图片保存到 SQLite 或 SDCard 或内存中

15

我需要从服务器获取图像和其他数据,然后在列表中显示它们。但是由于记录的数量可能相当大,因此我不确定是否应该将图像保存到SQLite数据库中,将其保存到SDCard中还是保存到内存中。

谢谢, nil


2
你可以将图像路径保存在SQLite数据库中,并轻松检索它。但是,如果不幸删除了已经存储的图像,则需要捕获此情况。如果感兴趣,我可以为您提供示例代码。 - OnkarDhane
我遇到了这个问题,我曾经将图像路径保存到数据库中以提高灵活性和快速工作。我建议不要将二进制值(如图像)保存到数据库中,而是使用内部存储器来保存图像,并使用数据库来保存图像路径。Kurtis Nusbaum 给出的答案解释得很好。 - RobinHood
@nilMoBile,你应该检查一下我的答案,它可能会对你有所帮助 :) - Lucifer
@OnkarDhane,我也在这个项目上工作。如果您能与我分享这个项目的示例代码,我将不胜感激。因为我想将图像路径存储到数据库中(不想使用 blob),但我卡在这里了。 - Krups
5个回答

18

始终养成将图像路径保存到数据库的习惯。对于列表视图,请确保仅使用这些图像的缩略图。这将有助于在列表中快速加载这些图像。

 long selectedImageUri = ContentUris.parseId(Uri.parse(anniEntry.getUri()));
 Bitmap bm = MediaStore.Images.Thumbnails.getThumbnail(
                    mContext.getContentResolver(), selectedImageUri,MediaStore.Images.Thumbnails.MICRO_KIND,
                    null );

这里的anniEntry.getUri()是图片的URI。现在,将它放入第二段代码中,您可以根据需要获取微型或迷你缩略图。


这似乎是一个很好的方法,你有使用缩略图方式的示例吗? - nilMoBile
你必须使用uri来获取位图缩略图。我将在编辑中发布代码。如果您对答案满意,请接受它。 - Shahzad Imam
1
我认为这可能是你的另一个问题,因此最好先搜索一下,如果找不到解决方案,再在 SO 上提出问题。@ nilMoBile - RobinHood

12

将二进制数据(如图像)保存在数据库中通常被认为是不好的做法。出于某些技术原因,在大多数情况下,这实际上会损害您的数据库性能。相反,将要缓存的图像保存到SD卡中,并只在数据库中存储这些图像的文件路径。


1
如果用户删除了我的应用程序中的图像,该怎么办? - Arun kumar
2
如果图像存储在内部存储中,则只能由您的应用程序访问(这意味着用户无法删除它们)。如果您将它们存储在SD卡上,则需要编写代码以处理用户删除您的图像的情况。请查看以下内容,了解如何使用内部存储:http://developer.android.com/training/basics/data-storage/files.html - Kurtis Nusbaum

3

如果您需要下载图像并保存在SD卡中,请按照以下代码:

package com.tablet;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.UnknownHostException;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

/*
 * This class download & store the media in external storage 
 * */
public class DownloadActivity extends Activity {

    private static String fileName = "android.jgp";

    private Button btnDownload;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btnDownload = (Button) findViewById(R.id.download);
        btnDownload.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                // TODO Auto-generated method stub
                download();
            }
        });


    private void download()
    {
        System.out.println("Inside Download");
        try {
            // this is the file you want to download from the remote server
            String path = "http://code.google.com/android/goodies/wallpaper/android-wallpaper5_1024x768.jpg";

            URL u = new URL(path);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            String PATH = "/data/Kamal"
                //Environment.getExternalStorageDirectory()
            // + "/download/";
                    + "/";

            Log.v("log_tag", "PATH: " + PATH);
            File file = new File(PATH);
            file.mkdirs();
            File outputFile = new File(file, fileName);

            FileOutputStream f = new FileOutputStream(outputFile);
            InputStream in = c.getInputStream();
            Log.v("log_tag"," InputStream consist of : "+in.read());
            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = in.read(buffer)) > 0) {
                //System.out.println("Reading byte : "+in.read(buffer));
                f.write(buffer, 0, len1);
            }
            Toast.makeText(this, "Download Completed Successfully @ "+PATH, Toast.LENGTH_LONG).show();
            f.close();


        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(this, "MalformedURLException", Toast.LENGTH_LONG).show();
        } catch (ProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(this, "ProtocolException", Toast.LENGTH_LONG).show();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG).show();
        }catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(this, "UnknownHostException", Toast.LENGTH_LONG).show();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(this, "IOException", Toast.LENGTH_LONG).show();
        }
    }



}

1

这是应用需求和实现的问题。我建议使用内部存储或SD卡来存储图像,并将其路径保存在数据库中。


如果用户外部进入SD卡并删除我的应用程序图像,该怎么办? - Arun kumar
1
是的,SD卡存储空间是被应用程序共享的,因此您可能会删除应用程序图像,所以您可以始终将图像保存到应用程序的私有内存中。就原始问题而言,位图缓存也可以用作附加功能来增强用户体验。 - Relsell

1

存储任何不需要根据应用的查询返回数据子部分行为的重型数据(如图像、视频),不应该存储在数据库中,而只应该存储对该数据的引用。


当移动用户删除我的应用程序图像时,会发生什么? - Arun kumar

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