1. 程式人生 > >2.ContentProvider類的使用--將手機號展示出來

2.ContentProvider類的使用--將手機號展示出來

1.定義一個類繼承Android.content 包下的ContentProvider類(抽象類)。子類需要重寫
它的onCreate(),delete(),getType(),insert(),query(),以及update()這幾個抽象方法。

2.ContentProvider是四大元件之一,必須要在清單檔案中註冊
<provider
android :name="cn.itcast.db.PersonDBRovider"
android :authorities="cn.itcast.db.personprovider">
</provider>

3.Uri 簡介
ContentProvider的幾個抽象方法,這幾個抽象方法有一個引數Uri,它代表了資料的操作方法。
Uri是由 scheme,authorities,path三部分組成
例如:
content://cn.itcast.db.personprovider/person
{scheme  }{authorities              }{path}


a.scheme:"content://" 是一個標準的字首,表明這個資料被內容提供者所控制,他不會被修改;
b.authorities:"cn.itcast.db.personprovider" 是指在清單檔案中指定的android.authorities屬性值,該值必須唯一,他表示了當前內容的提供者。
c.path:"/person"代表資源資料,當訪問者需要操作不同資料時,這個資料時動態改變的。


4.Uri.parse(String str)方法是將字串轉化成Uri物件的。為了解析Uri物件,Android系統提供了一個輔助工具類UriMatcher 用於匹配Uri。

UriMatcher 中的常見方法如下所示:
a.public UriMatcher (int code) :建立UriMatcher物件呼叫時,引數通常使用UriMatcher.No_MATCH,表示路徑不滿足條件事返回-1

b.public  void addUri(String authority,String path,int code) :新增一組匹配規則,
c.public int match (Uri uri) :匹配Uri與addUri方法相對應。匹配成攻,則返回addUri方法中傳入的引數code值

5.案例:讀取聯絡人的資訊
該案例實現了查詢自己暴露的資料,並將資料捆綁到ListView控制元件中的功能。
a,將資料插入到資料庫中   //執行看不到效果
b.通過ContentProvider將資料暴露出去  //執行看不到效果
c.暴露的資料以列表的形式顯示出來

主要程式碼:



MainActivity.java

package com.hh.contentprovider;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

    private ListView lv;
    private List<Person>  persons;

    //建立一個Handler物件用於執行緒間通訊
    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 100://接收到資料查詢完畢的訊息
                    //UI執行緒適配ListView
                    lv.setAdapter(new MyAdapter());
                    break;
            }
        };
    };
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.lv);
        //由於新增資料、查詢資料是比較耗時的,因此需要在子執行緒中做這兩個操作
        new Thread(){
            public void run() {
                //新增資料
                addData();
                //獲取persons集合
                getPersons();
                //如果查詢到資料 則向UI執行緒傳送訊息
                if(persons.size() > 0){
                    handler.sendEmptyMessage(100);
                }
            };
        }.start();
    }

    // 往person表中插入10條資料
    public void addData() {
        PersonDao dao = new PersonDao(this);
        long number = 885900000l;
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            dao.add("wangwu" + i, Long.toString(number + i));
        }
    }

    //利用ContentResolver物件查詢本應用程式使用ContentProvider暴露的資料
    private void getPersons() {
        //首先要獲取查詢的uri
        String url = "content://com.hh.contentprovider.personprovider/query";
        Uri uri = Uri.parse(url);
        //獲取ContentResolver物件 這個物件的使用後面會詳細講解
        ContentResolver contentResolver = getContentResolver();
        //利用ContentResolver物件查詢資料得到一個Cursor物件
        Cursor cursor = contentResolver.query(uri, null, null, null, null);
        persons = new ArrayList<Person>();
        //如果cursor為空立即結束該方法
        if(cursor == null){
            return;
        }
        while(cursor.moveToNext()){
            int id = cursor.getInt(cursor.getColumnIndex("id"));
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String number = cursor.getString(cursor.getColumnIndex("number"));
            Person p = new Person(id, name, number);
            persons.add(p);
        }
        cursor.close();
    }

    //介面卡
    private class MyAdapter extends BaseAdapter{
        private static final String TAG = "MyAdapter";
        // 控制listview裡面總共有多個條目
        public int getCount() {
            return persons.size(); //條目個數 == 集合的size
        }
        public Object getItem(int position) {
            return persons.get(position);
        }
        public long getItemId(int position) {
            return 0;
        }
        public View getView(int position, View convertView, ViewGroup parent) {
            //得到某個位置對應的person物件
            Person person = persons.get(position);
            View view = View.inflate(MainActivity.this, R.layout.list_item, null);
            //一定要在view物件裡面尋找孩子的id
            //姓名
            TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
            tv_name.setText("姓名:"+person.getName());
            //電話
            TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone);
            tv_phone.setText("電話:"+person.getNumber());
            return view;
        }

    }

}

