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





猜你喜欢

转载自blog.csdn.net/huanhuan59/article/details/80694879
今日推荐