ContentProvider

 ContentProvider表示“内容提供者”。
  ContentProvider是一种数据共享机制,它将同意其他应用程序对自身应用程序中的数据
  运行增删改查操作;
  ContentProvider是Android核心组件之中的一个,因此,开发者在创建它时,须要自己定义继承
  ContentProvider,并且,它须要在项目清单文件里(AndroidMainfest.xml)中注冊。
  ContentProvider须要定义用于訪问数据的URI,当其它应用程序知晓相应的URI时,就可以
  运行数据的相关操作。


  ContentProvider无需被激活,当配置了ContentProvider的应用程序被安装到设备上。
  同一台设备上的其他应用程序随时都能够訪问它的数据。
ContentProvider的开发步骤:
     自己定义类继承android,content.ContentProvider类。
     重写android.content.ContentProvider类中声明的抽象方法;
     在AndroidMainfest.xml文件里配置ContentProvider:
            创建<application>节点下加入<provider>子节点。
    配置android.name属性,指定ContentProvider类;
    配置android.authorities属性,指定用于訪问数据的URI的host部分;
   配置android:exported属性,指定值为true。
     标准URI:scheme://host:port/path
     比如:http://www.goole.com:80/android

   注意:基于ContentProvider中数据增删改查的方法与使用SQLite数据库时使用的方法极为相似。因此,
   大多数的ContentProvider共享的数据的方式都是通过操作SQLite数据库完毕的,可是,ContentProvider
   与SQLite数据库没有必定的关联。

      ContentProvider样例:

     package com.example.lianxi;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class StudentProvider extends ContentProvider{

	private DBOpenHelper helper;
	@Override
	public int delete(Uri arg0, String selection, String[] selectionArgs) {
		SQLiteDatabase db = helper.getReadableDatabase();
		db.delete("students", selection, selectionArgs);
		return 0;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		//插入
		SQLiteDatabase db = helper.getReadableDatabase();
		db.insert("students", null, values);
		return null;
	}

	@Override
	public boolean onCreate() {
		// 完毕初始化的操作
		helper = new DBOpenHelper(getContext());
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 查询
		SQLiteDatabase db = helper.getReadableDatabase();
		Cursor cursor = db.query("students", projection, selection, selectionArgs, null, null, sortOrder);
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = helper.getReadableDatabase();
		db.update("students", values, selection, selectionArgs);
		return 0;
	}

}

DBOpenHelper:

 package com.example.lianxi;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBOpenHelper extends SQLiteOpenHelper{
 
	public DBOpenHelper(Context context){
		super(context,"number2.db",null,1);
	}
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		String sql = "CREATE TABLE [students] (" 
				+"[_id] INTEGER PRIMARY KEY AUTOINCREMENT,"
				+"[_name] VARCHAR(50) UNIQUE NOT NULL,"
				+"[_age] INT NOT NULL DEFAULT 16"
				+")";
		db.execSQL(sql);
		
	}

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

}

MainActivity:

package com.example.lianxi;

import android.app.Activity;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;


public class MainActivity extends Activity {
	private DBOpenHelper helper;
	private SQLiteDatabase db;
	private EditText name;
	
