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年最后一天。。。。



你可能感兴趣的:(移动android)