如果使用SD卡,需要在AndroidManifest.xml中设置权限
<
uses-permission
android:name
="android.permission.WRITE_EXTERNAL_STORAGE"
></
uses-permission
>
<
uses-permission
android:name
="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
></
uses-permission
>
1
package
cn.arthur.common;
2
3
import
java.io.File;
4
import
java.io.FileOutputStream;
5
import
java.io.IOException;
6
import
java.io.InputStream;
7
import
java.io.OutputStream;
8
9
import
android.content.Context;
10
import
android.database.sqlite.SQLiteDatabase;
11
import
android.database.sqlite.SQLiteDatabase.CursorFactory;
12
import
android.database.sqlite.SQLiteException;
13
import
android.database.sqlite.SQLiteOpenHelper;
14
15
/**
16
*
@author
Joshua
17
* 用法:
18
* DBHelper dbHelper = new DBHelper(this);
19
* dbHelper.createDataBase();
20
* SQLiteDatabase db = dbHelper.getWritableDatabase();
21
* Cursor cursor = db.query()
22
* db.execSQL(sqlString);
23
* 注意:execSQL不支持带;的多条SQL语句,只能一条一条的执行,晕了很久才明白
24
* 见execSQL的源码注释 (Multiple statements separated by ;s are not supported.)
25
* 将把assets下的数据库文件直接复制到DB_PATH,但数据库文件大小限制在1M以下
26
* 如果有超过1M的大文件,则需要先分割为N个小文件,然后使用copyBigDatabase()替换copyDatabase()
27
*/
28
public
class
DBHelper
extends
SQLiteOpenHelper {
29
//
用户数据库文件的版本
30
private
static
final
int
DB_VERSION
=
1
;
31
//
数据库文件目标存放路径为系统默认位置,cn.arthur.examples 是你的包名
32
private
static
String DB_PATH
=
"
/data/data/cn.arthur.examples/databases/
"
;
33
/*
34
//如果你想把数据库文件存放在SD卡的话
35
private static String DB_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
36
+ "/arthurcn/drivertest/packfiles/";
37
*/
38
private
static
String DB_NAME
=
"
hello.db
"
;
39
private
static
String ASSETS_NAME
=
"
hello.db
"
;
40
41
private
SQLiteDatabase myDataBase
=
null
;
42
private
final
Context myContext;
43
44
/**
45
* 如果数据库文件较大,使用FileSplit分割为小于1M的小文件
46
* 此例中分割为 hello.db.101 hello.db.102 hello.db.103
47
*/
48
//
第一个文件名后缀
49
private
static
final
int
ASSETS_SUFFIX_BEGIN
=
101
;
50
//
最后一个文件名后缀
51
private
static
final
int
ASSETS_SUFFIX_END
=
103
;
52
53
/**
54
* 在SQLiteOpenHelper的子类当中,必须有该构造函数
55
*
@param
context 上下文对象
56
*
@param
name 数据库名称
57
*
@param
factory 一般都是null
58
*
@param
version 当前数据库的版本,值必须是整数并且是递增的状态
59
*/
60
public
DBHelper(Context context,String name,CursorFactory factory,
int
version) {
61
//
必须通过super调用父类当中的构造函数
62
super
(context,name,
null
,version);
63
this
.myContext
=
context;
64
}
65
66
public
DBHelper(Context context,
int
version){
67
this
(context,version);
68
}
69
70
public
DBHelper(Context context,String name){
71
this
(context,DB_VERSION);
72
}
73
74
public
DBHelper (Context context) {
75
this
(context,DB_PATH
+
DB_NAME);
76
}
77
78
public
void
createDataBase()
throws
IOException{
79
boolean
dbExist
=
checkDataBase();
80
if
(dbExist){
81
//
数据库已存在,do nothing.
82
}
else
{
83
//
创建数据库
84
try
{
85
File dir
=
new
File(DB_PATH);
86
if
(
!
dir.exists()){
87
dir.mkdirs();
88
}
89
File dbf
=
new
File(DB_PATH
+
DB_NAME);
90
if
(dbf.exists()){
91
dbf.delete();
92
}
93
SQLiteDatabase.openOrCreateDatabase(dbf,
null
);
94
//
复制asseets中的db文件到DB_PATH下
95
copyDataBase();
96
}
catch
(IOException e) {
97
throw
new
Error(
"
数据库创建失败
"
);
98
}
99
}
100
}
101
102
//
检查数据库是否有效
103
private
boolean
checkDataBase(){
104
SQLiteDatabase checkDB
=
null
;
105
String myPath
=
DB_PATH
+
DB_NAME;
106
try
{
107
checkDB
=
SQLiteDatabase.openDatabase(myPath,SQLiteDatabase.OPEN_READONLY);
108
}
catch
(SQLiteException e){
109
//
database does't exist yet.
110
}
111
if
(checkDB
!=
null
){
112
checkDB.close();
113
}
114
return
checkDB
!=
null
?
true
:
false
;
115
}
116
117
/**
118
* Copies your database from your local assets-folder to the just created empty database in the
119
* system folder,from where it can be accessed and handled.
120
* This is done by transfering bytestream.
121
*
*/
122
private
void
copyDataBase()
throws
IOException{
123
//
Open your local db as the input stream
124
InputStream myInput
=
myContext.getAssets().open(ASSETS_NAME);
125
//
Path to the just created empty db
126
String outFileName
=
DB_PATH
+
DB_NAME;
127
//
Open the empty db as the output stream
128
OutputStream myOutput
=
new
FileOutputStream(outFileName);
129
//
transfer bytes from the inputfile to the outputfile
130
byte
[] buffer
=
new
byte
[
1024
];
131
int
length;
132
while
((length
=
myInput.read(buffer))
>
0
){
133
myOutput.write(buffer,
0
,length);
134
}
135
//
Close the streams
136
myOutput.flush();
137
myOutput.close();
138
myInput.close();
139
}
140
141
//
复制assets下的大数据库文件时用这个
142
private
void
copyBigDataBase()
throws
IOException{
143
InputStream myInput;
144
String outFileName
=
DB_PATH
+
DB_NAME;
145
OutputStream myOutput
=
new
FileOutputStream(outFileName);
146
for
(
int
i
=
ASSETS_SUFFIX_BEGIN; i
<
ASSETS_SUFFIX_END
+
1
; i
++
) {
147
myInput
=
myContext.getAssets().open(ASSETS_NAME
+
"
.
"
+
i);
148
byte
[] buffer
=
new
byte
[
1024
];
149
int
length;
150
while
((length
=
myInput.read(buffer))
>
0
){
151
myOutput.write(buffer,length);
152
}
153
myOutput.flush();
154
myInput.close();
155
}
156
myOutput.close();
157
}
158
159
@Override
160
public
synchronized
void
close() {
161
if
(myDataBase
!=
null
){
162
myDataBase.close();
163
}
164
super
.close();
165
}
166
167
/**
168
* 该函数是在第一次创建的时候执行,
169
* 实际上是第一次得到SQLiteDatabase对象的时候才会调用这个方法
170
*/
171
@Override
172
public
void
onCreate(SQLiteDatabase db) {
173
}
174
175
/**
176
* 数据库表结构有变化时采用
177
*/
178
@Override
179
public
void
onUpgrade(SQLiteDatabase db,
int
oldVersion,
int
newVersion) {
180
}
181
182
}
183
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|