參考博客:http://blog.csdn.net/xiaanming/article/details/8679521
最近做畢設,一直在研究數據庫方面的問題,學會了利用Assets,這個文件夾使用AssetManager類來進行訪問。
Android要使用外部資源文件一般有兩種方法,分別是:
1.第一種是res目錄下存放的可編譯的資源文件:
這種資源文件系統會在R.java裏面自動生成該資源文件的ID,所以訪問這種資源文件比較簡單,通過R.XXX.ID即可;
2.第二種是assets目錄下存放的原生資源文件:
因爲系統在編譯的時候不會編譯assets下的資源文件,所以我們不能通過R.XXX.ID的方式訪問它們。我們不能通過該資源的絕對路徑去訪問它們,因爲apk安裝之後會放在/data/app/**.apk目錄下,以apk形式存在,asset/res和被綁定在apk裏,並不會解壓到/data/data/YourApp目錄下去,所以我們無法直接獲取到assets的絕對路徑,因爲它們根本就沒有。
不過Android系統提供了一個AssetManager工具類,它提供對應用程序的原始資源文件進行訪問;這個類提供了一個低級別的API,它允許以簡單的字節流的形式打開和讀取和應用程序綁定在一起的原始資源文件。通過getAssets()方法獲取AssetManager對象。
1. 先在Activity裏面調用getAssets()來獲取AssetManager引用。我們首先要做的是把數據庫文件“jingdian_db”複製到代碼工程的assets文件夾下,assets文件夾裏面的文件都是保持原始的文件格式,需要用AssetManager以字節流的形式讀取文件。
2. 再用AssetManager的open(String fileName)方法則指定讀取的文件以及訪問模式就能得到輸入流InputStream。
3. 然後就是用已經open file 的inputStream讀取文件,讀取完成後記得inputStream.close() 。
4.調用AssetManager.close()關閉AssetManager。
首先外部導入最主要的是,第一次使用的時候,判斷是否已經存在了相應的文件,如果沒有,再導入
private void importDB() {
File file = new File(getFilesDir(), DbName);
// String DbName = "people_db";
// 判斷是否存在
if (file.exists() && file.length() > 0) {
Log.i("import_db", "已存在");
} else {
// 使用AssetManager類來訪問assets文件夾
AssetManager asset = getAssets();
InputStream is = null;
FileOutputStream fos = null;
try {
is = asset.open(DbName);
fos = new FileOutputStream(file);
int len = 0;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
同樣,打開數據庫文件,不是以前的SQLiteDatabase db = getWritableDatabase()/getReadableDatabase();
而是: SQLiteDatabase sqLite = SQLiteDatabase.openOrCreateDatabase("data/data/com.test.phonebooks/files/people_db", null);
path傳值:data/data/包名/files/數據庫名稱
本次操作的數據庫有四個字段,分別是_id,name,age,position
這是創建表stuff時的屬性:"create table stuff(_id integer primary key autoincrement, name text not null, age integer, position text not null)"
MainActivity類:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
// 定義兩個按鈕
private Button submit, look;
static String DbName = "people_db";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 根據id 獲取到相對應的控件
submit = (Button) findViewById(R.id.button1);
look = (Button) findViewById(R.id.button2);
// 按鈕設置點擊監聽
submit.setOnClickListener(this);
look.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
importDB();
break;
case R.id.button2:
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setClass(this, ResultActivity.class);
startActivity(intent);
break;
default:
break;
}
}
private void importDB() {
File file = new File(getFilesDir(), DbName);
// String DbName = "people_db";
// 判斷是否存在
if (file.exists() && file.length() > 0) {
Log.i("import_db", "已存在");
} else {
// 使用AssetManager類來訪問assets文件夾
AssetManager asset = getAssets();
InputStream is = null;
FileOutputStream fos = null;
try {
is = asset.open(DbName);
fos = new FileOutputStream(file);
int len = 0;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ResultActivity類:
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.test.mode.Person;
public class ResultActivity extends Activity implements OnItemClickListener {
private ListView listView;
private DbAdapter adapter;
// 打開數據庫
static SQLiteDatabase sqLite = SQLiteDatabase.openOrCreateDatabase(
"data/data/com.test.phonebooks/files/people_db", null);
public static final String TABLE_NAME = "stuff";
List<Person> bookList = new ArrayList<Person>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
// 獲取ListView
listView = (ListView) findViewById(R.id.listView1);
bookList = queryData();
// 實例化DbAdapter
adapter = new DbAdapter(getApplication(), bookList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
// 查詢數據庫,將每一行的數據封裝成一個person 對象,然後將對象添加到List中
private List<Person> queryData() {
List<Person> list = new ArrayList<Person>();
// 調用query()獲取Cursor
Cursor c = sqLite.query(TABLE_NAME, null, null, null, null, null, null,
null);
while (c.moveToNext()) {
int _id = c.getInt(c.getColumnIndex("_id"));
String name = c.getString(c.getColumnIndex("name"));
int age = c.getInt(c.getColumnIndex("age"));
String position = c.getString(c.getColumnIndex("position"));
// 用一個Person對象來封裝查詢出來的數據
Person p = new Person();
p.set_id(_id);
p.setName(name);
p.setAge(age);
p.setPosition(position);
list.add(p);
}
return list;
}
// 自定義DbAdapter
public class DbAdapter extends BaseAdapter {
private List<Person> list;
private Context context;
private LayoutInflater layoutInflater;
public DbAdapter(Context context, List<Person> list) {
layoutInflater = LayoutInflater.from(context);
this.context = context;
this.list = list;
}
// 刷新適配器,更新數據
public void refresh(List<Person> list) {
this.list = list;
notifyDataSetChanged();
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Person p = list.get(position);
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.item, null);
holder.name = (TextView) convertView
.findViewById(R.id.textView1);
holder.age = (TextView) convertView
.findViewById(R.id.textView2);
holder.position = (TextView) convertView
.findViewById(R.id.textView3);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(p.getName());
holder.age.setText("" + p.getAge());
holder.position.setText(p.getPosition());
return convertView;
}
public class ViewHolder {
public TextView name;
public TextView age;
public TextView position;
public TextView id;
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
final Person p = bookList.get(position);
final long temp = id;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("真的要刪除該記錄?")
.setPositiveButton("是", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 查詢數據庫是否是關閉狀態
Boolean bb = sqLite.isOpen();
if (bb == false) {
// 如果是關閉狀態,就打開數據庫,否則會報錯
sqLite = SQLiteDatabase
.openOrCreateDatabase(
"data/data/com.test.phonebooks/files/people_db",
null);
}
// 查詢完畢後,會關閉數據庫,此時操作數據庫刪除條目,會報錯
/*
* 錯誤信息:java.lang.illegalstateexception
* android.database.
* sqlite.SQLiteDatabase.acquireference()
*/
sqLite.delete(TABLE_NAME, "_id=?",
new String[] { String.valueOf(p.get_id()) });
// 重新刷新適配器,並重新查詢
adapter.refresh(queryData());
}
}).setNegativeButton("否", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
// 關閉數據庫
sqLite.close();
}
}
還有一個Person類:
public class Person {
private String name;
private int age;
private String position;
private int _id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
}
源碼下載