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數據庫沒有一定的關聯。
html

      ContentProvider樣例:java

     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, "沒有匹配的記錄!android

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


佈局設置:

 <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:
app

 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>ide


 ContentProvider中的URI,本身定義ContentProvider。實例:

 核心代碼:
佈局

 StudentProvider:
post

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 一、是否合法 二、推斷操做類型
	 */

	/*
	 * 合法的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才幹知曉數據的變化。this


實例:

核心代碼:

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

。。

相關文章
相關標籤/搜索