    @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		helper = new DBOpenHelper(this);
		db = helper.getReadableDatabase();
		name = (EditText) findViewById(R.id.name);
		
    }
    public void find_All(View view){
    	Cursor cursor = db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc");
        long id;
        String name;
        int age;
        
    	for(cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){
    	    id = cursor.getLong(cursor.getColumnIndex("_id"));
    	    name = cursor.getString(cursor.getColumnIndex("_name"));
    	    age = cursor.getInt(cursor.getColumnIndex("_age"));
    		System.out.println("id = " + id + " ," + "name = " +name +" ," + "age = " + age);
    		
       }
    	cursor.close();
    }
    public void findName(View view){
    	String findName = name.getText().toString();
    	Cursor cursor = db.query("students", null, "_name=?

", new String[]{findName}, null, null, null); if(cursor.moveToFirst()){ long id1; String name1; int age1; id1 = cursor.getLong(cursor.getColumnIndex("_id")); name1 = cursor.getString(cursor.getColumnIndex("_name")); age1 = cursor.getInt(cursor.getColumnIndex("_age")); Toast.makeText(this, "学生记录为id = " + id1 + " ," + "name = " +name1 + " ," + "age = " + age1, Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "没有匹配的记录!

", Toast.LENGTH_LONG).show(); } } }


布局设置:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/find_all"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:onClick="find_All"
        android:text="查询全部数据" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginTop="30dp"
        android:orientation="horizontal" >

    <EditText
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10" >

    </EditText>

    <Button
        android:id="@+id/find"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:onClick="findName"
        android:text="查询" />
  </LinearLayout>
</LinearLayout>

要在AndroidMainfest.xml中注冊:
     <provider android:name="com.example.lianxi.StudentProvider"
          android:exported="true"
          android:authorities="test"></provider>


訪问ContentProvider共享的数据
        ContentResolver:ContentResolver:用于訪问其他应用程序通过ContentProvider共享的数据;
    通过ContextWraper类定义的getContentResolver()方法就可以获取ContentResolver的对象。
通过使用ContentResolver訪问上一个应用程序内的数据。样例:
        布局不需改动,MainActivity:

package com.example.lianxi;

import android.app.Activity;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;


public class MainActivity extends Activity {
	private DBOpenHelper helper;
	private SQLiteDatabase db;
	private EditText name;
	
    @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		helper = new DBOpenHelper(this);
		db = helper.getReadableDatabase();
		name = (EditText) findViewById(R.id.name);
		
    }
    public void find_All(View view){
    	Cursor cursor = db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc");
        long id;
        String name;
        int age;
        
    	for(cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){
    	    id = cursor.getLong(cursor.getColumnIndex("_id"));
    	    name = cursor.getString(cursor.getColumnIndex("_name"));
    	    age = cursor.getInt(cursor.getColumnIndex("_age"));
    		System.out.println("id = " + id + " ," + "name = " +name +" ," + "age = " + age);
    		
       }
    	cursor.close();
    }
    public void findName(View view){
    	String findName = name.getText().toString();
    	Cursor cursor = db.query("students", null, "_name=?", new String[]{findName}, null, null, null);
       if(cursor.moveToFirst()){
    	   long id1;
           String name1;
           int age1;
           id1 = cursor.getLong(cursor.getColumnIndex("_id"));
   	    name1 = cursor.getString(cursor.getColumnIndex("_name"));
   	    age1 = cursor.getInt(cursor.getColumnIndex("_age"));
   	    Toast.makeText(this, "学生记录为id = " + id1 + " ," + "name = " +name1 + " ," + "age = " + age1, Toast.LENGTH_LONG).show();
   	    
       }else{
    	   Toast.makeText(this, "没有匹配的记录!

", Toast.LENGTH_LONG).show(); } } }


訪问到的结果为:

 12-30 13:36:02.608: I/System.out(1305): id=1
12-30 13:36:02.616: I/System.out(1305): name=Mike
12-30 13:36:02.616: I/System.out(1305): age=28
12-30 13:36:02.616: I/System.out(1305): id=2
12-30 13:36:02.616: I/System.out(1305): name=fgusdfg
12-30 13:36:02.616: I/System.out(1305): age=21
12-30 13:36:02.616: I/System.out(1305): id=3
12-30 13:36:02.616: I/System.out(1305): name=huanghdf
12-30 13:36:02.616: I/System.out(1305): age=23
12-30 13:36:02.616: I/System.out(1305): id=4
12-30 13:36:02.616: I/System.out(1305): name=Macal
12-30 13:36:02.616: I/System.out(1305): age=45
12-30 13:36:02.616: I/System.out(1305): id=5
12-30 13:36:02.616: I/System.out(1305): name=jiaokong
12-30 13:36:02.616: I/System.out(1305): age=34
12-30 13:36:02.616: I/System.out(1305): id=6
12-30 13:36:02.620: I/System.out(1305): name=sdfff
12-30 13:36:02.620: I/System.out(1305): age=56

SimpleCursorAdapter:
SimpleCursorAdapter是一种使用Cursor对象作为数据源的Adapter。
使用SimpleCursorAdapter时,要求Cursor对象中必须存在名为_id的列。
使用实例,相同訪问的是上面应用的数据:

MainActivity:

 package com.example.contentresolver;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;

public class MainActivity extends Activity {

	private ListView listView;
	private SimpleCursorAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ContentResolver cr = getContentResolver();
		Uri uri = Uri.parse("content://test");
		Cursor cursor = cr.query(uri, new String[] { "_id", "_name", "_age" },
				null, null, null);

		listView = (ListView) findViewById(R.id.lv_student);
		String[] from = { "_id", "_name", "_age" };
		int[] to = { R.id.item_id, R.id.item_name, R.id.item_age };
		adapter = new SimpleCursorAdapter(this, R.layout.student_item, cursor,
				from, to, 0);
		listView.setAdapter(adapter);
		

	}
}

布局:

<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"
    android:gravity="center_vertical"
     >
     <LinearLayout 
         android:id="@+id/ll_head"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         >
         <TextView 
             android:id="@+id/tv_id"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="ID"
             android:gravity="center"
             android:layout_weight="1"
             android:padding="3dp"
             android:layout_margin="1dp"
             android:background="#aaaaaa"
             android:textColor="#ffffff"/>
           <TextView 
             android:id="@+id/tv_name"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="NAME"
             android:gravity="center"
             android:layout_weight="1"
             android:padding="3dp"
             android:layout_margin="1dp"
             android:background="#aaaaaa"
             android:textColor="#ffffff"/>
             <TextView 
             android:id="@+id/tv_age"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="AGE"
             android:gravity="center"
             android:layout_weight="1"
             android:padding="3dp"
             android:layout_margin="1dp"
             android:background="#aaaaaa"
             android:textColor="#ffffff"/>
     </LinearLayout>
    <ListView 
        android:id="@+id/lv_student"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="30dp"></ListView>

</RelativeLayout>

item_student:

 <?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_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ID" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" /> <TextView android:id="@+id/item_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="NAME" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" /> <TextView android:id="@+id/item_age" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="AGE" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" /> </LinearLayout>


 ContentProvider中的URI,自己定义ContentProvider。实例:

 核心代码:

 StudentProvider:

package com.example.lianxi;

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;

public class StudentProvider extends ContentProvider {
	/*
	 * 验证URI 1、是否合法 2、推断操作类型
	 */

	/*
	 * 合法的URI content://com.example.lianxi.providers/student 訪问所有的数据
	 * content://com.example.lianxi.providers/student/5 訪问ID为5的数据
	 */
	private DBOpenHelper helper;
	private static UriMatcher MATCHER;// 用于验证URi的类

	private static String AUTHORITY = "com.example.lianxi.providers";
	private static String PATH = "student";
	private static int MATCHER_ALL = 23;
	private static int MATCHER_ID = 34;
	static {
		MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		MATCHER.addURI(AUTHORITY, PATH, MATCHER_ALL);
		MATCHER.addURI(AUTHORITY, PATH + "/#", MATCHER_ID);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		if (MATCHER.match(uri) == MATCHER_ID) {
			SQLiteDatabase db = helper.getReadableDatabase();
			long id = ContentUris.parseId(uri);
			String whereClause;
			if (selection == null || "".equals(selection)) {
				whereClause = "_id" + id;
			} else {
				whereClause = selection + " and _id=" + id;
			}
			int result = db.delete("students", whereClause, selectionArgs);
			return result;
		} else {
			throw new IllegalArgumentException("非法的URI:" + uri.toString());
		}
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// 插入
		if (MATCHER.match(uri) == MATCHER_ALL) {
			SQLiteDatabase db = helper.getReadableDatabase();
			long id = db.insert("students", null, values);
			return ContentUris.withAppendedId(uri, id);// 返回的为两者合成的

		} else {
			throw new IllegalArgumentException("非法的URI:" + uri.toString());
		}

	}

	@Override
	public boolean onCreate() {
		// 完毕初始化的操作
		helper = new DBOpenHelper(getContext());

		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 查询
		if (MATCHER.match(uri) == MATCHER_ALL) {
			SQLiteDatabase db = helper.getReadableDatabase();
			Cursor cursor = db.query("students", projection, selection,
					selectionArgs, null, null, sortOrder);
			return cursor;
		} else if (MATCHER.match(uri) == MATCHER_ID) {
			SQLiteDatabase db = helper.getReadableDatabase();
			long id = ContentUris.parseId(uri);
			String whereClause;
			if (selection == null || "".equals(selection)) {
				whereClause = "_id=" + id;
			} else {
				whereClause = selection + " and _id=" + id;
			}
			Cursor cursor = db.query("students", projection, whereClause,
					selectionArgs, null, null, sortOrder);
			return cursor;
		} else {
			throw new IllegalArgumentException("非法的URI:" + uri.toString());
		}
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		if (MATCHER.match(uri) == MATCHER_ID) {
			SQLiteDatabase db = helper.getReadableDatabase();
			long id = ContentUris.parseId(uri);
			String whereClause;
			if (selection == null || "".equals(selection)) {
				whereClause = "_id=" + id;
			} else {
				whereClause = selection + " and _id=" + id;
			}
			int result = db
					.update("students", values, whereClause, selectionArgs);
			return result;
		} else {
			throw new IllegalArgumentException("非法的URI:" + uri.toString());
		}

	}

}

执行时须要先将上一个应用部署到虚拟机中。然后再将获取数据的应用执行,
通过一个应用获取还有一个应用中的数据:
        其它代码同上:核心代码:
   Uri uri = Uri.parse("content://com.example.lianxi.providers/student/5");//获取一个数值
Uri uri = Uri.parse("content://com.example.lianxi.providers/student");//获取全部数值


 ContentObserver监听数据的变化
       使用ContentObserver可监听数据变化,当注冊了ContentObserver的URI相应的数据发生变化时。该类中的onChange()
       方法会被回调。
       调用ContentResolver类定义的registerContentObserver()能够注冊ContentObserver。


       注意:ContentObserver的工作原理并非每分每秒的监听相应的数据,仅仅有ContentProvider的增删改查方法必须通知
       了数据发生变化以后。ContentObserver才干知晓数据的变化。


实例:

核心代码:

StudentProvider:

@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		if (MATCHER.match(uri) == MATCHER_ID) {
			SQLiteDatabase db = helper.getReadableDatabase();
			long id = ContentUris.parseId(uri);
			String whereClause;
			if (selection == null || "".equals(selection)) {
				whereClause = "_id=" + id;
			} else {
				whereClause = selection + " and _id=" + id;
			}
			int result = db.delete("students", whereClause, selectionArgs);
			this.getContext().getContentResolver().notifyChange(uri, null);
			return result;
		} else {
			throw new IllegalArgumentException("非法的URI:" + uri.toString());
		}
	}

MainActivity:

package com.example.contentresolver;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;

public class MainActivity extends Activity {

	private ListView listView;
	private SimpleCursorAdapter adapter;
	private Cursor cursor;
    private Uri uri;
    private ContentResolver cr;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		cr = getContentResolver();
		uri = Uri.parse("content://com.example.lianxi.providers/student");//获取一个数值
//		Uri uri = Uri.parse("content://com.example.lianxi.providers/student");//获取全部数值
		cursor = cr.query(uri, new String[] { "_id", "_name", "_age" },
				null, null, null);
        ContentObserver observer = new ContentObserver(new Handler()){
        	@Override
        	public void onChange(boolean selfChange) {
        		// TODO Auto-generated method stub
        		cursor.requery();
        		adapter.notifyDataSetChanged();
        		
        		super.onChange(selfChange);
        	}
        };
        cr.registerContentObserver(uri, true, observer);
		listView = (ListView) findViewById(R.id.lv_student);
		String[] from = { "_id", "_name", "_age" };
		int[] to = { R.id.item_id, R.id.item_name, R.id.item_age };
		adapter = new SimpleCursorAdapter(this, R.layout.student_item, cursor,
				from, to, 0);
		listView.setAdapter(adapter);
		registerForContextMenu(listView);
		

	}
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
		int position = info.position;
		cursor.moveToPosition(position);
		String studentName = cursor.getString(cursor.getColumnIndex("_name"));
		
		menu.add(Menu.NONE,1,1,"删除"+ studentName );
		super.onCreateContextMenu(menu, v, menuInfo);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		int position = info.position;
		cursor.moveToPosition(position);
		long id = cursor.getLong(cursor.getColumnIndex("_id"));
		
		Uri deleteUri = ContentUris.withAppendedId(uri, id);
		cr.delete(deleteUri,null,null);
		return super.onContextItemSelected(item);
	}
}

今天今天2015年最后一天。

。。



原文地址:https://www.cnblogs.com/yxysuanfa/p/7039808.html