内容提供者相关技术

zzqmettle 2015-03-06

 android中数据库一般是不能直接被其他程序创建的,一般是通过内容提供者 ,内容提供者是android开发中常见的数据操作方式,例如;android手机的联系人信息获取  我们是可以直接操作android提供的内容提供者的, android需要做的就是在联系人中定义一个内容提供者;  

   内容提供者关键步骤: 

          1,创建(A程序)数据库;   继承SQLiteOpenHelper创建数据库和表

           2,创建(A程序)的内容提供者;   继承Contentprovider自定义内容提供者      

         3,创建(B程序)操作A程序的数据(增删该查) ; 使用上下文获取内容提供者

 
内容提供者相关技术
 

一: A程序;

  1,定义A程序的数据库

package com.example.DemoDB;
/**
 * 数据库的创建
 */
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class HelperDemo extends SQLiteOpenHelper{

	public HelperDemo(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		//创建表
		String sql="create table user(_id integer primary key autoincrement,userphone txet,username text)";
		//使用execSQL只用sql语句
		db.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		
	}

}

2,创建显示操作数据的xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="130dp" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1"
        android:layout_marginLeft="18dp"
        android:layout_marginTop="44dp"
        android:onClick="optionuser"
        android:text="添加" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button1"
        android:layout_marginLeft="46dp"
        android:layout_toRightOf="@+id/button1"
        android:onClick="optionuser"
        android:text="删除" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="22dp"
        android:onClick="optionuser"
        android:text="修改" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button3"
        android:layout_alignBottom="@+id/button3"
        android:layout_alignLeft="@+id/button2"
        android:onClick="optionuser"
        android:text="查询" />

</RelativeLayout>

3,创建A程序的数据库和操作数据库方法,将操作的结果显示出来

package com.example.DemoDB;

import com.example.sharedpreferrences.R;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 
 * @author Administrator 数据库的操作
 */
public class DemoDB extends Activity {
	private TextView v1;
	private Button t1;
	private Button t2;
	private Button t3;
	private Button t4;
	private HelperDemo demo;
	private SQLiteDatabase database;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_db);
         //创建数据库 user_contacts数据库的名字 
		demo = new HelperDemo(this, "user_contacts", null, 1);
         //增删改查按钮和显示数据按钮
		v1 = (TextView) this.findViewById(R.id.textView1);
		t1 = (Button) this.findViewById(R.id.button1);
		t2 = (Button) this.findViewById(R.id.button2);
		t3 = (Button) this.findViewById(R.id.button3);
		t4 = (Button) this.findViewById(R.id.button4);

	}

	// 数据库的操作
	public void optionuser(View v) {
		switch (v.getId()) {
		case R.id.button1:// 添加数据
			database = demo.getWritableDatabase();
			if (database == null) {
				Toast.makeText(this, "不能添加数据", Toast.LENGTH_SHORT).show();
			} else {
				// 第一个方式
				String sql = "insert into user values(null,'12345','长沙')";
				database.execSQL(sql);

				// 第二种方式
				// 参数一:表名
				// 参数二:null
				// 参数三:使用ContentValues赋值
				// ContentValues values = new ContentValues();
				// values.put("userphone", "123");
				// values.put("username", "value");
				//
				// database.insert("user", null, values);
				selectuser();
			}
			break;

		case R.id.button2:// 删除
			database = demo.getWritableDatabase();
			if (database == null) {
				Toast.makeText(this, "不能删除数据数据", Toast.LENGTH_SHORT).show();
			} else {

				// //第一种方式
				// String sql ="delete from user where _id=?";
				// String[] str= {"1"};
				// database.execSQL(sql, str);

				// 第二种方式
				// 参数一:表名
				// 参数二:条件
				// 参数三:条件的值
				String whereClause = "_id=?";
				String[] whereArgs = { "2" };
				database.delete("user", whereClause, whereArgs);
			}

			selectuser();
			break;
		case R.id.button3:// 修改
			database = demo.getWritableDatabase();
			if (database == null) {
				Toast.makeText(this, "不能修改数据", Toast.LENGTH_SHORT).show();
			} else {

				// 第一种方式

				// String sql="update user set username='武汉' where _id=6";
				// database.execSQL(sql);

				// 参数一:表名
				// 参数二:更新的值
				// 参数三:?的字段名
				// 参数四:?字段名的值
				ContentValues values = new ContentValues();
				values.put("username", "北京");
				String whereClause = "_id=?";
				String[] whereArgs = { "5" };
				database.update("user", values, whereClause, whereArgs);
			}

			selectuser();
			break;
		case R.id.button4:// 查询
			selectuser();

			break;
		}
	}

	// 查询
	public void selectuser() {
		SQLiteDatabase database2 = demo.getReadableDatabase();
//		// 第一种方式
//		String sql = "select * from user order by _id desc";
//		Cursor c = database2.rawQuery(sql, null);
//		StringBuffer buffer = new StringBuffer();
//		while (c.moveToNext()) {
//			int id = c.getInt(c.getColumnIndex("_id"));
//			String phone = c.getString(c.getColumnIndex("userphone"));
//			String name = c.getString(c.getColumnIndex("username"));
//			buffer.append(id + "\t姓名:\t" + name + "<><>电话:\t" + phone + "\r\n");
//		}
//		v1.setText(buffer);
		
		//第二种方式
		//参数一:表名
		//查询数据会返回一个游标对象,遍历游标对象就得到值
		Cursor c=database2.query("user", null, null, null, null, null, null);
		StringBuffer buffer = new StringBuffer();
		while (c.moveToNext()) {
			int id = c.getInt(c.getColumnIndex("_id"));
			String phone = c.getString(c.getColumnIndex("userphone"));
			String name = c.getString(c.getColumnIndex("username"));
			buffer.append(id + "\t姓名:\t" + name + "<><>电话:\t" + phone + "\r\n");
		}
		v1.setText(buffer);
	}

}