Person.java

package com.hh.contentprovider;

public class Person {
	private int id;
	private String name;
	private String number;
	public Person() {
	}
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", number=" + number
				+ "]";
	}
	public Person(int id, String name, String number) {
		this.id = id;
		this.name = name;
		this.number = number;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
}

PersonDao.java

package com.hh.contentprovider;

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

public class PersonDao {
	private PersonSQLiteOpenHelper helper;//建立了一個私有的helper變數
	//在構造方法裡面完成helper的初始化
	public PersonDao(Context context){//構造方法
		helper = new PersonSQLiteOpenHelper(context);
	}
	//新增一條記錄到資料庫
	public long add(String name,String number){//新增內容
		SQLiteDatabase db = helper.getWritableDatabase();//寫入內容
		ContentValues values = new ContentValues();
		values.put("name", name);
		values.put("number", number);
		long id = db.insert("person", null, values);
		db.close();
		return id;
	}
}

PersonDBProvider.java

package com.hh.contentprovider;

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;

import com.hh.contentprovider.PersonSQLiteOpenHelper;

public class PersonDBProvider extends ContentProvider {
	// 定義一個uri的匹配器 用於匹配uri 如果路徑不滿足條件 返回 -1
	private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
	private static final int INSERT = 1;    //新增資料匹配Uri路徑成功時返回碼
	private static final int DELETE = 2;    //刪除資料匹配Uri路徑成功時返回碼
	private static final int UPDATE = 3;    //更改資料匹配Uri路徑成功時返回碼
	private static final int QUERY = 4;     //查詢資料匹配Uri路徑成功時返回碼
	private static final int QUERYONE = 5; //查詢一條資料匹配Uri路徑成功時返回碼
	//資料庫操作類的物件
	private PersonSQLiteOpenHelper helper;
	static {
		// 新增一組匹配規則.
		matcher.addURI("com.hh.contentprovider.personprovider", "insert", INSERT);
		matcher.addURI("com.hh.contentprovider.personprovider", "delete", DELETE);
		matcher.addURI("com.hh.contentprovider.personprovider", "update", UPDATE);
		matcher.addURI("com.hh.contentprovider.personprovider", "query", QUERY);
		//這裡的“#”號為萬用字元凡是符合”query/”皆返回QUERYONE的返回碼
		matcher.addURI("com.hh.contentprovider.personprovider", "query/#", QUERYONE);
	}
	//當內容提供者被建立的時候 呼叫 適合 資料的初始化
	public boolean onCreate() {
		helper = new PersonSQLiteOpenHelper(getContext());
		return false;
	}
	//查詢資料操作
	public Cursor query(Uri uri, String[] projection, String selection,
						String[] selectionArgs, String sortOrder) {
		if (matcher.match(uri) == QUERY) { //匹配查詢的Uri路徑
			//匹配成功 ,返回查詢的結果集
			SQLiteDatabase db = helper.getReadableDatabase();
			//呼叫資料庫操作的查詢資料的方法
			Cursor cursor = db.query("person", projection, selection,
					selectionArgs, null, null, sortOrder);
			return cursor;
		} else if (matcher.match(uri) == QUERYONE) {
			//匹配成功,根據id查詢資料
			long id = ContentUris.parseId(uri);
			SQLiteDatabase db = helper.getReadableDatabase();
			Cursor cursor = db.query("person", projection, "id=?",
					new String[]{id+""}, null, null, sortOrder);
			return cursor;
		} else {
			throw new IllegalArgumentException("路徑不匹配,不能執行查詢操作");
		}
	}
	//獲取當前Uri的資料型別
	public String getType(Uri uri) {
		if (matcher.match(uri) == QUERY) {
			// 返回查詢的結果集
			return "vnd.android.cursor.dir/person";
		} else if (matcher.match(uri) == QUERYONE) {
			return "vnd.android.cursor.item/person";
		}
		return null;
	}
	//新增資料
	public Uri insert(Uri uri, ContentValues values) {
		if (matcher.match(uri) == INSERT) {
			//匹配成功 返回查詢的結果集
			SQLiteDatabase db = helper.getWritableDatabase();
			db.insert("person", null, values);
		} else {
			throw new IllegalArgumentException("路徑不匹配,不能執行插入操作");
		}
		return null;
	}
	//刪除資料
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		if (matcher.match(uri) == DELETE) {
			//匹配成功 返回查詢的結果集
			SQLiteDatabase db = helper.getWritableDatabase();
			db.delete("person", selection, selectionArgs);
		} else {
			throw new IllegalArgumentException("路徑不匹配,不能執行刪除操作");
		}
		return 0;
	}
	//更新資料
	public int update(Uri uri, ContentValues values, String selection,
					  String[] selectionArgs) {
		if (matcher.match(uri) == UPDATE) {
			//匹配成功 返回查詢的結果集
			SQLiteDatabase db = helper.getWritableDatabase();
			db.update("person", values, selection, selectionArgs);
		} else {
			throw new IllegalArgumentException("路徑不匹配,不能執行修改操作");
		}
		return 0;
	}
}

