Android-编写简单的Content Provider
2014-04-28 15:17
435 查看
在自己的android应用中存储数据,可以用SQLite数据库。不过,如果需要在多个应用中共享数据,在Android中,只有通过Content provider机制。
下面用一个最简单(不完整)的示例来说明Content Provider的创建。在界面中使用这个示例显示的效果:
显示帝王姓名、登基年份和朝代。
在这个简单示例中,包括两部分:
创建一个Content Provider;
使用这个Content Provider(目前是在同一个应用中,可以在其他应用中以相同方式调用)。
实现一个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/
下面用一个最简单(不完整)的示例来说明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/
相关文章推荐
- android 编写简单可执行文件
- Android OpenGL 编写简单滤镜
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- Android系统篇之----编写简单的驱动程序并且将其编译到内核源码中
- 关于android中两种service的编写简单总结
- 【android基础】之编写最简单的android谷歌地图应用
- Android编写简单的手机通讯录,只是存到数据库里面,并没有显示出来,下次更新显示到自定义适配器的通讯录(这个只是教大家SQLite数据库如何使用)
- Android自定义半透明背景弹窗非popwindow/dialog超简单任意编写!
- Android简单的编写一个txt阅读器(没有处理字符编码),适用于新手学习
- Android2.3中C++编写的简单的绘图demo
- Android的NDK开发(2)——利用Android NDK编写一个简单的HelloWorld
- android编写简单的Webview
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- Android OpenGL 编写简单滤镜
- Android的NDK开发(2)——利用Android NDK编写一个简单的HelloWorld
- Android APP--编写简单的答题器
- android Jni NDK开发环境搭建及其简单实例的编写
- Android中简单的电话管理与短信管理App编写实例
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- Android编写简单的网络爬虫