您的位置:首页 > 移动开发 > Android开发

Android-编写简单的Content Provider

2014-04-28 15:17 435 查看
在自己的android应用中存储数据,可以用SQLite数据库。不过,如果需要在多个应用中共享数据,在Android中,只有通过Content provider机制。

下面用一个最简单(不完整)的示例来说明Content Provider的创建。在界面中使用这个示例显示的效果:





显示帝王姓名、登基年份和朝代。

在这个简单示例中,包括两部分:

创建一个Content Provider;
使用这个Content Provider(目前是在同一个应用中,可以在其他应用中以相同方式调用)。

创建一个简陋的Content Provider

content provider通过抽象一致的接口,供其他开发者使用Content provider,而实现Content provider,既可以用sqlite3这样的android内置数据库,也可以使用文件系统,甚至可以自己写其他的实现,只要实现规定的接口即可。

实现一个Content provider,需要做:

继承ContentProvider,实现该类的几个抽象方法;
在manifest文件中声明这个Content provider。
实现的Content provider代码:

package com.easymorse.cp;

 

import android.content.ContentProvider;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteStatement;

import android.net.Uri;

 

public class MyContentProvider extends ContentProvider {

 

    public static final Uri CONTENT_URI = Uri.parse("content://com.easymorse.cp.mycp");

 

    public static final String _ID = "id";

 

    public static final String NAME = "name";

 

    public static final String DYNASTY = "dynasty";

 

    public static final String START_YEAR = "start_year";

 

    private static SQLiteDatabase database;

 

    private static void createTablesIfNotExists() {

        database.execSQL("create table if not exists emperors("

                + " id integer primary key autoincrement," + " name text,"

                + "dynasty text," + "start_year text" + ");");

 

        SQLiteStatement statement = database

                .compileStatement("insert into emperors(name,dynasty,start_year) values(?,?,?)");

        int index = 1;

        statement.bindString(index++, "朱元璋");

        statement.bindString(index++, "明");

        statement.bindString(index++, "1398");

        statement.execute();

 

        index = 1;

        statement.bindString(index++, "玄烨");

        statement.bindString(index++, "清");

        statement.bindString(index++, "1722");

        statement.execute();

 

        statement.close();

    }

 

    @Override

    public int delete(Uri uri, String selection, String[] selectionArgs) {

        return 0;

    }

 

    @Override

    public String getType(Uri uri) {

        return null;

    }

 

    @Override

    public Uri insert(Uri uri, ContentValues contentValues) {

        // TODO Auto-generated method stub

        return null;

    }

 

    @Override

    public boolean onCreate() {

        if (database == null) {

            database = this.getContext().openOrCreateDatabase("emperors",

                    Context.MODE_PRIVATE, null);

            createTablesIfNotExists();

        }

        return database != null;

    }

 

    @Override

    public Cursor query(Uri uri, String[] projection, String selection,

            String[] selectionArgs, String sortOrder) {

        Cursor cursor = database.rawQuery("select * from emperors", null);

        return cursor;

    }

 

    @Override

    public int update(Uri uri, ContentValues contentValues, String selection,

            String[] selectionArgs) {

        // TODO Auto-generated method stub

        return 0;

    }

}



需要实现的方法是:

query() <<

insert()

update()

delete()

getType()

onCreate()<<

在本例中值实现了标注<<的方法。

onCreate方法是创建Content provider时,android调用的。创建Content provider时,本例检查是否创建emperors表,没有就创建一个,并且插入了2条记录。

query方法实现的很简单,只是返回表的所有结果集。

做完这些还不够,还需要声明一些常量:


public static final Uri CONTENT_URI = Uri.parse("content://com.easymorse.cp.mycp");

 

public static final String _ID = "id";

 

public static final String NAME = "name";

 

public static final String DYNASTY = "dynasty";

 

public static final String START_YEAR = "start_year";

CONTENT_URI 是便于Content provider使用者引用的,下面使用Content provider的时候能看到。

另外,要有一个_ID常量,值是具体表的id列名称。

其他几个常量是表中列的对应名称常量。目前没有真的使用。

在manifest文件中的声明:


<application android:icon="@drawable/icon" android:label="@string/app_name">

    <activity android:name=".UseContactActivity" android:label="@string/app_name">

        <intent-filter>

            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />

        </intent-filter>

    </activity>

   <provider android:name="com.easymorse.cp.MyContentProvider"

        android:authorities="com.easymorse.cp.mycp"></provider>

</application>

这里的android:name是ContentProvider实现类的类名,android:authorities是CONTENT_URI的值。

使用创建的Content Provider

代码在一个Activity中,通过TextView显示出emperors表中的数据:

package com.easymorse.cp;

 

    import android.app.Activity;

    import android.database.Cursor;

    import android.os.Bundle;

    import android.widget.TextView;

 

    public class UseContactActivity extends Activity {

        /** Called when the activity is first created. */

        @Override

        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

 

            TextView textView = new TextView(this);

            textView.setText(getContentProviderValues());

            this.setContentView(textView);

        }

 

        private String getContentProviderValues() {

            StringBuilder builder = new StringBuilder();

 

            Cursor cursor = managedQuery(MyContentProvider.CONTENT_URI, null, null,

                    null, null);

            while (cursor.moveToNext()) {

                builder

                        .append(

                                cursor.getString(cursor

                                        .getColumnIndex(MyContentProvider.NAME)))

                        .append(" | ")

                        .append(

                                cursor

                                        .getString(cursor

                                                .getColumnIndex(MyContentProvider.START_YEAR)))

                        .append(" | ")

                        .append(

                                cursor.getString(cursor

                                        .getColumnIndex(MyContentProvider.DYNASTY)))

                        .append("\n");

            }

 

            return builder.toString();

        }

    }

主要方法是getContentProviderValues()。通过managedQuery()方法获取到Cursor对象。在方法调用的参数,只用到了MyContentProvider.CONTENT_URI,通过这个参数,android可定位到具体的ContentProvider 并启动它(如果没有启动的话)。后面几个参数类似SQL的SELECT子句、WHERE子句和ORDER BY子句。都不写,将返回全部的结果(其实我这个例子中的Content provider也只实现了返回全部结果的逻辑)。

代码简洁,值得学习。

转自:http://disanji.net/2011/06/10/android-simple-content-provider/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息