PersonSQLiteOpenHelper.java

package com.hh.contentprovider;

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

public class PersonSQLiteOpenHelper extends SQLiteOpenHelper {
	private static final String TAG = "PersonSQLiteOpenHelper";
	// 資料庫的構造方法,用來定義資料庫的名稱 資料庫查詢的結果集 資料庫的版本
	public PersonSQLiteOpenHelper(Context context) {
		super(context, "person.db", null, 3);
	}
	// 資料庫第一次被建立時呼叫的方法
	public void onCreate(SQLiteDatabase db) {
		//初始化資料庫的表結構
		db.execSQL("create table person (id integer primary key autoincrement, name varchar(20), number varchar(20)) ");
	}
	// 當資料庫的版本號發生變化的時候呼叫
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.i(TAG,"資料庫的版本變化了");
	}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/lv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    </ListView>

</LinearLayout>

list_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="60dip"
    android:gravity="center_vertical"
    android:orientation="horizontal" >
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dip"
        android:src="@drawable/default_avatar" />
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="60dip"
        android:layout_marginLeft="20dip"
        android:gravity="center_vertical"
        android:orientation="vertical" >
        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dip"
            android:text="姓名"
            android:textColor="#000000"
            android:textSize="16sp" />
        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dip"
            android:layout_marginTop="3dp"
            android:text="電話"
            android:textColor="#88000000"
            android:textSize="16sp" />
    </LinearLayout>
</LinearLayout>
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hh.contentprovider">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:name="com.hh.contentprovider.PersonDBProvider"
            android:authorities="com.hh.contentprovider.personprovider">
        </provider>
    </application>

</manifest>
小程式總程式碼: 讀取聯絡人資訊小程式下載https://download.csdn.net/download/huanhuan59/10481236