当前位置: 编程技术>移动开发
本页文章导读:
▪搜寻的文章 搜索的文章
Android 中涉及数据库查询的地方一般都会有一个 query() 方法,而这些 query 中有大都(全部?)会有一个参数 selectionArgs,比如下面这个 android.database.sqlite.SQLiteDatabase.query():view pl.........
▪ 学习札记-ContentProvider与listview结合显示电话本信息 学习笔记-ContentProvider与listview结合显示电话本信息
ContentProvider是Android四大组件(Activity,intent,service,contentProvider)之一,它实现了一组标准方法,能够让其他引用保存或读取contentprovider处理的.........
▪ adnroid selector 组件的状态展示该状态对应的背景图片 adnroid selector 组件的状态显示该状态对应的背景图片
selector相当于图片选择器,在res下新建个drawable文件夹,把组件的背景设成对应你建的xml文件名
下面是我做的一个简单的例子
项目结构图.........
[1]搜寻的文章
来源: 互联网 发布时间: 2014-02-18
搜索的文章
Android 中涉及数据库查询的地方一般都会有一个 query() 方法,而这些 query 中有大都(全部?)会有一个参数 selectionArgs,比如下面这个 android.database.sqlite.SQLiteDatabase.query():
view plaincopy to clipboardprint?
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
selection 参数很好理解,就是 SQL 语句中 WHERE 后面的部分,即过滤条件, 比如可以为 id=3 AND name='Kevin Yuan' 表示只返回满足 id 为 3 且 name 为 "Kevin Yuan" 的记录。
再实际项目中像上面那样简单的“静态”的 selection 并不多见,更多的情况下要在运行时动态生成这个字符串,比如
view plaincopy to clipboardprint?
public doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name='" + name + "'", // selection
//...... 更多参数省略
);
}
public doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name='" + name + "'", // selection
//...... 更多参数省略
);
}
在这种情况下就要考虑一个字符转义的问题,比如如果在上面代码中传进来的 name 参数的内容里面有单引号('),就会引发一个 "SQLiteException syntax error .... "。
手工处理转义的话,也不麻烦,就是 String.replace() 调用而已。但是 Android SDK 为我们准备了 selectionArgs 来专门处理这种问题:
view plaincopy to clipboardprint?
public void doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name=?", // selection
new String[] {name}, //selectionArgs
//...... 更多参数省略
);
// ...... 更多代码
}
public void doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name=?", // selection
new String[] {name}, //selectionArgs
//...... 更多参数省略
);
// ...... 更多代码
}
也就是说我们在 selection 中需要嵌入字符串的地方用 ? 代替,然后在 selectionArgs 中依次提供各个用于替换的值就可以了。在 query() 执行时会对 selectionArgs 中的字符串正确转义并替换到对应的 ? 处以构成完整的 selection 字符串。 有点像 String.format()。
不过需要注意的是 ? 并不是“万金油”,只能用在原本应该是字符串出现的地方。比如下面的用法是错误的:
view plaincopy to clipboardprint?
public void doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"? = " + id + " AND name=?", // selection XXXX 错误!? 不能用来替换字段名
new String[]{"id", name}, //selectionArgs
//...... 更多参数省略
);
// ...... 更多代码
}
Android 中涉及数据库查询的地方一般都会有一个 query() 方法,而这些 query 中有大都(全部?)会有一个参数 selectionArgs,比如下面这个 android.database.sqlite.SQLiteDatabase.query():
view plaincopy to clipboardprint?
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
selection 参数很好理解,就是 SQL 语句中 WHERE 后面的部分,即过滤条件, 比如可以为 id=3 AND name='Kevin Yuan' 表示只返回满足 id 为 3 且 name 为 "Kevin Yuan" 的记录。
再实际项目中像上面那样简单的“静态”的 selection 并不多见,更多的情况下要在运行时动态生成这个字符串,比如
view plaincopy to clipboardprint?
public doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name='" + name + "'", // selection
//...... 更多参数省略
);
}
public doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name='" + name + "'", // selection
//...... 更多参数省略
);
}
在这种情况下就要考虑一个字符转义的问题,比如如果在上面代码中传进来的 name 参数的内容里面有单引号('),就会引发一个 "SQLiteException syntax error .... "。
手工处理转义的话,也不麻烦,就是 String.replace() 调用而已。但是 Android SDK 为我们准备了 selectionArgs 来专门处理这种问题:
view plaincopy to clipboardprint?
public void doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name=?", // selection
new String[] {name}, //selectionArgs
//...... 更多参数省略
);
// ...... 更多代码
}
public void doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"id=" + id + " AND name=?", // selection
new String[] {name}, //selectionArgs
//...... 更多参数省略
);
// ...... 更多代码
}
也就是说我们在 selection 中需要嵌入字符串的地方用 ? 代替,然后在 selectionArgs 中依次提供各个用于替换的值就可以了。在 query() 执行时会对 selectionArgs 中的字符串正确转义并替换到对应的 ? 处以构成完整的 selection 字符串。 有点像 String.format()。
不过需要注意的是 ? 并不是“万金油”,只能用在原本应该是字符串出现的地方。比如下面的用法是错误的:
view plaincopy to clipboardprint?
public void doQuery(long id, final String name) {
mDb.query("some_table", // table name
null, // columns
"? = " + id + " AND name=?", // selection XXXX 错误!? 不能用来替换字段名
new String[]{"id", name}, //selectionArgs
//...... 更多参数省略
);
// ...... 更多代码
}
[2] 学习札记-ContentProvider与listview结合显示电话本信息
来源: 互联网 发布时间: 2014-02-18
学习笔记-ContentProvider与listview结合显示电话本信息
ContentProvider是Android四大组件(Activity,intent,service,contentProvider)之一,它实现了一组标准方法,能够让其他引用保存或读取contentprovider处理的各种数据类型。
在android中,由于每个应用程序独立运行在自己的虚拟机中,在正常情况下,不能读取其他应用的db文件,因此需要contentProvider来解决不同应用程序间的数据共享问题。
android自身提供了现成的contentProvider:Contacts,Browser,CallLog,Settings,MediaStore。通过唯一的contentResolver来使用需要的contentProvider,resolver提供了query,insert,update等方法,使用时可能需要URI(String类型的contentProvider完整路径).
以查询联系人姓名和电话为例,整体处理逻辑为:
创建listData,listview-->获取contentResolver对象-->得到电话本的cursor-->遍历cursor-->关闭cursor-->创建listadapter-->加入到listview-->添加listview事件。
遍历cursor的逻辑为:
创建map-->得到联系人姓名-->加入map-->处理多个号码-->加入map-->map加入listData
处理多个号码的逻辑为:
得到号码的cursor2-->遍历cursor2(获取号码-->处理号码显示
代码如下:
参考http://blog.sina.com.cn/s/blog_48843e730100m6nw.html对读取多个号码的补充。
package com.helen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
public class ContactBook extends Activity {
ListView m_lstView; // 列表
ArrayList<Map<String, String>> lstData;
private static final String NAME = "name";
private static final String NUMBER = "number";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // 设置布局
m_lstView = (ListView) findViewById(R.id.lst_contacts); // 获取xml中定义的listview
lstData = new ArrayList<Map<String, String>>();
String number = "";
// 获取数据库电话本的cursor
ContentResolver cr = getContentResolver();
// 取得电话本中开始一项的光标
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
startManagingCursor(cur);
while (cur.moveToNext()) {
Map<String, String> mp = new HashMap<String, String>();
String cons = cur.getString(cur
.getColumnIndex(PhoneLookup.DISPLAY_NAME));
mp.put(NAME, cons); // 添加联系人姓名
// 获取联系人电话号码,处理多个号码的情况,不能直接使用PhoneLookup.NUMBER
long id = cur.getLong(cur.getColumnIndex(PhoneLookup._ID));
Cursor numCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
+ Long.toString(id), null, null);
while (numCur.moveToNext()) {
String strPhoneNumber = numCur
.getString(numCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
number += strPhoneNumber + "";
}
number += "\n";
numCur.close();
//添加到map中,并将map添加到lstData
mp.put(NUMBER, number);
lstData.add(mp);
}
cur.close();
// listAdapter存储后台数据,然后将其显示在listView中,是关键桥梁
ListAdapter lstAdp = new SimpleAdapter(this, lstData,
// 定义list中每一行的显示模板
// 这里使用android自定义的layout,表示每行包括两个数据项,也可以使用自己定义的模板
android.R.layout.simple_list_item_2,
// 需要取出的字段
new String[] { NAME, NUMBER },
// 与上面数据库字段相对应的显示样式
new int[] { android.R.id.text1, android.R.id.text2 });
// 将adp添加到listview中
m_lstView.setAdapter(lstAdp);
// 为listview中的每一项添加事件监听
// 鼠标滚动事件
m_lstView
.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
// 可以加入自己的事件
display("滚动到第 "
+ Long.toString(arg0.getSelectedItemId()) + "项");
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
// 鼠标点击事件
m_lstView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
display("选中第 " + Long.toString(arg0.getSelectedItemId()) + "项");
}
});
}
/**
* 显示Toast提示信息
*
* @param str
*/
private void display(String str) {
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
}
main.xml中添加Listview:
<ListView
android:id="@+id/lst_contacts"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
</ListView>
由于读取系统中的联系人列表,因此需要在androidmanifest.xml中添加权限:
<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
运行效果如图:
ContentProvider是Android四大组件(Activity,intent,service,contentProvider)之一,它实现了一组标准方法,能够让其他引用保存或读取contentprovider处理的各种数据类型。
在android中,由于每个应用程序独立运行在自己的虚拟机中,在正常情况下,不能读取其他应用的db文件,因此需要contentProvider来解决不同应用程序间的数据共享问题。
android自身提供了现成的contentProvider:Contacts,Browser,CallLog,Settings,MediaStore。通过唯一的contentResolver来使用需要的contentProvider,resolver提供了query,insert,update等方法,使用时可能需要URI(String类型的contentProvider完整路径).
以查询联系人姓名和电话为例,整体处理逻辑为:
创建listData,listview-->获取contentResolver对象-->得到电话本的cursor-->遍历cursor-->关闭cursor-->创建listadapter-->加入到listview-->添加listview事件。
遍历cursor的逻辑为:
创建map-->得到联系人姓名-->加入map-->处理多个号码-->加入map-->map加入listData
处理多个号码的逻辑为:
得到号码的cursor2-->遍历cursor2(获取号码-->处理号码显示
代码如下:
参考http://blog.sina.com.cn/s/blog_48843e730100m6nw.html对读取多个号码的补充。
package com.helen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
public class ContactBook extends Activity {
ListView m_lstView; // 列表
ArrayList<Map<String, String>> lstData;
private static final String NAME = "name";
private static final String NUMBER = "number";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // 设置布局
m_lstView = (ListView) findViewById(R.id.lst_contacts); // 获取xml中定义的listview
lstData = new ArrayList<Map<String, String>>();
String number = "";
// 获取数据库电话本的cursor
ContentResolver cr = getContentResolver();
// 取得电话本中开始一项的光标
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
startManagingCursor(cur);
while (cur.moveToNext()) {
Map<String, String> mp = new HashMap<String, String>();
String cons = cur.getString(cur
.getColumnIndex(PhoneLookup.DISPLAY_NAME));
mp.put(NAME, cons); // 添加联系人姓名
// 获取联系人电话号码,处理多个号码的情况,不能直接使用PhoneLookup.NUMBER
long id = cur.getLong(cur.getColumnIndex(PhoneLookup._ID));
Cursor numCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
+ Long.toString(id), null, null);
while (numCur.moveToNext()) {
String strPhoneNumber = numCur
.getString(numCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
number += strPhoneNumber + "";
}
number += "\n";
numCur.close();
//添加到map中,并将map添加到lstData
mp.put(NUMBER, number);
lstData.add(mp);
}
cur.close();
// listAdapter存储后台数据,然后将其显示在listView中,是关键桥梁
ListAdapter lstAdp = new SimpleAdapter(this, lstData,
// 定义list中每一行的显示模板
// 这里使用android自定义的layout,表示每行包括两个数据项,也可以使用自己定义的模板
android.R.layout.simple_list_item_2,
// 需要取出的字段
new String[] { NAME, NUMBER },
// 与上面数据库字段相对应的显示样式
new int[] { android.R.id.text1, android.R.id.text2 });
// 将adp添加到listview中
m_lstView.setAdapter(lstAdp);
// 为listview中的每一项添加事件监听
// 鼠标滚动事件
m_lstView
.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
// 可以加入自己的事件
display("滚动到第 "
+ Long.toString(arg0.getSelectedItemId()) + "项");
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
// 鼠标点击事件
m_lstView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
display("选中第 " + Long.toString(arg0.getSelectedItemId()) + "项");
}
});
}
/**
* 显示Toast提示信息
*
* @param str
*/
private void display(String str) {
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
}
main.xml中添加Listview:
<ListView
android:id="@+id/lst_contacts"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
</ListView>
由于读取系统中的联系人列表,因此需要在androidmanifest.xml中添加权限:
<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
运行效果如图:
1 楼
xierentc
2011-09-25
//添加到map中,并将map添加到lstData
mp.put(NUMBER, number);
// 需要将number 清空,不然前一个值会一直累加
number ="";
lstData.add(mp);
mp.put(NUMBER, number);
// 需要将number 清空,不然前一个值会一直累加
number ="";
lstData.add(mp);
[3] adnroid selector 组件的状态展示该状态对应的背景图片
来源: 互联网 发布时间: 2014-02-18
adnroid selector 组件的状态显示该状态对应的背景图片
selector相当于图片选择器,在res下新建个drawable文件夹,把组件的背景设成对应你建的xml文件名
下面是我做的一个简单的例子
项目结构图见附件
btn.xml代码:
<?xml version="1.0" encoding="utf-8" ?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--没有焦点时的图片背景 --> <item android:state_window_focused="false" android:drawable="@drawable/a" /> <!-- 非触摸模式下获得焦点并单击时的背景图片 --> <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/b" /> <!-- 触摸模式下单击时的背景图片 --> <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/c" /> <!-- 选中时的图片背景 --> <item android:state_selected="true" android:drawable="@drawable/d" /> <!-- 获得焦点时的图片背景 --> <item android:state_focused="true" android:drawable="@drawable/e" /> </selector>
main.xml代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/btn" ></Button> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/btn" ></Button> </LinearLayout>
最新技术文章: