赞
踩
3、 Uri:Uri是ContentResolver和ContentProvider进行数据交换的标识。
- 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据;
- ContentResolver 可以理解成是HttpClient的作用。
1、Contacts:获取、修改、保存联系人的信息;2、MediaStore:访问声音、视频、图片等多媒体文件;3、CallLog :查看或更新通话记录;4、Browser:读取或修改浏览历史、网络搜索、书签;5、Setting:查看和获取蓝牙设置、铃声设置等设备首选项。
1、调用Context的getContentResolver()方法获得ContentResolver 对象;2、调用使用ContentResolver 的insert()、delete()、update()、query()方法操作数据。
参数解释:String where:表示带有占位符的where子句组成的字符串;String[] whereArgs:表示替换where参数中占位符后的数据组成的字符串数组;String sortOrder:表示select语句中的order by子句组成的字符串;String[] projection:表示select语句中需要查询的所有的字段组成的字符串数组。ContentValues values:是由数据库中表字段和往该字段中放置的数据所组成的键值对对象。【备注:】以上四个方法的参数分别是2、3、4、5个。
1、联系人的Uri==> content://com.android.contacts/contacts 和 content://com.android.contacts/raw_contacts2、电话号码的Uri==> content://com.android.contacts/data/phones3、EMAIL的URI==> content://com.android.contacts/data/emails
不过为了方便记忆,系统中提供了以下常量来替代以上的Uri字符串。
publicstatic List<Map<String, Object>> selectContactsMsg(ContentResolver resolver, ContentValues values) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_phones = "content://com.android.contacts/data/phones";
String uri_contacts_emails = "content://com.android.contacts/data/emails";
// 从raw_contacts表中或许联系人的id和联系人的姓名。
Cursor cursor_contacts = resolver.query(Uri.parse (uri_contacts),
new String[] { "_id", "display_name" }, null, null, null);//Cursor query(Uri uri, String[] projection, String where, String[] whereArgs, String sortOrder)
// 遍历所有的联系人的信息
while (cursor_contacts.moveToNext()) {
int contacts_id = cursor_contacts.getInt(cursor_contacts.getColumnIndex("_id"));
String display_name = cursor_contacts.getString(cursor_contacts.getColumnIndex("display_name"));
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", contacts_id);
map.put("display_name", display_name);
// 以下开始获取电话号码
// 根据每个联系人的id再去data表中查找相应的电话号码。
Cursor cursor_phones = resolver.query(Uri.parse(uri_contacts_phones), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",new String[] { contacts_id + "" }, null);
// 因为电话号码可能是多个,所以需要再遍历,组合在一起形成一个电话号码的字符串,放到StringBuilder中
StringBuilder sb = new StringBuilder();
while (cursor_phones.moveToNext()) {
sb.append(cursor_phones.getString(1));//?
sb.append(" | ");
}
// 将生成的电话号码放到map集合中
map.put("phones", sb.toString());
// 以下开始获取Email信息
Cursor cursor_emails = resolver.query(Uri.parse(uri_contacts_emails), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",new String[] { contacts_id + "" }, null);
StringBuilder sb2 = new StringBuilder();
while (cursor_emails.moveToNext()) {
sb2.append(cursor_emails.getString(1));
sb2.append(" | ");
}
map.put("emails", sb2.toString());
// 将包含有id、联系人姓名、手机号码、emails的map放到list集合中
list.add(map);
}
return list;
}
// 以下方法是利用常量值所写的插入联系人的方法。如果希望封装成方法,再增加一个Map集合的参数,用来传入信息即可。
publicvoid insertContacts(ContentValues values, ContentResolver resolver) {
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = resolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
// 往data表入姓名数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,"王向军");
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,"王向军");
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
// 往data表入电话数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "13520551441");
values.put(ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
// 往data表入Email数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Email.DATA,"237235475@qq.com");
values.put(ContactsContract.CommonDataKinds.Email.TYPE,
ContactsContract.CommonDataKinds.Email.TYPE_WORK);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
}
publicclass ContactsResolverHelper {
/*
* 以下代码是插入新联系人的子过程。其中第三个参数:List集合表示要插入到通讯录中的新数据(该集合中有三个值,
* 分别是:姓名、电话、email)。
*/
publicvoid insertContacts(ContentResolver resolver, ContentValues values,List<String> list) {
String uri_rawcontacts = "content://com.android.contacts/raw_contacts";
String uri_data = "content://com.android.contacts/data";
Uri uri = Uri.parse(uri_contacts);
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = resolver.insert(Uri.parse(uri_rawcontacts), values);
long contact_id = ContentUris.parseId(rawContactUri);
// 往data表中插入一条用户的名称信息
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/name");
values.put("data1", list.get(0));
values.put("data2", list.get(0));
resolver.insert(uri_data, values);
// 往data表中插入电话信息
values.clear();
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/phone_v2");
values.put("data1", list.get(1));
values.put("data2", 2);// 2,Phone.TYPE_MOBILE ,表示手机号码
resolver.insert(uri_data, values);
// 往data表中插入Email信息
values.clear();
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/email_v2");
values.put("data1", list.get(2));
values.put("data2", 2);// 2,Email.TYPE_WORK , 表示工作用Email号码
resolver.insert(uri_data, values);
}
// 以下代码是删除联系人信息的方法。
publicstaticint deleteContacts(ContentResolver resolver, String where, String[] whereArgs) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
return resolver.delete(Uri.parse(uri_contacts), where, whereArgs);
}
// 以下代码是查询联系人信息的方法。
publicstatic Cursor selectContactsName(ContentResolver resolver,
String[] projection, String where, String[] whereArgs,String sortOrder) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
return resolver.query(Uri.parse(uri_contacts), projection, where, whereArgs, sortOrder);
}
publicstatic List<Map<String, Object>> selectContactsMsg(ContentResolver resolver, ContentValues values) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_phones = "content://com.android.contacts/data/phones";
String uri_contacts_emails = "content://com.android.contacts/data/emails";
// 从raw_contacts表中或许联系人的id和联系人的姓名。
Cursor cursor_contacts = resolver.query(Uri.parse(uri_contacts),
new String[] { "_id", "display_name" }, null, null, null);
// 遍历所有的联系人的信息
while (cursor_contacts.moveToNext()) {
int contacts_id = cursor_contacts.getInt(cursor_contacts.getColumnIndex("_id"));
String display_name = cursor_contacts.getString(cursor_contacts.getColumnIndex("display_name"));
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", contacts_id);
map.put("display_name", display_name);
// 以下开始获取电话号码
// 根据每个联系人的id再去data表中查找相应的电话号码。
Cursor cursor_phones = resolver.query(Uri.parse(uri_contacts_phones), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",new String[] { contacts_id + "" }, null);
// 因为电话号码可能是多个,所以需要再遍历,组合在一起形成一个电话号码的字符串,放到StringBuilder中
StringBuilder sb = new StringBuilder();
while (cursor_phones.moveToNext()) {
sb.append(cursor_phones.getString(1));
sb.append(" | ");
}
// 将生成的电话号码放到map集合中
map.put("phones", sb.toString());
// 以下开始或许Email信息
Cursor cursor_emails = resolver.query(Uri.parse(uri_contacts_emails), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?", new String[] { contacts_id + "" }, null);
StringBuilder sb2 = new StringBuilder();
while (cursor_emails.moveToNext()) {
sb2.append(cursor_emails.getString(1));
sb2.append(" | ");
}
map.put("emails", sb2.toString());
// 将包含有id、联系人姓名、手机号码、emails的map放到list集合中
list.add(map);
}
return list;
}
// 以下代码是更新联系人姓名的方法。
publicstaticint updateContactsName(ContentValues values,
ContentResolver resolver, String oldName, String newName) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_data = "content://com.android.contacts/data";
// 先更新raw_contacts表中的联系人姓名,共有四列需要更新
values.put("display_name", newName);
values.put("display_name_alt", newName);
values.put("sort_key", newName);
values.put("sort_key_alt", newName);
int count1 = resolver.update(Uri.parse(uri_contacts), values,"display_name=?", new String[] { oldName });
// 再更新data表中联系人的姓名,共有两列
values.clear();
values.put("data1", newName);
values.put("data2", newName);
int count2 = resolver.update(Uri.parse(uri_contacts_data), values, "data1=? and mimetype_id=?",
new String[] { oldName, "7" });
// 返回2,则说明六项都被更新。如果只返回1,则说明没有修改完全
return count1 + count2;
}
}
(一)、Android系统管理联系人的Uri如下:
【数据库中主要字段:】
(二)、Android为多媒体提供的ContentProvider的Uri如下:
【数据库中主要字段:】
(三)、短信Uri:
【数据库中主要字段:】
(四)、通话记录Uri:
1、完善今天的随堂代码“ContentResolver管理联系人”,增加添加联系人功能,增加删除联系人功能。2、利用ContentResolver制作管理SDCard上的多媒体文件管理器。
1、编写一个类,必须继承自ContentProvider类;
2、实现ContentProvider类中所有的抽象方法;
需要实现:onCreate() 、getType() 、query() 、insert() 、update()、delete() 等方法。
【备注:】
ContentProvider暴露出来的数据和方法并不是给自身调用的,而是给其他应用程序来调用。其他应用程序通过其ContentResolver对象调用的query() 、insert() 、update()、delete() 等方法就是我们在这里暴露出来的ContentProvider类中的重写后的query() 、insert() 、update()、delete() 方法。
3、定义ContentProvider的Uri。这个Uri是ContentResolver对象执行CRUD操作时重要的参数;
4、使用UriMatcher对象映射Uri返回代码;
5、在AndroidMainfest.xml文件中使用<provider>标签注册ContentProvider。
(二)、ContentProvider类中的六个抽象方法:
1、boolean onCreate()
Notice that your provider is not created until a
ContentResolver
object tries to access it.ContentResolver不访问内容提供者的时候,内容提供者是不会创建出来的.
2、Uri insert(Uri uri, ContentValues values)
3、int delete(Uri uri, String selection, String[] selectionArgs)
4、int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
5、Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
6、String getType(Uri uri)
(三)、ContentProvider类中六个抽象方法的说明:
1、onCreate() 初始化provider
2、query() 返回数据给调用者
3、insert() 插入新数据到ContentProvider
4、update() 更新ContentProvider已经存在的数据
5、delete() 从ContentProvider中删除数据
6、getType() 返回ContentProvider数据的MIME类型
(四)、在清单文件中声明注册ContentProvider:
<provider android:name=".MyWordsProvider"
android:authorities="com.steven.wordscontentprovider"
android:exported="true"
/>
//android:name属性的值是:ContentProvider类的子类的完整路径;
//android:authorities属性的值是:content:URI中authority部分。一般就是将name属性的值全小写。
//android:exported属性是否允许其他应用调用。如果是false,则该ContentProvider不允许其他应用调用。
UriMatcher工具类提供了两个方法:1、void addURI(String authority , String path , int code) : 该方法用于向UriMatcher对象注册Uri。其中authority和path是Uri中的重要部分。而code代表该Uri对应的标示符。2、int match(Uri uri) : 根据注册的Uri来判断指定的Uri对应的标示符。如果找不到匹配的标示符,该方法返回-1。
private static UriMatcher matcher = null;
static {
// 定义一个Uri匹配器。将UriMatcher.NO_MATCH,即-1作为参数。
matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 定义一组匹配规则
matcher.addURI(AUTHORITY, "words", 1);
matcher.addURI(AUTHORITY, "newwords", 2);
}
一、清单配置文件中注册ContentProvider:
<provider android:name=".MyWordsProvider"
android:authorities="com.steven.wordscontentprovider"
android:exported="true"
/>
二、ContentProvider 的程序部分:
publicclass MyWordsProvider extends ContentProvider {
private MySQLiteOpenHelper dbHelper = null;
private SQLiteDatabase db = null;
privatestatic UriMatcher matcher = null;
privatestaticfinal String AUTHORITY = "com.steven.wordscontentprovider";
static {
matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "words", 1);
matcher.addURI(AUTHORITY, "newwords", 2);}
@Override
publicboolean onCreate() {
dbHelper = new MySQLiteOpenHelper(getContext());
db = dbHelper.getReadableDatabase();
returntrue;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {switch (matcher.match(uri)) {
case 1:Cursor cursor = db.query("tb_words", projection, selection,selectionArgs, null, null, sortOrder);return cursor;case 2:
Cursor cursor2 = db.query("tb_newwords", projection, selection,selectionArgs, null, null, sortOrder);
return cursor2;
default:
break;
}
returnnull;
}
@Override
public String getType(Uri uri) {
returnnull;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowId = 0;
switch (matcher.match(uri)) {
case 1:
rowId = db.insert("tb_words", null, values);
if (rowId > 0) {
Uri newUri = ContentUris.withAppendedId(
Uri.parse("content://" + AUTHORITY + "/words"), rowId);
// 通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
break;
case 2:
rowId = db.insert("tb_newwords", null, values);
if (rowId > 0) {
Uri newUri = ContentUris.withAppendedId(
Uri.parse("content://" + AUTHORITY + "/newwords"),rowId);
// 通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
break;
default:
break;
}
returnnull;
}
@Override
publicint delete(Uri uri, String selection, String[] selectionArgs) {
switch (matcher.match(uri)) {
case 1:
int count = db.delete("tb_words", selection, selectionArgs);
if (count > 0) {
// 通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
case 2:
int count2 = db.delete("tb_newwords", selection, selectionArgs);
if (count2 > 0) {
// 通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(uri, null);
}
return count2;
default:
break;
}
return 0;
}
@Override
publicint update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {switch (matcher.match(uri)) {
case 1:
int count = db.update("tb_words", values, selection, selectionArgs);
if (count > 0) {
// 通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
case 2:
int count2 = db.update("tb_newwords", values, selection,
selectionArgs);
if (count2 > 0) {
// 通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(uri, null);
}
return count2;
default:
break;
}
return 0;
}
}
二、Java知识回顾:
(一)、静态代码块的作用:
一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。静态代码块和静态方法两者的区别就是:静态代码块是自动执行的;静态方法是被调用的时候才执行的。
1、在Java里,可以定义一个不需要创建对象的方法,这种方法就是静态方法。要实现这样的效果,只需要在类中定义的方法前加上static关键字。例如:
public static int maximum(int n1,int n2)
使用类的静态方法时,注意:
2、静态变量属于整个类,而不是属于某个对象的。注意不能把任何方法体内的变量声明为静态,例如:
fun() {
static int i=0;//非法。
}
3、一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。例如:
static {
}
(二)、对象的初始化顺序:
静态代码块对象的初始化顺序 :内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的无参构造方法。如果父类没有无参构造方法,那么子类必须用super关键子来调用父类带参构造方法,否则编译不能通过。
(三)、类装载步骤:
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:
1、装载:查找和导入类或接口的二进制数据;2、链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;
3、初始化:激活类的静态变量和静态Java代码块。 初始化类中属性是静态代码块的常用用途,但只能使用一次。
三、UriMatcher对象的addURI方法的#和*问题:
(一)、#和*的含义:
1、UriMatcher.addURI(String authority, String path, int code)
Parameters:
authority the authority to match
path the path to match. * may be used as a wild card for any text, and # may be used as a wild card for numbers.
code the code that is returned when a URI is matched against the given components. Must be positive.
*和#是两个通配符,它们用在uri地址中,*可以匹配任何文本,#匹配任何数字。
(二)、截取Uri地址和拼接Uri地址的方法:【重点】
1、Uri对象的截取方法:
2、Uri对象的拼接方法,拼接path:
3、ContentUris对象的截取id的方法:
4、ContentUris对象的拼接id的方法:
【备注:】Content URIs 的语法规则:content://authority/path/id
(三)、创建ContentProvider的示例代码:
1、MyProvider.java中的核心代码:
publicclass MyProvider extends ContentProvider {
private MySQLiteOpenHelper dbHelper = null;
private SQLiteDatabase db = null;
privatestatic UriMatcher matcher = null;
privatestaticfinal String AUTHORITY = "com.steven.contentprovider.mywordsprovider";
static {
matcher = new UriMatcher(-1);
matcher.addURI(AUTHORITY, "words", 1);
matcher.addURI(AUTHORITY, "newwords", 2);
matcher.addURI(AUTHORITY, "words/*", 3);// 匹配任何文本
matcher.addURI(AUTHORITY, "words_id/#", 4);// 匹配任何数字
matcher.addURI(AUTHORITY, "words_zh/*", 5);// 匹配任何中文文本
}
@Override
publicboolean onCreate() {
dbHelper = new MySQLiteOpenHelper(this.getContext());
db = dbHelper.getReadableDatabase();
returntrue;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {switch (matcher.match(uri)) {
case 1:
returndb.query("tb_words", projection, selection, selectionArgs,null, null, sortOrder);case 2:
returndb.query("tb_newwords", projection, selection,selectionArgs, null, null, sortOrder);case 3:
Log.i("MyProvider", "==返回值是:" + matcher.match(uri));
String data = uri.getLastPathSegment();
Log.i("MyProvider", "==" + data);
returndb.query("tb_words", projection, "word like ?",new String[] { data + "%" }, null, null,
sortOrder);
case 4:
Log.i ("MyProvider", "==返回值是:" + matcher.match(uri));
String data2 = uri.getLastPathSegment();
// long id = ContentUris.parseId(uri);
Log.i ("MyProvider", "==" + data2);
returndb.query("tb_words", projection, "_id=?",new String[] { data2 }, null, null, sortOrder);case 5:
String data3 = uri.getLastPathSegment();
returndb.query("tb_words", projection, "detail like ?",new String[] { data3 + "%" }, null, null,
sortOrder);
default:
Log.i ("MyProvider", "==返回值是:" + matcher.match(uri));
returnnull;
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (matcher.match(uri)) {
case 1:
long id = db.insert("tb_words", null, values);
return Uri.parse("content://" + AUTHORITY + "/words/" + id);
case 2:
long id2 = db.insert("tb_newwords", null, values);
return Uri.parse("content://" + AUTHORITY + "/newwords/" + id2);
}
returnnull;
}
@Override
publicint delete(Uri uri, String selection, String[] selectionArgs) {
switch (matcher.match(uri)) {
case 1:
returndb.delete("tb_words", selection, selectionArgs);
case 2:
returndb.delete("tb_newwords", selection, selectionArgs);
}
return 0;
}
@Override
publicint update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {switch (matcher.match(uri)) {
case 1:
returndb.update("tb_words", values, selection, selectionArgs);
case 2:
returndb.update("tb_newwords", values, selection, selectionArgs);
}
return 0;
}
@Override
public String getType(Uri uri) {
returnnull;
}
}
2、日志截图:
1、XML布局文件的代码:<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<SearchView
android:id="@+id/searchView_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</SearchView>
<ListView
android:id="@+id/listView_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
2、MainActivity的代码:publicclass MainActivity extends Activity {
privatestaticfinal String TAG = "MainActivity";
private ListView listView_main;
private SearchView searchView_main;
private MySQLiteOpenHelper dbHelper = null;
private SQLiteDatabase db = null;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView_main = (ListView) findViewById(R.id.listView_main);
searchView_main = (SearchView) findViewById(R.id.searchView_main);
dbHelper = new MySQLiteOpenHelper(this);
db = dbHelper.getReadableDatabase();
// SearchView控件的监听器:查询文本监听器OnQueryTextListener
searchView_main.setOnQueryTextListener(new OnQueryTextListener() {
@Override
publicboolean onQueryTextSubmit(String query) {
returnfalse;
}
// 当查询内容发生改变时执行该方法
@Override
publicboolean onQueryTextChange(String newText) {
fillListView(newText);
returnfalse;
}
});
}
publicvoid fillListView(String data) {
Cursor cursor = null;
ContentResolver resolver = getContentResolver();
Uri uri_words = Uri.parse("content://com.steven.contentprovider.mywordsprovider/words");// 如果查询的关键词为空,则执行没有where条件的查询,也就是显示所有数据。
if (data != null && !"".equals(data)) {
// 如果查询关键词不为空,则在原来的uri地址后追加需要查询的内容
uri_words = Uri.withAppendedPath(uri_words, data);
}
cursor = resolver.query(uri_words, null, null, null, null);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_listview_main, cursor,new String[] { "word","detail" }, newint[] { R.id.text_item_word ,R.id.text_item_detail }, 2);listView_main.setAdapter(adapter);
}
* 以下代码跟本案例《SearchView实现查询》无关,而是测试Cursor是否为null的例子。/*
* 如果数据库的表为空,返回的Cursor是否为null? 结果证明cursor都不为null,只不过其中没有数据而已,但
* 也就是说:即便是没有一条数据的cursor也可以获取到列名称。是存在表结构。
*/publicvoid clickButton(View view) {
switch (view.getId()) {
case R.id.button_main_show:
// 第一种cursor的生成方法
String sql = "select id ,abc from tb_words";
Cursor cursor1 = dbHelper.selectCursor(sql, null);
// 第二种cursor的生成方法
Cursor cursor2 = db.query("tb_words", null, null, null, null, null,null);if (!cursor1.moveToFirst()) {
Toast.makeText(this, "数据为空!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, cursor1.moveToFirst() + "",Toast.LENGTH_LONG).show();String[] arrClos = cursor1.getColumnNames();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arrClos.length; i++) {
sb.append(arrClos[i]);
sb.append(",");
}
Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。