在content provider中使用二进制数据

在android的sqlite中,如果要处理二进制数据,就要用到blob类型。这也可以运用到content provider中。

实现了一个超丑陋的示例,在编写完整的Content provider示例基础上。

image

实现这个小示例,需要几个技术点,下面依次介绍。

在SQLite数据库中插入图片数据

首先要说图片来源,为了简单起见,放在res/raw目录下了。正式开发,可能是通过网络或者sdcard上获取。

image

如何把这几张图片插入到表中?

表结构中增加blog类型的image列:

database.execSQL("create table if not exists emperors("
                    + " id integer primary key autoincrement," + " name text,"
                    + "dynasty text," + "start_year text," + "image blob"
                    + ");");

插入一条记录的代码:

SQLiteStatement statement = database
        .compileStatement("insert into emperors(name,dynasty,start_year,image) values(?,?,?,?)");
int index = 1;
statement.bindString(index++, "朱元璋");
statement.bindString(index++, "明");
statement.bindString(index++, "1398");
statement.bindBlob(index++, getImageData(R.raw.e1));
statement.execute();

在getImageData()方法中生成图的byte数组:

private byte[] getImageData(int rawId) {
    InputStream inputStream = context.getResources().openRawResource(
            rawId);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] data = new byte[1024 * 100];

    try {
        for (int i = inputStream.read(data); i > 0; i = inputStream
                .read(data)) {
            outputStream.write(data, 0, i);
        }

        inputStream.close();
        data = outputStream.toByteArray();
        outputStream.close();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    return data;

这里有个问题,因为是在Content provider中实现的SQLiteOpenHelper,如何获取context实例,因为不是Activity了,Activity本身就是context实例。好在SQLiteOpenHelper的构造方法中有context实例,需要保持一个context成员变量:

private static class MyDatabaseHelper extends SQLiteOpenHelper {

    private Context context;
    public MyDatabaseHelper(Context context, String name,
            CursorFactory factory, int version) {
        super(context, name, factory, version);
        this.context = context;
    }

Android SQLite API只提供了将byte[]数组作为参数创建blob的方法,因此二进制数据不能太大,否则会OutOfMemery。

读取SQLite中的二进制数据

上面是将数据插入到SQLite数据库中。不论是直接使用SQLite或者通过Content provider,写法是相同的。

下面读取SQLite的二进制数据,直接用数据库和通过content provider就不同了。

如果直接读取SQLite中的二进制数据

可以参见android操作sqlite3的blob字段

通过Content provider

首先要为数据列创建一个常量,和其他content provider列的情况类似:

public static final String IMAGE = "image";

获取到二进制数据:

this.imageView = new ImageView(this);
this.imageView.setImageDrawable(Drawable.createFromStream(
        new ByteArrayInputStream(cursor.getBlob(cursor
                .getColumnIndex(MyContentProvider.IMAGE))),
        "image.png"));

完整源代码见:

http://easymorse.googlecode.com/svn/tags/content.provider-0.4.0/

PDF下載    发送文章为PDF   

这篇文章上的评论的 RSS feed TrackBack URI

Leave a Reply