ContentProvider类的使用--将手机号展示出来

2.ContentProvider类的使用--将手机号展示出来

2018年06月15日 16:17:42 huanhuan59 阅读数:39

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.暴露的数据以列表的形式显示出来

ContentProvider类的使用--将手机号展示出来ContentProvider类的使用--将手机号展示出来

主要代码:

ContentProvider类的使用--将手机号展示出来

 

MainActivity.java

 
  1. package com.hh.contentprovider;

  2.  
  3. import java.util.ArrayList;

  4. import java.util.List;

  5. import java.util.Random;

  6.  
  7. import android.app.Activity;

  8. import android.content.ContentResolver;

  9. import android.database.Cursor;

  10. import android.net.Uri;

  11. import android.os.Bundle;

  12. import android.os.Handler;

  13. import android.view.View;

  14. import android.view.ViewGroup;

  15. import android.widget.BaseAdapter;

  16. import android.widget.ListView;

  17. import android.widget.TextView;

  18.  
  19. public class MainActivity extends Activity {

  20.  
  21. private ListView lv;

  22. private List<Person> persons;

  23.  
  24. //创建一个Handler对象用于线程间通信

  25. private Handler handler = new Handler(){

  26. public void handleMessage(android.os.Message msg) {

  27. switch (msg.what) {

  28. case 100://接收到数据查询完毕的消息

  29. //UI线程适配ListView

  30. lv.setAdapter(new MyAdapter());

  31. break;

  32. }

  33. };

  34. };

  35. protected void onCreate(Bundle savedInstanceState) {

  36. super.onCreate(savedInstanceState);

  37. setContentView(R.layout.activity_main);

  38. lv = (ListView) findViewById(R.id.lv);

  39. //由于添加数据、查询数据是比较耗时的,因此需要在子线程中做这两个操作

  40. new Thread(){

  41. public void run() {

  42. //添加数据

  43. addData();

  44. //获取persons集合

  45. getPersons();

  46. //如果查询到数据 则向UI线程发送消息

  47. if(persons.size() > 0){

  48. handler.sendEmptyMessage(100);

  49. }

  50. };

  51. }.start();

  52. }

  53.  
  54. // 往person表中插入10条数据

  55. public void addData() {

  56. PersonDao dao = new PersonDao(this);

  57. long number = 885900000l;

  58. Random random = new Random();

  59. for (int i = 0; i < 10; i++) {

  60. dao.add("wangwu" + i, Long.toString(number + i));

  61. }

  62. }

  63.  
  64. //利用ContentResolver对象查询本应用程序使用ContentProvider暴露的数据

  65. private void getPersons() {

  66. //首先要获取查询的uri

  67. String url = "content://com.hh.contentprovider.personprovider/query";

  68. Uri uri = Uri.parse(url);

  69. //获取ContentResolver对象 这个对象的使用后面会详细讲解

  70. ContentResolver contentResolver = getContentResolver();

  71. //利用ContentResolver对象查询数据得到一个Cursor对象

  72. Cursor cursor = contentResolver.query(uri, null, null, null, null);

  73. persons = new ArrayList<Person>();

  74. //如果cursor为空立即结束该方法

  75. if(cursor == null){

  76. return;

  77. }

  78. while(cursor.moveToNext()){

  79. int id = cursor.getInt(cursor.getColumnIndex("id"));

  80. String name = cursor.getString(cursor.getColumnIndex("name"));

  81. String number = cursor.getString(cursor.getColumnIndex("number"));

  82. Person p = new Person(id, name, number);

  83. persons.add(p);

  84. }

  85. cursor.close();

  86. }

  87.  
  88. //适配器

  89. private class MyAdapter extends BaseAdapter{

  90. private static final String TAG = "MyAdapter";

  91. // 控制listview里面总共有多个条目

  92. public int getCount() {

  93. return persons.size(); //条目个数 == 集合的size

  94. }

  95. public Object getItem(int position) {

  96. return persons.get(position);

  97. }

  98. public long getItemId(int position) {

  99. return 0;

  100. }

  101. public View getView(int position, View convertView, ViewGroup parent) {

  102. //得到某个位置对应的person对象

  103. Person person = persons.get(position);

  104. View view = View.inflate(MainActivity.this, R.layout.list_item, null);

  105. //一定要在view对象里面寻找孩子的id

  106. //姓名

  107. TextView tv_name = (TextView) view.findViewById(R.id.tv_name);

  108. tv_name.setText("姓名:"+person.getName());

  109. //电话

  110. TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone);

  111. tv_phone.setText("电话:"+person.getNumber());

  112. return view;

  113. }

  114.  
  115. }

  116.  
  117. }

 

