Android之ContentProvider详解

来源:互联网 发布:户外轨迹软件 编辑:程序博客网 时间:2024/04/19 15:19

       ContentProvider为Android四大组件之一,主要用来应用程序之间的数据共享,也就是说一个应用程序用ContentProvider将自己的数据暴露出来,其他应用程序通过ContentResolver来对其暴露出来的数据进行增删改查。

      ContenProvider与ContentResolver之间的对话同过Uri(通用资源标识符),一个不恰当的比喻就好像浏览器要显示一个网页要有一个东西发送请求,这相当于ContentResolver,你要拿东西就要知道去哪里拿,你就得知道服务器的域名或网址,而这个网址就相当于Uri,当到达服务器的时候服务器要有个东西来处理,这就相当于ContenProvider。

 

A程序通过ContenProvider来暴露数据的基本步骤:

   1、实现一个ContenProvider的子类,并重写query,insert,update,delete等这几个方法,

    2、在androidmanifest.xml中注册ContenProvider,指定的android:authorities属性

B程序通过ContentResolver来操作A程序暴露出来的数据的基本步骤

   1、通过content的getContentResolver()来获取ContentResolver对象

   2、通过ContentResolver对象来query,insert,update,delete来进行操作

在实现query,insert,update,delete时有一个重要的参数Uri类,Uri一个中要的方法Uri.parse(String str)用来解析str字符串,而str字符串格式一般都有A程序提供给B程序,B程序按照指定的格式去请求 。比如:content//:com.android.xiong.ConentProviderTestA.firstContentProvider/xiong 其格式一般分为三个部分:content//:这部分是固定不变的 而com.android.xiong.ConentProviderTestA.firstContentProvider表A程序在androidmanifest.xml注册的android:authorities属性,xiong则表示资源部分

       <provider           android:name="com.android.xiong.conentprovidertesta.FirstContentProvider"           android:authorities="com.android.xiong.ConentProviderTestA.firstContentProvider"           android:exported="true" ></provider>

 

 

实例如下

   A程序:

  UserInfo.java

package com.android.xiong.conentprovidertesta;import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;public class FirstContentProvider extends ContentProvider {// UriMatcher类主要用来匹配Uriprivate static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);private MySqlite mysqlite;static {// 注册向外部程序提供的UriuriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);}//删除数据@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {int number = 0;if (uriMatcher.match(uri) == 1) {// 根据条件删除数据,并获取删除的行数number = mysqlite.getReadableDatabase().delete("user_info",selection, selectionArgs);}// 通知数据已经改变getContext().getContentResolver().notifyChange(uri, null);return number;}@Overridepublic String getType(Uri uri) {return null;}//插入数据@Overridepublic Uri insert(Uri uri, ContentValues values) {String name = values.getAsString(UserInfo.User.NAME).toString();String age = values.getAsInteger(UserInfo.User.AGE).toString();String maxId = "select max(id) id from user_info";Cursor cursor = mysqlite.getReadableDatabase().rawQuery(maxId, null);cursor.moveToFirst();int userid = cursor.getInt(0) + 1;if (uriMatcher.match(uri) == 1) {mysqlite.getWritableDatabase().execSQL("insert into user_info values(?,?,?)",new String[] { String.valueOf(userid), name, age });}return uri;}// 连接数据库@Overridepublic boolean onCreate() {mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);return true;}//查询数据@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {SQLiteDatabase sqlite = mysqlite.getReadableDatabase();String str = "select name,age from user_info";if (uriMatcher.match(uri) == 1) {str += " where " + selection;}Cursor cursor = sqlite.rawQuery(str, selectionArgs);return cursor;}//修改数据@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {SQLiteDatabase sqlite = mysqlite.getReadableDatabase();int number = 0;if (uriMatcher.match(uri) == 1) {number = sqlite.update("user_info", values, selection,selectionArgs);}return number;}}


 

   FirstContentProvider.java

package com.android.xiong.conentprovidertesta;import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;public class FirstContentProvider extends ContentProvider {// UriMatcher类主要用来匹配Uriprivate static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);private MySqlite mysqlite;static {// 注册向外部程序提供的UriuriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);}//删除数据@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {int number = 0;if (uriMatcher.match(uri) == 1) {// 根据条件删除数据,并获取删除的行数number = mysqlite.getReadableDatabase().delete("user_info",selection, selectionArgs);}// 通知数据已经改变getContext().getContentResolver().notifyChange(uri, null);return number;}@Overridepublic String getType(Uri uri) {return null;}//插入数据@Overridepublic Uri insert(Uri uri, ContentValues values) {String name = values.getAsString(UserInfo.User.NAME).toString();String age = values.getAsInteger(UserInfo.User.AGE).toString();String maxId = "select max(id) id from user_info";Cursor cursor = mysqlite.getReadableDatabase().rawQuery(maxId, null);cursor.moveToFirst();int userid = cursor.getInt(0) + 1;if (uriMatcher.match(uri) == 1) {mysqlite.getWritableDatabase().execSQL("insert into user_info values(?,?,?)",new String[] { String.valueOf(userid), name, age });}return uri;}// 连接数据库@Overridepublic boolean onCreate() {mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);return true;}//查询数据@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {SQLiteDatabase sqlite = mysqlite.getReadableDatabase();String str = "select name,age from user_info";if (uriMatcher.match(uri) == 1) {str += " where " + selection;}Cursor cursor = sqlite.rawQuery(str, selectionArgs);return cursor;}//修改数据@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {SQLiteDatabase sqlite = mysqlite.getReadableDatabase();int number = 0;if (uriMatcher.match(uri) == 1) {number = sqlite.update("user_info", values, selection,selectionArgs);}return number;}}


MySqlite.java

  

package com.android.xiong.conentprovidertesta;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class MySqlite extends SQLiteOpenHelper {static final String sql = "create table user_info(id int,name varchar(30),age int)";public MySqlite(Context context, String name, CursorFactory factory,int version) {super(context, name, factory, version);// TODO Auto-generated constructor stub}@Overridepublic void onCreate(SQLiteDatabase db) {//创建数据表db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stub}}


MainActivity.java

  

package com.android.xiong.conentprovidertesta;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class MySqlite extends SQLiteOpenHelper {static final String sql = "create table user_info(id int,name varchar(30),age int)";public MySqlite(Context context, String name, CursorFactory factory,int version) {super(context, name, factory, version);// TODO Auto-generated constructor stub}@Overridepublic void onCreate(SQLiteDatabase db) {//创建数据表db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stub}}


activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity" >    <TextView        android:id="@+id/txt1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:text="添加信息"        android:textSize="20dp" />    <EditText        android:id="@+id/ed1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="添加name" />    <EditText        android:id="@+id/ed2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="添加age"        android:inputType="number" />    <Button        android:id="@+id/bt1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="提交数据" />        <ListView            android:id="@+id/lists"            android:layout_width="match_parent"            android:layout_height="wrap_content" >        </ListView></LinearLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <TextView         android:id="@+id/item_txt1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>        <TextView         android:id="@+id/item_txt2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>    </LinearLayout>


B程序

 UserInfo.java

package com.android.xiong.contentprovidertestb;//向外部程序提供一个工具类public class UserInfo {// 获取ContentProvider的“域名”public static final String AUTOR = "com.android.xiong.ConentProviderTestA.firstContentProvider";//定义一个静态内部类,提供ContentProvider可操作的列public static final class User  {public  static final  String ID="id";public static final String NAME="name";public static final String AGE="age";//定义该content提供服务的一个Uripublic static final String uri="content://"+AUTOR+"/userinfo";public static final String uriall="content://"+AUTOR+"/userinfoall";}}


MainActivity.java

 

package com.android.xiong.contentprovidertestb;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.ScrollView;import android.widget.SimpleAdapter;import android.widget.Toast;public class MainActivity extends Activity {private Button bt1, bt2, bt3, bt4;private EditText ed1, ed2;private ListView list1;private ScrollView sc1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bt1 = (Button) findViewById(R.id.bt1);bt2 = (Button) findViewById(R.id.bt2);bt3 = (Button) findViewById(R.id.bt3);bt4 = (Button) findViewById(R.id.bt4);ed1 = (EditText) findViewById(R.id.ed1);ed2 = (EditText) findViewById(R.id.ed2);list1 = (ListView) findViewById(R.id.list);// 显示所有数据list1.setAdapter(adapter(0));sc1 = (ScrollView) findViewById(R.id.scr1);// 向添加ContentProviderA应用的数据bt1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String eds1 = ed1.getText().toString();String eds2 = ed2.getText().toString();ContentValues content = new ContentValues();if (!eds1.equals("") && !eds2.equals("")) {content.put(UserInfo.User.NAME, eds1);content.put(UserInfo.User.AGE, eds2);MainActivity.this.getContentResolver().insert(Uri.parse(UserInfo.User.uri), content);Toast.makeText(MainActivity.this, "数据插入成功",Toast.LENGTH_LONG).show();// 刷新ListView界面list1.setAdapter(adapter(0));} else {Toast.makeText(MainActivity.this, "name和age不能为空",Toast.LENGTH_LONG).show();}}});// 根据条件删除ContentProviderA应用的数据bt2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String eds1 = ed1.getText().toString();String eds2 = ed2.getText().toString();if (!eds1.equals("") || !eds2.equals("")) {HashMap<String, String[]> wheres = wheres(eds1, eds2);String sql = wheres.get("sql")[0];String[] selectags = wheres.get("selectages");MainActivity.this.getContentResolver().delete(Uri.parse(UserInfo.User.uri), sql, selectags);} else {Toast.makeText(MainActivity.this, "请输入删除条件",Toast.LENGTH_LONG).show();}// 刷新ListView界面list1.setAdapter(adapter(0));}});// 修改数据bt3.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String eds1 = ed1.getText().toString();String eds2 = ed2.getText().toString();ContentValues values = new ContentValues();// 根据条件将列修改为xiong,23values.put(UserInfo.User.NAME, "xiong");values.put(UserInfo.User.AGE, "23");if (!eds1.equals("") || !eds2.equals("")) {HashMap<String, String[]> wheres = wheres(eds1, eds2);String sql = wheres.get("sql")[0];String[] selectags = wheres.get("selectages");int i=MainActivity.this.getContentResolver().update(Uri.parse(UserInfo.User.uri), values, sql,selectags);} else {Toast.makeText(MainActivity.this, "请输入删除条件",Toast.LENGTH_LONG).show();}// 刷新ListView界面list1.setAdapter(adapter(0));}});// 根据条件查询ContentProviderA应用的数据bt4.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (!ed1.getText().toString().equals("")|| !ed2.getText().toString().equals(""))list1.setAdapter(adapter(1));elselist1.setAdapter(adapter(0));}});}// 用来判别条件public HashMap<String, String[]> wheres(String eds1, String eds2) {HashMap<String, String[]> where = new HashMap<String, String[]>();if (!eds1.equals("") && !eds2.equals("")) {String[] sql = { UserInfo.User.NAME + "=? and " + UserInfo.User.AGE+ " =?" };String[] selectages = { eds1, eds2 };where.put("sql", sql);where.put("selectages", selectages);}if (!eds1.equals("") && eds2.equals("")) {String[] sql = { UserInfo.User.NAME + "=? " };String[] selectages = { eds1 };where.put("sql", sql);where.put("selectages", selectages);}if (eds1.equals("") && !eds2.equals("")) {String[] sql = { UserInfo.User.AGE + " =?" };String[] selectages = { eds2 };where.put("sql", sql);where.put("selectages", selectages);}return where;}// 用来显示数据public SimpleAdapter adapter(int i) {Cursor cs = MainActivity.this.getContentResolver().query(Uri.parse(UserInfo.User.uriall), null, null, null, null);String eds1 = ed1.getText().toString();String eds2 = ed2.getText().toString();if (i == 1) {if (!eds1.equals("") || !eds2.equals("")) {HashMap<String, String[]> wheres = wheres(eds1, eds2);String sql = wheres.get("sql")[0];String[] selectags = wheres.get("selectages");cs = MainActivity.this.getContentResolver().query(Uri.parse(UserInfo.User.uri), null, sql, selectags,null);}}List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();while (cs.moveToNext()) {Map<String, Object> map = new HashMap<String, Object>();map.put("name", cs.getString(0));map.put("age", cs.getString(1));lists.add(map);}SimpleAdapter simepl = new SimpleAdapter(MainActivity.this, lists,R.layout.item, new String[] { "name", "age" }, new int[] {R.id.item_txt1, R.id.item_txt2 });return simepl;}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}

activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity" >    <ScrollView        android:id="@+id/scr1"        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical" >            <Button                android:id="@+id/bt1"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="添加" />            <Button                android:id="@+id/bt2"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="删除" />            <Button                android:id="@+id/bt3"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="更改" />            <Button                android:id="@+id/bt4"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="查询" />            <EditText                android:id="@+id/ed1"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:hint="输入name条件进行增删改查" />            <EditText                android:id="@+id/ed2"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:hint="输age条件进行增删改查" />        </LinearLayout>    </ScrollView>    <ListView        android:id="@+id/list"        android:layout_width="match_parent"        android:layout_height="wrap_content" >    </ListView></LinearLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <TextView         android:id="@+id/item_txt1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>        <TextView         android:id="@+id/item_txt2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>    </LinearLayout>





 

原创粉丝点击