4,定义A程序的内容提供者

package com.example.DemoDB;
/**
 * 内容提供者
 */
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

/**
 * 
 * @author Administrator 使用内容提供者共享数据 第一步:继承ContentProvider 第二步; <provider
 *         android:name="com.example.DemoDB.MyContent"
 *         android:authorities="com.example.DemoDB.MyContent.provider"
 *         android:exported="true"></provider>
 */
public class MyContent extends ContentProvider {

	// 定义字符串用来匹配的关键
	static String authority = "com.MyContent.provider";
	// 定义一个URI匹配器,NO_MATCH表示默认不匹配任何路径
	static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
	// 使用静态块来添加可匹配路径,为了保证在执行那个程序之前,匹配器中有可匹配路径
	static {
		// 参数一:内容提供者
		// 参数二:名字
		// 参数三:匹配的地址
		matcher.addURI(authority, "insretdate", 1);//插入
		matcher.addURI(authority, "selectdate", 2);//查询
		matcher.addURI(authority, "daletedate", 3);//删除
		matcher.addURI(authority, "updatedate", 4);//修改
	}

	private HelperDemo demo;

	@Override
	public boolean onCreate() {
		// 创建数据库
		demo = new HelperDemo(this.getContext(), "user_contacts", null, 1);
		return true;
	}

	@Override
	public String getType(Uri uri) {
		// 获得类型
		return null;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 匹配内容提供者的数据
		int code = matcher.match(uri);
		if (code != 2) {
			throw new IllegalArgumentException("参数异常:" + uri);
		}
		//判断是否可读
		SQLiteDatabase querydatabase=demo.getReadableDatabase();
		if(querydatabase==null){
			throw new RuntimeException("数据不存在");
		}
		Cursor cursor=querydatabase.query("user", projection, selection, selectionArgs, null, null, sortOrder);
		
		
		return cursor;
	}

	@Override
	// 插入数据
	public Uri insert(Uri uri, ContentValues values) {
		// 匹配uri
		int code = matcher.match(uri);
		if (code != 1) {
			throw new IllegalArgumentException("插入数据时参数异常:" + uri);
		}

		SQLiteDatabase db = demo.getWritableDatabase();
		if (db == null) {
			throw new RuntimeException("无法插入数据,数据库对象为只读!");
		}
		// 返回的是插入的数据的id 插入到数据库可以使用insertOrThrow 和insert插入
		long id = db.insertOrThrow("user", "_id", values);
		// 返回的Uri代表被插入的数据
		uri = ContentUris.withAppendedId(uri, id);

		return uri;
	}

	@Override
	// 删除数据
	public int delete(Uri uri, String selection, String[] selectionArgs) {
          //匹配编码
       int code=matcher.match(uri);
       if(code!=3){
    	   throw new IllegalArgumentException("删除参数异常:"+uri);
       }
       //判断是否可写
       SQLiteDatabase sd= demo.getWritableDatabase();
        if(sd==null){
        	throw new RuntimeException("删除 运行时异常");
        }
        
        //删除数据
        int len=sd.delete("user", selection, selectionArgs);
        
       
		return len;
	}

	@Override
	// 更新数据
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int code=matcher.match(uri);
		if(code!=4){
			throw new IllegalArgumentException("更新参数异常:"+uri);
		}
		SQLiteDatabase sd=demo.getWritableDatabase();
		if(sd==null){
			throw new RuntimeException("更新运行时异常");
		}
		//更新数据
		int len=sd.update("user", values, selection, selectionArgs);
		return len;
	}

}

