读取SDcard Database并在Android ListView显示的处理流程
虽然整个功能比较简单,但要掌握的东西还是很多的
完成整个功能主要需要以下几点内容:
一. 申请SDcard权限,让程序可以在SDcard创建文件夹和数据库文件
二. 创建一个ListView Activity 和 Activity对应的list.xml layout
三. 使用 SQLiteDatabase 来管理 SQL , execute SQL commands, and perform other common database management tasks
四. 使用 Adapter 把数据映射到ListView ,且把数据传到TextView等控件中显示出来(这位同学有关于Adapter相关资料:Android开发——说说Adapter那点事)
首先来设置SDcard的权限,加上uses-permission
AndroidManifest.xml
创建listview元素文件:
布局layout中, android:descendantFocusability="blocksDescendants" 这个属性尤其关键, 如果你需要在listview里添加按钮什么的,就需要添加这个元素,使listview不把按钮的焦点覆盖
list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:descendantFocusability="blocksDescendants">
<ImageView android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2px"
android:layout_alignParentLeft="true"/>
<TextView android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="13px"
android:paddingTop="8px"
android:paddingLeft="35px"
/>
</RelativeLayout>
创建MyListViewActivity 继承 ListActivity , 它和Activity差不多,只是多了对ListView的一些优化
MyListViewActivity.java
public class MyListViewActivity extends ListActivity {
/** Called when the activity is first created. */
//定义SQLiteDatabase对象,用于处理数据库的操作
private SQLiteDatabase db = null;
//定义Cursor游标,用于管理数据,比如获得数据库的每一行数据
private Cursor cursor = null;
//定义一个列表储存 mData
private List<Map<String, Object>> mData;
//获取自定义的function
function function = new function();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化数据库,创建文件夹和数据库文件
function.initDatabase();
mData = getData();
MyAdapter adapter = new MyAdapter(this);
setListAdapter(adapter);
}
private List<Map<String, Object>> getData() {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
//使用SQLiteDatabase的openOrCreateDatabase获取SDcard的数据库
//config.f 是在config.java里定义的文件路径变量
db = SQLiteDatabase.openOrCreateDatabase(config.f, null);
Map<String, Object> map = new HashMap<String, Object>();
try {
//查询test_listview数据
cursor = db.query("test_listview", new String[]{}, null, null, null, null, null);
//通过强大的cursor把数据库的资料一行一行地读取出来
while(cursor.moveToNext()){
String text = cursor.getString(cursor.getColumnIndex("text"));
map = new HashMap<String, Object>();
map.put("text", text);
map.put("img", R.drawable.info);
list.add(map);
}
} catch (Exception e) {
// TODO: handle exception
Log.i("opendatabase", e.toString());
}
return list;
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
function.showDialog((String)mData.get(position).get("text"), MyListViewActivity.this);
//Toast.makeText(MyListViewActivity.this, (String)mData.get(position).get("text"), Toast.LENGTH_LONG).show();
}
public final class ViewHolder{
public ImageView img;
public TextView text;
}
public class MyAdapter extends BaseAdapter{
private LayoutInflater mInflater;
ViewHolder holder = null;
public MyAdapter(Context context){
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder=new ViewHolder();
convertView = mInflater.inflate(R.layout.list, null);
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.text = (TextView)convertView.findViewById(R.id.text);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
//把字符串设置在TextView上显示
holder.text.setText((String)mData.get(position).get("text"));
return convertView;
}
}
}
配置文件,定义各种常量和变量,方便重复使用
config.java
public class config {
//获取SDcard路径
public static String CR_SDCARD = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
//定义SDcard存放数据库的文件夹
public static final String CR_URL_DBFILE = "/listview";
public static final String CR_PATH = CR_SDCARD+CR_URL_DBFILE;
public static final String CR_DBNAME = "database.db";
public static final String CR_URL_DBTABLE = CR_PATH+"/"+CR_DBNAME;//database file
public static File path = new File(CR_PATH);
public static File f = new File(CR_URL_DBTABLE);
}
自定义函数文件
function.java
public class function{
private SQLiteDatabase db;
private int i;
/**
* create database folder and database
* and check the table is already exist to create new
*/
public void initDatabase(){
if(!config.path.exists()){
config.path.mkdirs();
Log.i("init", "create a database folder");
}
if(!config.f.exists()){
try{
config.f.createNewFile();
Log.i("init", "create a new database file");
}catch(IOException e){
Log.i("init", e.toString());
}
}
try {
if(tabIsExist("test_listview")==false){
db.execSQL("create table test_listview(id integer primary key autoincrement," +
"text varchar(128))");
for(i=0;i<10;i++){
db.execSQL("insert into test_listview(text)values('Auto insert value "+i+"')");
}
Log.i("init", "create a table test_listview");
}
} catch (Exception e) {
// TODO: handle exception
Log.i("init", e.toString());
}
}
/**
* check the database is already exist
* @param tabName
* @return
*/
public boolean tabIsExist(String tabName){
boolean result = false;
if(tabName == null){
return false;
}
Cursor cursor = null;
db = SQLiteDatabase.openOrCreateDatabase(config.f, null);
try {
String sql = "select count(*) as c from sqlite_master where type ='table' " +
"and name ='"+tabName.trim()+"' ";
cursor = db.rawQuery(sql, null);
if(cursor.moveToNext()){
int count = cursor.getInt(0);
if(count>0){
result = true;
}
}
} catch (Exception e) {
// TODO: handle exception
}
return result;
}
/**
* define a dialog for show the message
* @param mess
* @param activity
*/
public void showDialog(String mess,Activity activity){
new AlertDialog.Builder(activity).setTitle("Message").setMessage(mess)
.setNegativeButton("Confirm",new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
}
})
.show();
}
}
adb查看数据sdcard数据库
补充一下,如果你需要把现有的数据库放到SDcard的话,(既是用户安装使用该软件的时候,把已经装好数据的Database放到SDcard)
先把处理好的数据库放在assets文件夹中,然后当程序第一次运行的时候,就把数据库复制到SDcard
第一步,复制已经处理好的database.db放在assets文件夹
第二步,在程序的第一个Activity判断用户的SDcard中是否已经存在这个数据库文件
第三步,若不存在,则进行复制
public void createDataBase() throws IOException{
File dbdir = config.path;
if(!dbdir.exists()){
dbdir.mkdirs();
}
if(!config.f.exists()){
config.f.createNewFile();
SQLiteDatabase.openOrCreateDatabase(config.f, null);
copyDataBase();
}
}
private void copyDataBase() throws IOException {
InputStream myInput;
//复制到的目标路径
String outFileName = config.CR_URL_DBTABLE;
OutputStream myOutput = new FileOutputStream(outFileName);
//获取Assets文件夹中的databae.db
myInput = this.getAssets().open(config.CR_DBNAME);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myInput.close();
myOutput.close();
}