Android之ContentProvider详解

       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>

 

 

实例如下

Android之ContentProvider详解_第1张图片Android之ContentProvider详解_第2张图片

   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类主要用来匹配Uri
	private static final UriMatcher uriMatcher = new UriMatcher(
			UriMatcher.NO_MATCH);
	private MySqlite mysqlite;
	static {
		// 注册向外部程序提供的Uri
		uriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);
		uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);
	}
	//删除数据
	@Override
	public 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;
	}

	@Override
	public String getType(Uri uri) {

		return null;
	}
	//插入数据
	@Override
	public 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;
	}

	// 连接数据库
	@Override
	public boolean onCreate() {
		mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);
		return true;
	}
	//查询数据
	@Override
	public 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;
	}
	//修改数据
	@Override
	public 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类主要用来匹配Uri
	private static final UriMatcher uriMatcher = new UriMatcher(
			UriMatcher.NO_MATCH);
	private MySqlite mysqlite;
	static {
		// 注册向外部程序提供的Uri
		uriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);
		uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);
	}
	//删除数据
	@Override
	public 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;
	}

	@Override
	public String getType(Uri uri) {

		return null;
	}
	//插入数据
	@Override
	public 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;
	}

	// 连接数据库
	@Override
	public boolean onCreate() {
		mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);
		return true;
	}
	//查询数据
	@Override
	public 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;
	}
	//修改数据
	@Override
	public 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
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		//创建数据表
		db.execSQL(sql);

	}

	@Override
	public 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
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		//创建数据表
		db.execSQL(sql);

	}

	@Override
	public 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提供服务的一个Uri
		public 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;

	@Override
	protected 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() {

			@Override
			public 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() {

			@Override
			public 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() {

			@Override
			public void onClick(View v) {
				String eds1 = ed1.getText().toString();
				String eds2 = ed2.getText().toString();
				ContentValues values = new ContentValues();
				// 根据条件将列修改为xiong,23
				values.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() {
			@Override
			public void onClick(View v) {
				if (!ed1.getText().toString().equals("")
						|| !ed2.getText().toString().equals(""))
					list1.setAdapter(adapter(1));
				else
					list1.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;
	}

	@Override
	public 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>





 

你可能感兴趣的:(android,android应用,AndroidManifest,contentresolver)