Person.java

 
  1. package com.hh.contentprovider;

  2.  
  3. public class Person {

  4. private int id;

  5. private String name;

  6. private String number;

  7. public Person() {

  8. }

  9. public String toString() {

  10. return "Person [id=" + id + ", name=" + name + ", number=" + number

  11. + "]";

  12. }

  13. public Person(int id, String name, String number) {

  14. this.id = id;

  15. this.name = name;

  16. this.number = number;

  17. }

  18. public int getId() {

  19. return id;

  20. }

  21. public void setId(int id) {

  22. this.id = id;

  23. }

  24. public String getName() {

  25. return name;

  26. }

  27. public void setName(String name) {

  28. this.name = name;

  29. }

  30. public String getNumber() {

  31. return number;

  32. }

  33. public void setNumber(String number) {

  34. this.number = number;

  35. }

  36. }

 

PersonDao.java

 
  1. package com.hh.contentprovider;

  2.  
  3. import android.content.ContentValues;

  4. import android.content.Context;

  5. import android.database.sqlite.SQLiteDatabase;

  6.  
  7. public class PersonDao {

  8. private PersonSQLiteOpenHelper helper;//创建了一个私有的helper变量

  9. //在构造方法里面完成helper的初始化

  10. public PersonDao(Context context){//构造方法

  11. helper = new PersonSQLiteOpenHelper(context);

  12. }

  13. //添加一条记录到数据库

  14. public long add(String name,String number){//添加内容

  15. SQLiteDatabase db = helper.getWritableDatabase();//写入内容

  16. ContentValues values = new ContentValues();

  17. values.put("name", name);

  18. values.put("number", number);

  19. long id = db.insert("person", null, values);

  20. db.close();

  21. return id;

  22. }

  23. }

 

PersonDBProvider.java

 
  1. package com.hh.contentprovider;

  2.  
  3. import android.content.ContentProvider;

  4. import android.content.ContentUris;

  5. import android.content.ContentValues;

  6. import android.content.UriMatcher;

  7. import android.database.Cursor;

  8. import android.database.sqlite.SQLiteDatabase;

  9. import android.net.Uri;

  10.  
  11. import com.hh.contentprovider.PersonSQLiteOpenHelper;

  12.  
  13. public class PersonDBProvider extends ContentProvider {

  14. // 定义一个uri的匹配器 用于匹配uri 如果路径不满足条件 返回 -1

  15. private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

  16. private static final int INSERT = 1; //添加数据匹配Uri路径成功时返回码

  17. private static final int DELETE = 2; //删除数据匹配Uri路径成功时返回码

  18. private static final int UPDATE = 3; //更改数据匹配Uri路径成功时返回码

  19. private static final int QUERY = 4; //查询数据匹配Uri路径成功时返回码

  20. private static final int QUERYONE = 5; //查询一条数据匹配Uri路径成功时返回码

  21. //数据库操作类的对象

  22. private PersonSQLiteOpenHelper helper;

  23. static {

  24. // 添加一组匹配规则.

  25. matcher.addURI("com.hh.contentprovider.personprovider", "insert", INSERT);

  26. matcher.addURI("com.hh.contentprovider.personprovider", "delete", DELETE);

  27. matcher.addURI("com.hh.contentprovider.personprovider", "update", UPDATE);

  28. matcher.addURI("com.hh.contentprovider.personprovider", "query", QUERY);

  29. //这里的“#”号为通配符凡是符合”query/”皆返回QUERYONE的返回码

  30. matcher.addURI("com.hh.contentprovider.personprovider", "query/#", QUERYONE);

  31. }

  32. //当内容提供者被创建的时候 调用 适合 数据的初始化

  33. public boolean onCreate() {

  34. helper = new PersonSQLiteOpenHelper(getContext());

  35. return false;

  36. }

  37. //查询数据操作

  38. public Cursor query(Uri uri, String[] projection, String selection,

  39. String[] selectionArgs, String sortOrder) {

  40. if (matcher.match(uri) == QUERY) { //匹配查询的Uri路径

  41. //匹配成功 ,返回查询的结果集

  42. SQLiteDatabase db = helper.getReadableDatabase();

  43. //调用数据库操作的查询数据的方法

  44. Cursor cursor = db.query("person", projection, selection,

  45. selectionArgs, null, null, sortOrder);

  46. return cursor;

  47. } else if (matcher.match(uri) == QUERYONE) {

  48. //匹配成功,根据id查询数据

  49. long id = ContentUris.parseId(uri);

  50. SQLiteDatabase db = helper.getReadableDatabase();

  51. Cursor cursor = db.query("person", projection, "id=?",

  52. new String[]{id+""}, null, null, sortOrder);

  53. return cursor;

  54. } else {

  55. throw new IllegalArgumentException("路径不匹配,不能执行查询操作");

  56. }

  57. }

  58. //获取当前Uri的数据类型

  59. public String getType(Uri uri) {

  60. if (matcher.match(uri) == QUERY) {

  61. // 返回查询的结果集

  62. return "vnd.android.cursor.dir/person";

  63. } else if (matcher.match(uri) == QUERYONE) {

  64. return "vnd.android.cursor.item/person";

  65. }

  66. return null;

  67. }

  68. //添加数据

  69. public Uri insert(Uri uri, ContentValues values) {

  70. if (matcher.match(uri) == INSERT) {

  71. //匹配成功 返回查询的结果集

  72. SQLiteDatabase db = helper.getWritableDatabase();

  73. db.insert("person", null, values);

  74. } else {

  75. throw new IllegalArgumentException("路径不匹配,不能执行插入操作");

  76. }

  77. return null;

  78. }

  79. //删除数据

  80. public int delete(Uri uri, String selection, String[] selectionArgs) {

  81. if (matcher.match(uri) == DELETE) {

  82. //匹配成功 返回查询的结果集

  83. SQLiteDatabase db = helper.getWritableDatabase();

  84. db.delete("person", selection, selectionArgs);

  85. } else {

  86. throw new IllegalArgumentException("路径不匹配,不能执行删除操作");

  87. }

  88. return 0;

  89. }

  90. //更新数据

  91. public int update(Uri uri, ContentValues values, String selection,

  92. String[] selectionArgs) {

  93. if (matcher.match(uri) == UPDATE) {

  94. //匹配成功 返回查询的结果集

  95. SQLiteDatabase db = helper.getWritableDatabase();

  96. db.update("person", values, selection, selectionArgs);

  97. } else {

  98. throw new IllegalArgumentException("路径不匹配,不能执行修改操作");

  99. }

  100. return 0;

  101. }

  102. }

 

PersonSQLiteOpenHelper.java

 
  1. package com.hh.contentprovider;

  2.  
  3. import android.content.Context;

  4. import android.database.sqlite.SQLiteDatabase;

  5. import android.database.sqlite.SQLiteOpenHelper;

  6. import android.util.Log;

  7.  
  8. public class PersonSQLiteOpenHelper extends SQLiteOpenHelper {

  9. private static final String TAG = "PersonSQLiteOpenHelper";

  10. // 数据库的构造方法,用来定义数据库的名称 数据库查询的结果集 数据库的版本

  11. public PersonSQLiteOpenHelper(Context context) {

  12. super(context, "person.db", null, 3);

  13. }

  14. // 数据库第一次被创建时调用的方法

  15. public void onCreate(SQLiteDatabase db) {

  16. //初始化数据库的表结构

  17. db.execSQL("create table person (id integer primary key autoincrement, name varchar(20), number varchar(20)) ");

  18. }

  19. // 当数据库的版本号发生变化的时候调用

  20. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

  21. Log.i(TAG,"数据库的版本变化了");

  22. }

  23. }

 

activity_main.xml

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. xmlns:app="http://schemas.android.com/apk/res-auto"

  4. xmlns:tools="http://schemas.android.com/tools"

  5. android:layout_width="match_parent"

  6. android:layout_height="match_parent"

  7. tools:context=".MainActivity">

  8.  
  9. <ListView

  10. android:id="@+id/lv"

  11. android:layout_width="wrap_content"

  12. android:layout_height="wrap_content">

  13.  
  14. </ListView>

  15.  
  16. </LinearLayout>

 

list_item.xml

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="match_parent"

  4. android:layout_height="60dip"

  5. android:gravity="center_vertical"

  6. android:orientation="horizontal" >

  7. <ImageView

  8. android:layout_width="wrap_content"

  9. android:layout_height="wrap_content"

  10. android:layout_marginLeft="5dip"

  11. android:src="@drawable/default_avatar" />

  12. <LinearLayout

  13. android:layout_width="fill_parent"

  14. android:layout_height="60dip"

  15. android:layout_marginLeft="20dip"

  16. android:gravity="center_vertical"

  17. android:orientation="vertical" >

  18. <TextView

  19. android:id="@+id/tv_name"

  20. android:layout_width="wrap_content"

  21. android:layout_height="wrap_content"

  22. android:layout_marginLeft="5dip"

  23. android:text="姓名"

  24. android:textColor="#000000"

  25. android:textSize="16sp" />

  26. <TextView

  27. android:id="@+id/tv_phone"

  28. android:layout_width="wrap_content"

  29. android:layout_height="wrap_content"

  30. android:layout_marginLeft="5dip"

  31. android:layout_marginTop="3dp"

  32. android:text="电话"

  33. android:textColor="#88000000"

  34. android:textSize="16sp" />

  35. </LinearLayout>

  36. </LinearLayout>

Manifest.xml

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"

  3. package="com.hh.contentprovider">

  4.  
  5. <application

  6. android:allowBackup="true"

  7. android:icon="@mipmap/ic_launcher"

  8. android:label="@string/app_name"

  9. android:roundIcon="@mipmap/ic_launcher_round"

  10. android:supportsRtl="true"

  11. android:theme="@style/AppTheme">

  12. <activity android:name=".MainActivity">

  13. <intent-filter>

  14. <action android:name="android.intent.action.MAIN" />

  15.  
  16. <category android:name="android.intent.category.LAUNCHER" />

  17. </intent-filter>

  18. </activity>

  19. <provider

  20. android:name="com.hh.contentprovider.PersonDBProvider"

  21. android:authorities="com.hh.contentprovider.personprovider">

  22. </provider>

  23. </application>

  24.  
  25. </manifest>

小程序总代码:读取联系人信息小程序下载https://download.csdn.net/download/huanhuan59/10481236