分析:

    a, MyContent类执行时,先初始化static的相关属性,

// 定义字符串用来匹配的关键
	static String authority = "com.MyContent.provider";
	// 定义一个URI匹配器,NO_MATCH表示默认不匹配任何路径
	static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
	// 使用静态块来添加可匹配路径,为了保证在执行那个程序之前,匹配器中有可匹配路径
	static {
		// 参数一:内容提供者
		// 参数二:名字
		// 参数三:匹配的地址
		matcher.addURI(authority, "insretdate", 1);//插入
		matcher.addURI(authority, "selectdate", 2);//查询
		matcher.addURI(authority, "daletedate", 3);//删除
		matcher.addURI(authority, "updatedate", 4);//修改
	}

     b,    B程序操作A程序的内容提供者是通过 addURI()方法中的名字 找到内容提供者,通过匹配地址找到插  入语句

5,清单中注册

  <provider 

            android:name="com.example.DemoDB.MyContent"

            android:authorities="com.MyContent.provider"

            android:exported="true"></provider>

    </application>

二 :B程序

  操作A程序中的内容提供者的步骤:

         上下文获取内容提供者

  1,xml文件  按不同的按钮输入框输入的结果不同,请仔细查看B程序中按钮的操作

<RelativeLayout 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"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="141dp"
        android:onClick="show"
        android:text="更新" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button1"
        android:layout_alignBottom="@+id/button1"
        android:layout_toRightOf="@+id/textView1"
        android:onClick="show"
        android:text="查询" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/button1"
        android:layout_below="@+id/button2"
        android:layout_marginTop="36dp"
        android:onClick="show"
        android:text="删除" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button3"
        android:layout_alignBottom="@+id/button3"
        android:layout_alignRight="@+id/editText2"
        android:onClick="show"
        android:text="添加" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_centerVertical="true"
        android:ems="10" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/editText2"
        android:layout_alignLeft="@+id/editText2"
        android:layout_marginBottom="14dp"
        android:ems="10" >

        <requestFocus />
    </EditText>

</RelativeLayout>

2,B程序操作A程序的内容提供者

  

package com.example.date.provider;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
/**
 * 
 * @author Administrator
 *操作数据保存程序的内容提供者,实现增删改查操作
 */
public class MainActivity extends Activity {

	private EditText editText1;
	private EditText editText2;
	private ContentResolver resolver; 
	private TextView t1;	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		t1=(TextView)this.findViewById(R.id.textView1);
		editText1 = (EditText) this.findViewById(R.id.editText1);
		editText2 = (EditText) this.findViewById(R.id.editText2);
		//获得内容提供者
     resolver= this.getContentResolver();
	}

	//实现按钮的监听器方法
	public void show(View v) {
		switch (v.getId()) {
		case R.id.button1://更新数据
			//获取输入框的值
			String str=editText1.getText().toString().trim();
			//内容提供者的地址
            Uri uri= Uri.parse("content://com.MyContent.provider/updatedate");
            ContentValues values= new ContentValues();
            values.put("username", "天津");
            String where="_id=?";
             String[] selectionArgs={str};
             //更新语句
            resolver.update(uri, values, where, selectionArgs);
             
			break;
		case R.id.button2:
			//查询
			 Uri uriselect= Uri.parse("content://com.MyContent.provider/selectdate");
			
			 Cursor c= resolver.query(uriselect, null, null, null, null);
			 StringBuffer buffer = new StringBuffer();
				while (c.moveToNext()) {
					int id = c.getInt(c.getColumnIndex("_id"));
					String phone = c.getString(c.getColumnIndex("userphone"));
					String name = c.getString(c.getColumnIndex("username"));
					buffer.append(id + "\t姓名:\t" + name + "<><>电话:\t" + phone + "\r\n");
				}
				t1.setText(buffer);
			break;
		case R.id.button3:	
			//删除
         Uri uridelete=Uri.parse("content://com.MyContent.provider/daletedate");
         String str1=editText1.getText().toString().trim();
         String wheredelete = "username=?";
			String[] selectionArgsdelete = {str1};
         resolver.delete(uridelete, wheredelete, selectionArgsdelete);
         
			break;
		case R.id.button4:
			//增加
          Uri uriinsret= Uri.parse("content://com.MyContent.provider/insretdate");
          //获取输入框中的姓名和电话
          String name=editText1.getText().toString().trim();	
          String phone=editText2.getText().toString().trim();
          //使用键值对存放数据
          ContentValues valuesinsert = new ContentValues();
          
          valuesinsert.put("username", name);
          valuesinsert.put("userphone", phone);
          //插入语句
          resolver.insert(uriinsret, valuesinsert);
          break;
		}
	}
}

相关推荐