TR
NG Đ I H C CÔNG NGH THÔNG TIN
ƯỜ
Ạ Ọ
Ệ
KHOA CÔNG NGH PH N M M
Ầ
Ệ
Ề
Seminar Subject: Data Storage in Android
Giáo viên h ướ ng d n: Cáp Ph m Đình Thăng. ạ ẫ
Sinh viên th c hi n: ự ệ
Nguy n Văn Sinh 105020130 ễ
Tôn Ng c T n 10520133 ẩ ọ
1 Gi
i thi u v cách l u tr trên android:
ớ
ệ ề
ư
ữ
ấ Android cung c p cho b n m t s l a ch n đ l u tr d li u c a ng d ng m t cách r t ữ ữ ệ ủ ứ ộ ố ự ể ư ụ ấ ạ ọ ộ
i pháp l u tr tùy thu c vào ph thu c vào s l a ch n c a b n và b n v ng. Các gi ề ữ ả ọ ủ ạ ự ự ư ữ ụ ộ ộ
ch ng trình c a b n đang phát tri n. ươ ủ ạ ể
• Shared Storage: D li u c a b n s đ c l u tr d ữ ệ ủ ạ ẽ ượ ư ữ ướ ạ ị i d ng c p khóa-giá tr , ặ
đây là cách l u tr truy n th ng trên di đ ng. Chúng ta mu n l u tr UI state, user ộ ố ư ư ữ ữ ề ố
preferences hay application setting thì đây là m t c ch g n nh đ l u tr . ữ ộ ơ ế ọ ẹ ể ư
• File: Android cho phép chúng ta t t b di đ ng. ả i và l u các t p tin trên thi ệ ư ế ị ộ
• SQLite Databases: L u tr d li u d ữ ữ ệ ướ ạ ự i d ng m t c u trúc mà b n xây d ng ộ ấ ư ạ
ng đ c dùng nhi u trong android s n trong m t c s d li u riêng. Cách này th ẵ ộ ơ ở ữ ệ ườ ượ ề
đ xây d ng các ng d ng ể ư ứ ụ
• Network Connection: D li u s đ ữ ệ ẽ ượ c chia s và l u tr trên web thông qua ữ ư ẻ
máy ch d li u c a b n. ủ ữ ệ ủ ạ
• Ngoài ra, android cung c p cho b n m t cách đ chia s các d li u cá nhân ộ ữ ệ ể ẻ ấ ạ
c a ng d ng cho các ng d ng khác thông qua ứ ủ ứ ụ ụ Content Provider. Chúng ta có thể
truy c p Content Provider đ s d ng h th ng đ c phép. ể ử ụ ệ ố ậ ượ
1.1 Shared Storage:
cho phép b n l u tr và L pớ Shared Preferences cung c pấ m t khuôn kh chung ộ ổ ạ ư ữ l yấ c pặ
i d ng key-value. B n có th s d ng Shared Preferences đ l u b t kì ki u d giá trị d ướ ạ ể ư ấ ể ử ụ ể ữ ạ
li u m c đ nh nào: ặ ị ệ Booleans, floats, ints, longs ho c ặ strings. D li u này s t n t ẽ ồ ạ ữ ệ ố i su t
phiên làm vi c c a ng ệ ủ ườ i dùng (ngày c khi ng d ng c a b n có b đóng đi). ụ ủ ạ ứ ả ị
u đi m: Ư ể
• D li u l u tr ch dành riêng cho ng d ng mà nó đ c vi t ra. ữ ệ ư ữ ỉ ứ ụ ượ ế
• Đ c coi là m t ph n thông tin c a h th ng. ầ ủ ệ ố ượ ộ
• Tính b o m t r t cao. ậ ấ ả
Nh c đi m: ể
ượ • Không th l y thông tin d li u d i d ng file. ể ấ ữ ệ ướ ạ
• Dung l ượ ấ ng b nh l u tr th p nên ch phù h p v i vi c l u tr thông tin c u ữ ấ ệ ư ớ ư ữ ộ ợ ớ ỉ
hình.
S d ng m t đ i t c m t ộ ố ượ ử ụ ng Editor đ l u d li u. Đ có đ ể ư ữ ệ ể ượ ộ đ iố
hai ph ngượ SharedPreferences cho các ng d ng c a b n t ủ ạ , hãy sử d ngụ m t trong ụ ứ ộ ngươ
th cứ :
• tham getSharedPreferences (): Sử d ngụ nó n u b n c n ạ ầ nhi u t p tin ề ậ ế
theo tên, mà b n ch đ nh . chi uế đ cượ xác đ nhị ạ ỉ ị v iớ tham s đ u tiên ố ầ
• getPreferences () : Sử d ngụ đi uề này n uế b n ch c n m t ỉ ầ ế ộ tham chi u đ n ế ạ
t pậ tin cho ho t đ ng c a b n ạ ộ ủ ạ . Vì có duy nh tấ một t pậ tin tham chi u ế cho active
//ten cua SharedPreferences
ủ ạ , b n không c a b n ạ c nầ cung c p tên. ấ
private static final String CONFIGURATION_NAME = "NAME_CONFIG";
ạ Đ ghi giá tr vào trong b nh b n c n s d ng m t đ i t ng editor: 1.1.1 T o và l u giá tr vào SharePreferences: ị ớ ạ ầ ử ụ ư ị ộ ố ượ ể ộ
• G i m t editor thông qua SharedPreference.Editor. ọ ộ
• Thêm các giá tr vào b nh đ m b ng các hàm putString(), putInt(), ớ ệ ằ ộ ị
putBoolean().
• Đ y giá tr vào b nh b ng hàm editor.comit(). ớ ằ ẩ ộ ị
btSave.setOnClickListener(new View.OnClickListener() {
@Override
Code:
public void onClick(View v) {
ủ
ấ
ườ
ậ
//l y tên c a ng
i dùng nh p trong EditText name.
String name =
edtName.getEditableText().toString().trim();
ủ
ấ
ườ
ậ
//l y id c a ng
i dùng nh p trong EditText id.
String id =
edtID.getEditableText().toString().trim();
ạ
ố
ượ
ở
ộ //t o m t đ i t
ng SharedPreferences ch đ
ế ộ
MODE_PRIVATE.
SharedPreferences editPreference =
getSharedPreferences(CONFIGURATION_NAME,
Activity.MODE_PRIVATE);
//lay doi tuong Editor dung de luu du lieu vao bo nho
Editor editor = editPreference.edit();
//day du lieu voi cap khoa-gia tri la id-name va bo nho phu
editor.putString(id, name);
//day du lieu tu bo nho phu vao bo nho thiet bi
editor.commit();
}
});
1.1.2 Truy xu t giá tr t SharePreferences: ị ừ ấ
Đ truy c p Shared Preferences thì cũng dùng ph ể ậ ươ ư ng th c getSharedPreferences, đ a ứ
vào khóa c a d li u trong SharedPreferences mà chúng ta mu n truy c p, dùng ph ủ ữ ệ ậ ố ươ ng
ị ầ th c SharedPreferences.getString (),SharedPreferences.getInt(), …đ truy xu t giá tr c n ứ ể ấ
thi t.ế
btLoad.setOnClickListener(new View.OnClickListener() {
@Override
Code:
public void onClick(View v) {
//lay id ma nguoi dung nhap thong qua edtID de lay du lieu
ra
String id =
edtID.getEditableText().toString().trim();
//lay doi tuong SharedPreferences thong qua ten va che do
Activity.
SharedPreferences editPreference =
getSharedPreferences(CONFIGURATION_NAME,Activity.MODE_PRIVATE);
//lay du lieu voi 2 tham so la: id va gia tri xuat ra khi khong co
roi sau do set cho edtName
edtName.setText(editPreference.getString(id,CONFIGURATION_NAME));
}
});
Toàn b source code và demo n m trong th m c ư ụ DemoSeminar/Seminar_Share ằ ộ
1.2 L u và đ c các t p tin trong android:
ư
ọ
ậ
Cũng nh các tiêu chu n I/O c a java thì trong android cũng cung c p openFileInput và ư ủ ẩ ấ
openFileOutput đ đ n gi n các công vi c ghi và đ c trên các dòng ho c các file. ệ ể ơ ả ặ ọ
u đi m: Ư ề
• X lí trên file đ n gi n. ử ả ơ
• Đ c file và l u tr file có th ư ể ở ữ ọ nhi u đ nh d ng. ị ề ạ
• Dung l ng file không gi i h n nh cách l u tr SharePreferences ượ ớ ạ ư ư ữ
Nh c đi m: ể
ượ • Không có tính b o m t cao. ả ậ
• Có th b l i khi xung đ t file ho c xung đ t lu ng đ c file. ể ị ỗ ặ ộ ộ ồ ọ
Các l p ti n ích đ x lí file n m trong gói Android.os.Enviroment ể ử ệ ằ ớ
Đ x lí các thao tác trên file đ ể ử c t ượ ố t ta nên x d ng các l p n m trong gói java.os ớ ử ụ ằ
• File: Thao tác x lí file. ử
• FileInputStream: đ c n i dung file. ọ ộ
• FileOutputStream:Ghi n i dung file. ộ
1.2.1 Đ c file: ọ
Mu n đ c m t file lên ta ph i dung l p ớ FileInputStream ả ố ọ ộ ớ đ m file và dùng l p ể ở
InputStreamReader đ m m t dòng đ c file. ể ở ộ ọ
Code:
private String readFile() throws IOException
{
//doc ten cua file tu edtFilePath
FILE_NAME = edtFilePath.getEditableText().toString().trim();
//mo mot file len de doc
FileInputStream ios = openFileInput(FILE_NAME);
//mot kenh truu tuong hoa dung de doc cac dinh dang dau vao
//trong truong hop nay la file
InputStreamReader isr= new InputStreamReader(ios);
//tao mot mang dung de doc du lieu nhan duoc tu file
char[] data = new char[1024];
//dung StringBuffer de nhan du lieu tu file ra
StringBuffer strBuffer = new StringBuffer();
int len = 0;
//khi chua ket thuc file thi doc du lieu vao strBuffer
while((len = isr.read(data)) != -1)
{
strBuffer.append(new String(data, 0, len));
}
//dong file va dong kenh doc file
isr.close();
ios.close();
//tra ve chuoi du lieu trong file
return strBuffer.toString();
}
1.2.2 Ghi file:
Mu n đ c m t file lên ta ph i dung l p ớ ớ FileOutputStream đ m file và dùng l p ể ở ả ộ ọ ố
OutputStreamWriter đ m m t dòng đ c file. ể ở ộ ọ
Có nhi u ch đ đ m file đ ghi là: ế ộ ể ở ề ể
Context.MODE_PRIVATE: đ cfile mà d li u cũ c a file b ghi đè b i d li u m i. ữ ệ
• ở ữ ệ ủ ớ ọ ị
Context.MODE_APPEND: đ cfile mà d li u m i c a file đ
• c ghi ti p t c d i d ớ ủ ữ ệ ọ ượ ế ụ ướ ữ
li u cũ. ệ
private void writeFile(String inText) throws IOException
{
//lay ten file tu edtFilePath
FILE_NAME = edtFilePath.getEditableText().toString().trim();
//mo mot file neu co hoac tao mot file moi neu chua co
FileOutputStream fos = openFileOutput(FILE_NAME,
Context.MODE_PRIVATE);
//mo mot luong(kenh) du lieu de ghi vao files
OutputStreamWriter osw = new OutputStreamWriter(fos);
//chi viet ra mot bo dem trong thiet bi di dong
osw.write(inText + "\n");
//day vao file can luu
osw.flush();
//dong file va kenh du lieu
osw.close();
fos.close();
}
t b ngo i vi đ l u tr file: 1.2.3 Ki m tra thi ể ế ị ể ư ữ ạ
Android có th giúp b n ki m tra m t thi t b SD-Card có đang đ ể ể ạ ộ ế ị ượ ỗ ợ ể ư ữ ệ c h tr đ l u d li u
hay không.
Ta dùng l p Enviroment đ ki m tra và l y tr ng thái c a môi tr ng. ể ể ủ ấ ạ ớ ườ
Code:
private boolean hasSDCard()
{
//kiem tra co ho tro the SDCard ben ngoai hay khong
//lay trang thai cua bo nho ngoai SDCard, tra ve trang thai duoi
dang chuoi
String state = Environment.getExternalStorageState();
//kiem tra da duoc dua vao he thong hay chua
if(state.equals(Environment.MEDIA_MOUNTED))
{
return true;
}
return false;
}
B n làm vi c trên file nên s ném ra các ngo i l ạ ệ ẽ ệ ạ IOException, ta s x d ng hàm try catch ẽ ử ụ
i. T t c các demo và source code n m trong DemoSeminar/Seminar_FileDemo. đ b t l ể ắ ỗ ấ ả ằ
1.3 C s d li u trong Android:
ơ ở ữ ệ
Android cung c p đ y đ các quan h c s d li u thông qua th vi n SQLite mà không ệ ơ ở ữ ệ ầ ủ ư ệ ấ
ệ ộ ậ áp đ t b t kì h n ch nào l n. S d ng SQLite có th t o c s d li u quan h đ c l p ể ạ ơ ở ữ ệ ặ ấ ử ụ ế ạ ớ
cho m i ng d ng. ỗ ứ ụ
T t c các c s d li u trong android đ ơ ở ữ ệ ấ ả ượ ư ư ụ c l u trong th m c
/data/data/
Context Provider ( ph n sau). ầ ở
1.3.1 Gi i thi u v SQLite: ớ ệ ề
• SQLite là m t b n SQL sever less c a SQL database engine. ộ ả ủ
• Nh g n và linh ho t v i dung l ạ ớ ẹ ọ ượ ủ ng kho ng 300kb(chi u trong kho ng d ng c a ứ ụ ế ả
thi t b ) ế ị
• Đa n n t ng và không c n c u hình m nh. ầ ấ ề ả ạ
• Không h tr m t s tính năng ví d nh qu n lí user s d ng, không có khóa ngo i, ạ ự ư ả ỗ ợ ộ ố ử ụ
không có các ràng bu c toàn v n… ẹ ộ
i data/data/
1.3.2 Các l p c b n khi s d ng SQLite: ớ ơ ả ư ụ
1.3.2.1 L p SQLiteOpenHelper: ớ
1.3.2.1.1 Gi ớ i thi u: ệ
SQLiteOpenHelper là l p qu n lí vi c k t n i, t o và qu n lí c s d li u cũng nh phiên ệ ế ố ạ ơ ở ữ ệ ư ả ả ớ
b n c a c s d li u. ả ủ ơ ở ữ ệ
• Đ i t ng c a l p này c n tham chi u đ n m t đ i t ng Context. M i database ố ượ ộ ố ượ ủ ớ ế ế ầ ỗ
đ ượ ạ ả c t o ra n m trong m t ng d ng riêng nên đ qu n lí chúng ta c n ph i ộ ứ ụ ể ằ ả ầ
chuy n vào ng c nh Context đ SQLiteOpenHelper nh n bi t và qu n lí. ữ ả ề ề ậ ế ả
Cách t t nh t đ s d ng l p này là chúng ta t o ra m t l p m i k th a các ph ố ấ ề ử ụ ớ ế ừ ộ ớ ạ ớ ươ ứ ng th c
c a SQLiteOpenHelper đ d s d ng nh ví d sau: ủ ể ễ ử ụ ư ụ
1.3.2.1.2 Các ph ng th c: ươ ứ
• Hàm kh i t o: ở ạ
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int
version), g m có 4 tham s truy n vào là: ề ồ ố
Context context : ng c nh Context hi n t ữ ả i ệ ạ
SQLiteDatabase.CursorFactory factory: dùng đ cho phép các l p con đ c tr v ể ớ ượ ả ề
con tr cursor khi g i câu query ỏ ọ
String name: tên c a database. ủ
int version: phiên b n c a database. ả ủ
• Các ph ng th c o đ c m c đ nh k th a trong l p m i: ươ ứ ả ượ ế ừ ặ ị ớ ớ
c g i khi database đ ượ ọ ượ ạ ầ ớ c t o l n đ u tiên v i ầ o Void onCreate(SQLiteDatabase db), đ
tham s :ố
SQLiteDatabase db: đ i t ng dùng đ qu n lí các công vi c c a database. ố ượ ệ ủ ể ả
ượ ọ ầ c g i khi c n o void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),đ
update phiên b n cho database, g m các tham s sau: ả ồ ố
• Các ph ươ ng th c khác: ứ
SQLiteDatabase db: đ i t ng qu n lí các công vi c c a database. ố ượ ệ ủ ả
int oldVersion: phiên b n cũ c a database. ủ ả
int newVersion: phiên b n m i c a database. ớ ủ ả
(SQLiteDatabase db), g i m t đ i t ng SQLiteDatabase khi c n thi t (ít s ộ ố ượ ọ ầ ế ử o onOpen
d ng). ụ
(): đóng đ i t ng SQLiteOpenHelper. ố ượ o close
getDatabaseName(): tr v tên c a database. ả ề ủ o String
getReadableDatabase() m database hi n hành đ đ c. ở ể ọ ệ o SQLiteDatabase
getWritableDatabase() m database hi n hành đ đ c và ghi. ề ọ ệ ở o SQLiteDatabase
1.3.2.2 L p SQLiteDatabase: ớ
1.3.2.2.1 Gi ớ i thi u: ệ
Là đ i t ng đ i di n cho c s d li u mà ta t o ra b i đ i t ng SQLiteOpenHelper. ố ượ ơ ở ữ ệ ở ố ượ ệ ạ ạ
Tên c a database trong m t ng d ng là duy nh t. ộ ứ ủ ụ ấ
Là đ i t ng tr c ti p đ th c thi các câu l nh SQL và các công vi c c n th c hi n trên ố ượ ự ế ệ ầ ể ự ự ệ ệ
các table c a database. ủ
1.3.2.2.2 Các ph ng th c: ươ ứ
• void execSQL(String sql): th c thi câu l nh sql thông th ự ệ ườ ng, không tr v k t qu . ả ả ề ế
• Long insert(String table, String nullColumnHack, ContentValues values), chèn d li u ữ ệ
vào m t table. Tham s : ố ộ
table: tên c a table c n chèn d li u. ữ ệ ủ ầ o String
nullColumnHack: th ườ ng đ null. ể o String
values: đ i t ng ch a d li u chèn vào. ố ượ ứ ữ ệ o ContentValues
• int delete(String table, String whereClause, String[] whereArgs) : ph ng th c dùng đ ươ ứ ể
xóa các hàng trong c s d li u. Tham s : ố ơ ở ữ ệ
table: tên c a table trong c s d li u. ơ ở ữ ệ ủ o String
whereClause: câu l nh đi u ki n c n đ th c hi n câu delete (m n đ ệ ầ ể ự ệ ề ệ ệ ề o String
WHERE).
whereArgs: m ng tham s c n đ th c hi n delete. ể ự ố ầ ệ ả o String[]
ơ ở ữ ệ ả ề ố o Tr v s dòng đã b xóa trong c s d li u. ị
• Cursor ả ề ộ rawQuery(String sql, String[] selectionArgs): ch y câu l nh sql và tr v m t ệ ạ
ng cursor (s nói đ i t ố ượ ẽ ở ph n sau). Tham s : ố ầ
sql: câu l nh sql. ệ o String
selectionArgs: tham s c n truy n vào trong câu truy v n. ố ầ ề ấ o String[]
1.3.2.3 L p Cursor: ớ
1.3.2.3.1 Gi
i thi u: ớ ệ • Là m t đ i t ng tr v t ph ộ ố ượ ả ề ừ ươ ng th c c a h Query. ứ ủ ọ
• Hành đ ng nh m t con tr đ n t p h p các giá tr d li u n m d ỏ ế ậ ị ữ ệ ư ộ ằ ộ ợ ướ ơ ở ữ ệ i c s d li u
ệ ị
mà ta đã xác đ nh thông qua các câu l n trong SQLiteDatabase. • Qu n lí và ki m soát các dòng d li u (row) trong t p k t qu truy v n c a c s d ấ ủ ơ ở ữ ữ ệ ể ế ả ậ ả
li u.ệ
1.3.2.3.2 Các ph ng th c: ươ ứ
• Boolean moveToFirst(): di chuy n con tr đ n dòng d li u đ u tiên, thành công tr v ỏ ế ữ ệ ả ề ể ầ
i là false c l ượ ạ
true, ng • Boolean moveToLast(): di chuy n con tr d li u đ n dòng cu i cùng, thành công tr ỏ ữ ệ ể ế ố ả
i là false. c l ượ ạ
v true, ng ề • Boolean moveToNext(): di chuy n con tr đ n dòng d li u k ti p, thành công tr v ữ ệ ế ế ỏ ế ể ả ề
i là false. c l ượ ạ
true, ng • Boolean moveToPrevious(): di chuy n con tr đ n dòng d li u tr c đó, thành công ữ ệ ỏ ế ể ướ
tr v true, ng i là false. ả ề c l ượ ạ
• Boolean moveToPosition(int position): di chuy n con tr d li u đ n dòng t i v trí ỏ ữ ệ ể ế ạ ị
position, thành công tr v true, ng i là false. ả ề c l ượ ạ
• Boolean isFirst(): ki m tra coi con tr t i v trí dòng đ u tiên. ể ỏ ạ ị ầ
i v trí dòng cu i cùng. t • Boolean isLast(): ki m tra coi con tr có đang ể ỏ ở ạ ị ố
• Boolean isNull(int columnIndex): Tr v true n u giá tr trong c t ch đ nh là null. ả ề ế ộ ị ỉ ị
• Int getCount(): tr v s dòng d li u c a câu truy v n query. ữ ệ ủ ả ề ố ấ
• Int getPosition(): tr v v trí hi n t i c a con tr cursor t i dòng nào. ả ề ị ệ ạ ủ ỏ ạ
• Int getType(int columnIndex): tr v ki u d li u t ả ề ể ữ ệ ạ ộ i c t có ch s columIndex. ỉ ố
getColumnName(int columnIndex): tr v tên c a c t t i v trí ch đ nh. • String ủ ộ ạ ị ả ề ị ỉ
• String[] getColumnNames(): tr v tên c a các c t. ả ề ủ ộ
• Int getColumnIndex(String columnName): tr v ch s c a c t có tên là columnName. ả ề ỉ ố ủ ộ
• Int getColumnCount(): tr v s c t có trong d li u này. ả ề ố ộ ữ ệ
Và còn nhi u ph ng th c khác, b n có th xem thêm trên ề ươ ứ ể ạ
http://developer.android.com/reference/android/database/Cursor.html
1.3.3 Ví d demo v qu n lí thông tin m t ng i. ụ ộ ề ả ườ
1.3.3.1 L p DTOPeople: ớ
Đ qu n lí vi c nh n d li u t GUI và chuy n d li u vào database đ c d dàng và ậ ữ ệ ừ ệ ể ả ể ữ ệ ượ ễ
thu n ti n, không gây khó ch u cho vi c vi t code chúng ta c n xây d ng m t l p g i là ệ ệ ậ ị ế ộ ớ ự ầ ọ
DTOPeople (T ch c theo mô hình 3 l p). L p này là m t l p tr u t ng hóa các thông tin ổ ứ ộ ớ ừ ượ ớ ớ
i c n đ a vào c s d li u. Sau đây là code: c a con ng ủ ườ ầ ư ơ ở ữ ệ
public class DTOPeople {
private int gID;
private String gName;
private String gPhone;
private String gEmail;
private String gAddress;
public int getgID() {
return gID;
}
public void setgID(int gID) {
this.gID = gID;
}
public String getgName() {
return gName;
}
public void setgName(String gName) {
this.gName = gName;
}
public String getgPhone() {
return gPhone;
}
public void setgPhone(String gPhone) {
this.gPhone = gPhone;
}
public String getgEmail() {
return gEmail;
}
public void setgEmail(String gEmail) {
this.gEmail = gEmail;
}
public String getgAddress() {
return gAddress;
}
public void setgAddress(String gAddress) {
this.gAddress = gAddress;
}
public DTOPeople()
{
gID = 0;
gName = "Nguyen Van Sinh";
gEmail = "Royalknight2902@gmail.com";
gPhone = "01264721476";
gAddress = "Ho Chi Minh";
}
public DTOPeople(int mID, String mName, String mEmail,
String mPhone, String mAddress)
{
gID = mID;
gName = mName;
gEmail = mEmail;
gPhone = mPhone;
gAddress = mAddress;
}
public String displayPeople()
{
String temp = "";
temp += String.valueOf(gID).toString().trim() + "\n";
temp += gName.toString().trim() + "\n";
temp += gEmail.toString().trim() + "\n";
temp +=gPhone.toString().trim() + "\n";
temp += gAddress.toString().trim();
return temp;
}
}
1.3.3.2 L p DAOPeople: ớ
ế L p này s hi n th c hóa và k th a l p SQLiteOpenHelper dùng đ t o và qu n lí k t ế ừ ớ ẽ ệ ể ạ ự ả ớ
n i t i database. ố ớ
ả Đ u tiên b n c n t o tên c a database, tên c a table có trong database, câu l nh t o b ng ủ ạ ầ ạ ủ ệ ầ ạ
//ten cua database
và đ i t ng SQLDatabase đ s d ng trong toàn b l p. Sau đây là Code ph n này: ố ượ ể ử ụ ộ ớ ầ
private static String database_name = "INFOPEOPLE";
//ten cua mot bang nam trong database
private static String table_name = "PEOPLE";
//cau truc tao ra bang table_name
private static String table_create = "CREATE TABLE [" + table_name +"]
(" +
"[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
"[Name] TEXT NOT NULL," +
"[Email] TEXT NULL," +
"[Phone] TEXT NULL," +
"[Address] TEXT NULL)";
//phien ban cua database
private static int database_version = 1;
//doituong SQLiteDatabase dung de thuc hien cac cau len SQL
private SQLiteDatabase gdb;
ể ạ
ề
ạ
ố
ớ
ố
ở
//hàm kh i t o dùng đ t o database v i đ i s truy n vào là Context.
Sau đó b n c n t o database, table và t o hàm update database: ạ ầ ạ ạ
public DAOPeople(Context context) {
super(context, database_name, null, database_version);
}
ả
ể ạ //hàm onCreate dùng đ t o b ng trong database
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(table_create);
}
//update phien ban cua database
@Override
public void onUpgrade(SQLiteDatabase db, int version_old, int
version_new) {
Log.w(DAOPeople.class.getName(),
"Upgrading database from version " + version_old + " to "
+ version_new + ", which will destroy all old data");
gdb.execSQL("DROP TABLE IF EXISTS " + table_name);
db.execSQL(table_create);
}
ộ ố Ti p theo b n s t o hàm thêm d li u vào database, l p này nh n thông tin qua m t đ i ạ ẽ ạ ữ ệ ế ậ ớ
gdb = this.getWritableDatabase();
ng DTOPeople. Chúng ta c n m database d i d ng đ c và ghi theo code sau: t ượ ầ ở ướ ạ ọ
ủ
ộ
ườ
//thêm thông tin c a m t ng
i vào database
.Sau đây là code:
public void addPeople(DTOPeople mPeople)
{
//mo database duoi dang doc va ghi
gdb = this.getWritableDatabase();
//cau lenh sql
String str = "INSERT INTO " + table_name +
"(Name,Email,Phone,Address) VALUES(";
str += "'" + mPeople.getgName().toString().trim() + "',";
str += "'" + mPeople.getgEmail().toString().trim() + "',";
str += "'" + mPeople.getgPhone().toString().trim() + "',";
str += "'" + mPeople.getgAddress().toString().trim() + "')";
//thuc hien cau lenh sql thong qua doi tuong SQLDatabase
gdb.execSQL(str);
gdb.close();
}
Ti p theo b n s t o hàm s a d li u trong database, l p này cũng nh n nh ng thông tin ử ữ ệ ạ ẽ ạ ữ ế ậ ớ
ử
ữ
ệ
//hàm s a d li u có trong database
ng DTOPeople. Sau đây là code: c n s a ch a qua m t đ i t ầ ử ộ ố ượ ữ
public void updatePeople(DTOPeople mPeople)
{
//mo database duoi dang doc va ghi
gdb = this.getWritableDatabase();
//cau lenh sql
String str = "UPDATE " + table_name + " SET ";
str += "Name = '" + mPeople.getgName().toString().trim() + "',";
str += "Email = '" + mPeople.getgEmail().toString().trim() +
"',";
str += "Phone = '" + mPeople.getgPhone().toString().trim() +
"',";
str += "Address = '" + mPeople.getgAddress().toString().trim() +
"' ";
str += "WHERE ID = " + mPeople.getgID();
//thuc hien cau lenh sql thong qua doi tuong SQLDatabase
gdb.execSQL(str);
gdb.close();
}
Sau đó b n s t o hàm delete d li u có trong database d i d ng id. B n cũng có th xây ạ ẽ ạ ữ ệ ướ ạ ể ạ
i d ng tên hay theo s đi n tho i tùy vào mong mu n s d ng hàm delete hay update d ự ướ ạ ố ệ ố ử ạ
ệ d ng c a b n và b n ch c n thay đ i tham s truy n vào cũng nh c u trúc c a câu l nh ố ụ ủ ạ ư ấ ỉ ầ ủ ề ạ ổ
//ham xoa mot dong trong bang voi id duoc dua vao
sql. Sau đây là code:
public void deletePeople(int id)
{
//mo database duoi dang doc va ghi
gdb = this.getWritableDatabase();
//cau lenh sql
String str = "DELETE FROM " + table_name + " WHERE ID = " + id;
//thuc hien cau lenh sql thong qua doi tuong SQLDatabase
gdb.execSQL(str);
gdb.close();
}
Sau đây là các hàm l y thông tin t ấ ừ ơ ở ữ ệ ấ c s d li u đ đ a ra bên ngoài. Đ u tiên là hàm l y ể ư ầ
//lay thong tin cua mot nguoi voi id duoc nhap vao
//return ve duoi dang doi tuong DTOPeople
m t dòng d li u v i tham s truy n vào là id c a d li u, đ i t ng tr ra là DTOPeople: ủ ữ ệ ữ ệ ố ượ ề ộ ớ ố ả
public DTOPeople getPeople(int id)
{
//mo database duoi dang doc
gdb = this.getReadableDatabase();
//tao mot doi tuong DTOPeople de luu thong tin cua nguoi nay
//sau do return gia tri
DTOPeople mPeople = new DTOPeople();
//cau lenh sql
String str = "SELECT * FROM " + table_name + " WHERE ID = " + id;
//tra ve con tro Cursor tro den du lieu ma chung ta da lay ra
thong qua cau len sql
Cursor cur = gdb.rawQuery(str, null);
//kiem tra con tro cursor co du lieu hay khong
//neu khong co thi return ve null
if(cur.moveToFirst() == false)
{
cur.close();
gdb.close();
return null;
}
//co du lieu trong con tro cursor thi
//lay du lieu trong dua vao trong doi tuong DTOPeople de dua ra
ngoai
else
{
//vi tri cua cac cot trong du lieu giong nhu khi ta tao bang
//ID la kieu int nen chung ta getInt
mPeople.setgID(cur.getInt(0));
//tuong tu, cac truong con lai la String nen chung ta
getString
mPeople.setgName(cur.getString(1).toString().trim());
mPeople.setgEmail(cur.getString(2).toString().trim());
mPeople.setgPhone(cur.getString(3).toString().trim());
mPeople.setgAddress(cur.getString(4).toString().trim());
cur.close();
gdb.close();
return mPeople;
}
}
//ham lay tat ca du lieu trong table_name
Ti p theo là hàm l y toàn b d li u có trong b ng. Sau đây là code: ộ ữ ệ ế ấ ả
public DTOPeople[] getAllPeople()
{
//mo database duoi dang doc
gdb = this.getReadableDatabase();
//cau lenh sql dem so dong du lieu co trong table_name
String sql = "SELECT COUNT(*) FROM " + table_name;
//cau lenh sql lay toan bo du lieu trong table_name
String str = "SELECT * FROM " + table_name;
//thuc hien cau lenh dem so dong du lieu co trong table_name
Cursor cur = gdb.rawQuery(sql, null);
//kiem tra con tro cursor co du lieu hay khong
if(cur.moveToFirst())
{
//lay so dong du lieu co trong table,
//doi tuong nay dung de duyet sau nay, giup chung ta lay
toan bo du lieu
int len = cur.getInt(0);
//neu so dong du leu nho hon hoac bang 0 thi return ve null
if(len <= 0)
{
cur.close();
gdb.close();
return null;
}
//neu so dong du lieu lon hon 0 (ton tai du lieu) thi thuc
hien viec lay du lieu
else
{
//thuc hien cau lenh lay toan bo du lieu co trong table_name
cur = gdb.rawQuery(str, null);
//neu con tro cursor khong co du lieu (loi) thi tra ve null
if(cur.moveToFirst() == false)
{
cur.close();
gdb.close();
return null;
}
else
{
int count = 0;
//tao mot mang doi tuong DTOPeople de lay du
lieu
DTOPeople[] listPeople = new DTOPeople[len];
do
{
listPeople[count] = new DTOPeople();
listPeople[count].setgID(cur.getInt(0));
listPeople[count].setgName(cur.getString(1).toString().trim());
listPeople[count].setgEmail(cur.getString(2).toString().trim());
listPeople[count].setgPhone(cur.getString(3).toString().trim());
listPeople[count].setgAddress(cur.getString(4).toString().trim());
count++;
} while (cur.moveToNext());
cur.close();
gdb.close();
return listPeople;
}
}
}
else
{
cur.close();
gdb.close();
return null;
}
}
1.3.3.3 L p MainActivity: ớ
L p này là l p giao ti p gi a vi c đ a d li u vào l p DAOPeople và giao di n ng ệ ư ữ ệ ữ ệ ế ớ ớ ớ ườ i
dùng.
Đ u tiên, chúng ta c n t o các đ i t ng đ h tr cho l p này th c hi n các thao tác. ầ ạ ố ượ ầ ể ỗ ợ ự ệ ớ
private DAOPeople daoPeople;
private DTOPeople dtoPeople;
//cac Button de xu li xu kien
private Button btSave;
private Button btUpdate;
private Button btDelete;
private Button btShow;
private Button btDisplay;
//cac EditText de nhan du lieu tu nguoi dung nhap
private EditText edtID;
private EditText edtName;
private EditText edtEmail;
private EditText edtPhone;
private EditText edtAddress;
private ListView lvShow;
ng DAOPeople. Sau đó là t o các hàm c b n đ thao tác v i đ i t ơ ả ớ ố ượ ể ạ
//them mot du lieu vao co so du lieu
Hàm l y d li u t giao di n và thêm vào c s d li u: ấ ữ ệ ừ ơ ở ữ ệ ệ
private void onSave()
{
//lay du lieu tu man hinh GUI va dua vao doi tuongDTOPeople
dtoPeople.setgName(edtName.getEditableText().toString().trim());
dtoPeople.setgEmail(edtEmail.getEditableText().toString().trim());
dtoPeople.setgPhone(edtPhone.getEditableText().toString().trim());
dtoPeople.setgAddress(edtAddress.getEditableText().toString().trim());
daoPeople.addPeople(dtoPeople);
}
//sua du lieu trong co so du lieu
Hàm s a d li u trong database: ử ữ ệ
private void onUpdate()
{
//lay du lieu tu man hinh GUI va dua vao doi tuongDTOPeople
dtoPeople.setgID(Integer.parseInt(edtID.getEditableText().toString().trim()))
;
dtoPeople.setgName(edtName.getEditableText().toString().trim());
dtoPeople.setgEmail(edtEmail.getEditableText().toString().trim());
dtoPeople.setgPhone(edtPhone.getEditableText().toString().trim());
dtoPeople.setgAddress(edtAddress.getEditableText().toString().trim());
daoPeople.updatePeople(dtoPeople);
}
//xoa du lieu trong co so du lieu
Hàm xóa d li u: ữ ệ
private void onDelete()
{
if(edtID.getEditableText().toString().trim() != null)
{
//neu co nhap id thi lay id tu man hinh giao dien ma nguoi
dung nhap
int id =
Integer.parseInt(edtID.getEditableText().toString().trim());
daoPeople.deletePeople(id);
}
else
{
//neu nguoi dung khong nhap id thi mac dinh xoa ban ghi dau
tien
int id = daoPeople.getAllPeople()[0].getgID();
daoPeople.deletePeople(id);
}
}
//hien thi thong tin du lieu voi mot id duoc nhap vao
Hàm hi n th d li u v i id đ c nh p vào lên trên giao di n cho ng i dùng bi t: ị ữ ệ ệ ớ ượ ệ ậ ườ ế
private void onShow()
{
if(edtID.getText() != null)
{
//lay id tu nguoi dung nhap
int id =
Integer.parseInt(edtID.getEditableText().toString().trim());
//lay doi tuong DTOPeople thong qua id
dtoPeople = daoPeople.getPeople(id);
//xuat tat ca cac truong len giao dien cho nguoi dung nhin
thay
edtID.setText(String.valueOf(dtoPeople.getgID()));
edtName.setText(dtoPeople.getgName().toString().trim());
edtEmail.setText(dtoPeople.getgEmail().toString().trim());
edtPhone.setText(dtoPeople.getgPhone().toString().trim());
edtAddress.setText(dtoPeople.getgAddress().toString().trim());
}
else
{
//neu nguoi dung ko nhap id thi lay ban ghi dau tien
int id = daoPeople.getAllPeople()[0].getgID();
dtoPeople = daoPeople.getPeople(id);
edtID.setText(String.valueOf(dtoPeople.getgID()));
edtName.setText(dtoPeople.getgName().toString().trim());
edtEmail.setText(dtoPeople.getgEmail().toString().trim());
edtPhone.setText(dtoPeople.getgPhone().toString().trim());
edtAddress.setText(dtoPeople.getgAddress().toString().trim());
}
}
//hien thi toan bo thong tin du lieu len ListView
Hi n th toàn b thông tin d li u lên ListView ữ ệ ể ộ ị
private void onDisplay()
{
DTOPeople[] listPeople = daoPeople.getAllPeople();
int len = listPeople.length;
String[] values = new String[len];
for(int i = 0; i < len; i++)
{
values[i] = listPeople[i].displayPeople().toString().trim();
}
ArrayAdapter
android.R.layout.simple_list_item_1, values);
//show du lieu len ListView
lvShow.setAdapter(adapter);
}
Demo và source code c a ch ng trình này n m DemoSeminar/Seminar_SQLite ủ ươ ằ ở
2 Tìm hi u và s d ng Content Provider:
ử ụ
ề
2.1 Tim hiêu vê Content Provider:
̀ ̀ ̀
• Content Provider la môt thanh phân c ban cua Android SDK. ̀ ơ ̉ ̀ ̣ ̀ ̉
• Content Provider la môt chuân giup ban chia se d liêu gi a cac ng dung trên ̉ ữ ́ ứ ữ ̀ ̣ ̉ ́ ̣ ̣ ̣
Android:
La cach th c tiêu chuân đê chia se d liêu gi a cac ng dung khac nhau.. ̉ ữ ́ ứ ữ ứ ̀ ́ ̉ ̉ ̣ ̣ ́ o
Không phai la cach th c đê l u tr d liêu trên Android. ̉ ư ữ ữ ứ ̉ ̀ ́ ̣ o
• Call long, Contact List hoăc SMS co thê truy xuât băng Content Provider. ̣ ́ ̉ ́ ̀
• Content Provider đong goi d liêu va cung câp d liêu cho cac ng dung thông ́ ữ ́ ữ ́ ứ ́ ̣ ̀ ̣ ̣
qua giao diên ContentResolver duy nhât. ̣ ́
• ́ Khi th c hiên yêu câu thông qua ContentResolver thi hê thông cân kiêm tra cac ự ̣ ̀ ̀ ̣ ̀ ̉
chi đinh tai nguyên URI (Uniform Resource Identifier) ma nha cung câp đa đăng ki v i hê ́ ớ ̣ ̉ ̣ ̀ ̀ ̀ ́ ̃
điêu hanh. Chi đinh URI se đ c giai thich phân sau va l p UriMatcher rât co ich cho ̃ ượ ́ ở ̀ ớ ̀ ̀ ̉ ̣ ̉ ̀ ́ ́ ́
viêc phân tich chuôi URI. ̣ ́ ̃
• Đôi t ng tra vê cua Content Provider la đôi t ́ ượ ́ ượ ̉ ng Cursor tro đên d liêu cua ́ ữ ̉ ̀ ̉ ̀ ̉ ̣
ng dung. ứ ̣
• ả ề ữ ệ M i content provider, đ u s d ng chung 1 interface đ tìm và tr v d li u, ề ử ụ ể ọ
bao g m vi c thêm, b t và s a d li u. Vi c này đ ử ữ ệ ệ ệ ồ ớ ượ ố c th c hi n thông qua các đ i ự ệ
t ượ ng ContentResolver khi g i getContentResolver(): ọ
ContentResolver cr = getContentResolver();
• Đê lây đôi t ́ ượ ng Cursor tro đên d liêu cua ng dung chia se b i Content ̉ ứ ́ ữ ̉ ở ̉ ́ ̉ ̣ ̣
Provider ta s ham sau: ử ̀
getContentResolver().query(Uri uri)
2.2 Tim hiêu vê URI:
̀ ̉ ̀
• URI la đ ng dân đên d liêu ma Content Provider chia se. ̀ ườ ́ ữ ̃ ̣ ̀ ̉
• Nôi dung môt chuôi URI chuân: ̣ ̣ ́ ̉
m c đ nh c a 1 chuôi URI chi ra d liêu đ c điêu khiên b i Content ề ố ặ ị ̣ ượ ủ ữ ở ̃ ̉ ̀ ̉ o A – Ti n t
Provider va no không thê thay đ i đ c. ổ ượ ̀ ́ ̉
ữ ơ ở ữ ơ ư ư ́ ̉ ́ ̣ ́ ́ ̉ ̣ ́ ̣ ̣ ̀ ́ o Chi đên n i l u tr c s d liêu. Giông nh câu truc cua môt sô điên thoai thi cai
nay giông ma quôc gia hoăc giông nh tên cua môt c s d liêu. ̣ ơ ở ữ ư ̀ ́ ̃ ́ ̣ ́ ̉ ̣
ư ữ ̣ ữ ̉ ̀ ̀ ̉ ̣ ̉ ̣ ̣ ̀ ̀ ́ o Phân nay chi ra loai d liêu. Chăng han nh d liêu contact, sms, ... Phân nay co thê
coi nh tên cua môt table do ban đinh nghia khi xây d ng Content Provider. ư ự ̉ ̣ ̣ ̣ ̃
̉ ữ ư ữ ̀ ̀ ̉ ́ ́ ̣ ́ ̣ ̀ ̀ ́ ̉ ̀ ̣ o Phân nay chi đên đung vi tri cua d liêu. Phân nay giông nh id cua dong d liêu
trong table hoăc môt dong d liêu khi xuât ra câu truy vân. ữ ̣ ̣ ̀ ̣ ́ ́
• Vi du: ́ ̣
content://contacts/people/0
2.3 S dung môt Content Provider co săn:
ử
̣ ̣ ́ ̃
2.3.1 Gi ớ • i thi u: ệ Android cung câp môt tâp h p cac Content Provider co săn trong tât ca cac ng ́ ứ ợ ́ ̣ ̣ ́ ́ ̃ ́ ̉
dung đa đ c xây d ng măc đinh. Tâp h p nh ng Content Provider nay đ c năm săn ̃ ượ ̀ ượ ự ữ ợ ̣ ̣ ̣ ̣ ̀ ̃
trong android.provider.
• S dung đinh danh tai nguyên URI đê truy xuât đên tai nguyên cua c s d liêu ̉ ơ ở ữ ử ̣ ̣ ̀ ̉ ́ ́ ̀ ̣
đ c chia se ượ ̉
• Đôi t ng tra vê la con tro dang Cursor. ́ ượ ̉ ̀ ̀ ̉ ̣
• Đê s dung Content Provider co săn ban phai s dung uses-permission trong ̉ ử ̉ ử ̣ ́ ̃ ̣ ̣
AndroidMainfast.xml.
2.3.2 Ví d Demo: ụ ề ệ ử ụ ỏ ẵ ạ ệ t b đang ch y ng d ng này. Mu n s d ng đ ề ế ộ ứ ể ấ ạ c Content ố ệ ẽ ẽ ử ụ ạ ủ ộ ủ ạ ứ ố ử ụ ế ị ượ
Contacts
; ể ỏ ế
t m t ng d ng Sau đây mình s demo v vi c s d ng m t Content Provider có s n đ vi ụ nh . Mình s s d ng Content Provider c a Contact List (danh b đi n tho i) đ l y ra tên và s đi n tho i c a thi ụ Provider c a Contact List b n c n import thông tin sau: ủ ữ ệ ủ ể ứ ụ ộ
. Phones Trong ng d ng này, b n c n l y m t Cursor đ tr đ n vùng d li u c a Contact List đ l y các thông tin mà chúng ta c n thông qua cách sau: ấ
//tra ve 1 cursor tro den tat ca cac ban ghi trong danh ba dien
thoai
ườ
ủ
ệ
ạ
ng d n c a danh b đi n thoai
ượ
ố
ở
ạ ầ import android.provider. ạ ầ ấ ầ
ẫ //thông qua Phones_URI là đ Cursor cur = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null); ộ //kh i đ ng đ i t startManagingCursor
Ta l y các thông tin v tên, s đi n tho i c a m t b n ghi b ng cách sau:
ng cursor này ; (cur) ạ ủ
ệ
ạ
ạ
ộ
i trong 1 b ng ghi danh b đi n tho i
ườ
ệ
ả
ạ
ạ
ủ
ộ
i trong 1 b ng ghi danh b đi n tho i
ằ ấ ộ ả ả ố ệ ườ
Và còn nhi u thông s khác mà b n có th l y, tùy m c đích c a b n. ề ủ //tên c a m t ng . NAME Phones ạ ệ ố //s đi n tho i c a m t ng . NUMBER Phones ố ề ủ ạ ể ấ ụ ạ public class MainActivity extends ListActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//tra ve 1 cursor tro den tat ca cac ban ghi trong danh ba dien
thoai
(cur)
;
ượ
ừ
ệ
ấ
ố
ố
Cursor cur = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null); //khoi dong doi tuong cursor nay startManagingCursor //tao các đ i t
ữ ng ListAdapter t các d li u mà mình mu n l y
( this
,
simple_list_item_2
Phones
, Phones
, cur, . NUMBER }, , android.R.id.
. NAME
text1
text2
}) ;
ListAdapter adapter = new SimpleCursorAdapter android.R.layout. new String[] { new int [] { android.R.id. setListAdapter(adapter);
}
B n c n thay đ i m t s thông tin trong AndroidMainfest.xml, b n c n khai báo s d ng
ử ụ
ộ ố
ạ ầ
đ c danh b đi n tho i:
ạ
ọ
ạ ầ ổ ạ ệ
DemoSeminar/Seminar_ContactList. ng trình này n m ằ ở ươ ủ
2.4 Xây d ng va s dung môt Content Provider:
̀ ử
ự
̣ ̣
ụ ị ự 2.4.1 M c đ ch vi c xây d ng Content Provider: ả ế ạ ấ ộ ố ệ B n c n ph i xây d ng m t Content Provider n u b n mu n cung c p m t ộ ạ ầ ề ặ ụ ng d ng c a b n vào ng d ng ủ ạ ừ ứ ụ ứ ặ ậ ố • ự ho c nhi u các tính năng sau: o B n mu n cung c p d li u ho c các t p tin t ấ ữ ệ
i dùng sao chép d li u t ườ ữ ệ ừ ứ ứ ng d ng c a b n vào các ng ủ ạ ụ o B n mu n cho phép ng ố ạ khác. ạ d ng khác. ụ
2.4.2 Xây d ng Content Provider: • ự ̀ Đê xây d ng môt Content Provider cho ng dung cua minh ban cân hiên th c va ứ ự ự ̉ ̣ ̣ ̉ ̀ ̣ ̀ ̣
kê th a t môt l p co săn la contentProvider trong Android. ́ ừ ừ ̣ ớ ́ ̃ ̀
• Override t t c các ph ấ ả ươ ng th c sau: ứ
onCreate() : kh i t o m t ng d ng đ ở ạ ộ ứ ụ ượ ạ ọ c b n cung c p. H th ng Android g i ệ ố ấ o
ph ng th c này ngay sau khi nó t o ra ng d ng đ ươ ứ ứ ụ ạ ượ ạ c b n cung c p. Chú ý r ng, ấ ằ
c b n cung c p s không đ c t o ra cho đ n khi có m t đ i t ứ ng d ng đ ụ ượ ạ ấ ẽ ượ ạ ộ ố ượ ng ế
ContentResolver đ c truy c p. ượ ậ
getType()
: tr v đ nh d ng MIME t
ng ng v i n i dung c a m t URI. ả ề ị ạ ươ ứ ớ ộ ủ ộ o
Ph ng th c này s đ sau. ươ ẽ ượ ứ c nói rõ h n trong ph n th c thi c a Content Provider ự ủ ầ ơ ở
insert()
: chèn m t dòng d li u m i vào
c b n cung c p ữ ệ ộ ớ ứ ng d ng đ ụ ượ ạ ấ . Trả o
v m t đ nh d ng URI cho dòng m i thêm vào. ề ộ ị ạ ớ
update()
: c p nh t dòng d li u hi n đang có trong ữ ệ
c b n cung ệ ậ ậ ứ ng d ng đ ụ ượ ạ o
c c p nh t. c p. Tr v s dòng đ ả ề ố ấ ượ ậ ậ
delete()
: xóa dòng d li u trong Provider c a b n. Tr v s dòng đ
c xóa. ả ề ố ủ ạ ữ ệ ượ o
query()
: l y d li u t
Provider c a b n. Tr v d li u d i d ng m t con ấ ữ ệ ừ ả ề ữ ệ ướ ạ ủ ạ ộ o
tr Cursor. ỏ
• Gi i thi u v l p UriMatcher: ớ ề ớ ệ
L p ti n ích đ h tr trong vi c k t h p các URI trong Content Provider. ệ ế ợ ể ỗ ợ ệ ớ o
Đ giúp b n l a ch n các cách th c x lí t ọ ứ ử ạ ự ể ố ố ớ t đ i v i m t m u URI, API cung ẫ ộ o
c p m t s d ch v thu n ti n t ấ ộ ố ị ệ ạ ớ i l p UriMatcher, v i m t cây URI m u d ớ ẫ ướ ạ i d ng ụ ậ ộ
ạ các s nguyên. B n có th s d ng các s nguyên này trong m t câu l nh mà b n ố ể ử ụ ệ ạ ộ ố
mu n x lí v i hành đ ng là chu i URI đ c đ nh danh. ố ử ớ ỗ ộ ượ ị
Đ s d ng l p này, xây d ng m t cây c a các đ i t ự ể ử ụ ố ượ ủ ộ ớ ư ng UriMatcher, nh ví o
private static final int PEOPLE = 1; private static final int PEOPLE_ID = 2; private static final int PEOPLE_PHONES = 3; private static final int PEOPLE_PHONES_ID = 4; private static final int PEOPLE_CONTACTMETHODS = 7; private static final int PEOPLE_CONTACTMETHODS_ID = 8;
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static { sURIMatcher.addURI("contacts", "people", PEOPLE); sURIMatcher.addURI("contacts", "people/#", PEOPLE_ID); sURIMatcher.addURI("contacts", "people/#/phones", _PHONES); sURIMatcher.addURI("contacts", "people/#/phones/#", PEOPLE_PHONES_ID); sURIMatcher.addURI("contacts", "people/#/contact_methods", PEOPLE_CONTACTMETHODS); sURIMatcher.addURI("contacts", "people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID); }
d sau: ụ
• M t mô hình n i dung URI (UriMatcher) kh p v i n i dung URI s d ng đ ớ ộ ử ụ ớ ộ ộ ể
đăng kí ph i s d ng các kí t ả ử ụ ự ạ đ i di n sau: ệ
*: đ i di n cho m t chu i kí t v i đ dài b t kì. h p l ệ ạ ộ ỗ ự ợ ệ ớ ộ ấ o
#: đ i di n cho m t chu i kí t s v i đ dài b t kì. ệ ạ ộ ỗ ự ố ớ ộ ấ o
Ví d :ụ
ệ ề ạ ỗ content://com.example.app.provider/*: đ i di n cho nhi u chu i URI
trong provider.
ệ ạ content://com.example.app.provider/table2/*: đ i di n cho các URI có
ch a trong table2 ứ
ệ ạ content://com.example.app.provider/table3/#: đ i di n cho các dòng
c a table3 ủ
UserInfo k th a l p
ụ ề t k m t ng d ng l y v i c s d li u ch là t o ra 1 mã ỉ ấ ụ ớ ơ ở ữ ệ Bây gi ờ đ ng và ng ư ự ộ ụ ố ằ ẽ ượ 2.4.3 Ví d v xây d ng m t Content Provider: ộ ự ta s thi ế ế ộ ứ ẽ ạ i dùng nh p tên vào trong EditText sau đó l u xu ng c s d li u ơ ở ữ ệ ậ ườ ự c chia s v i bên ngoài b ng cách xây d ng ẻ ớ ộ Đ u tiên, chúng ta t o m t l p g i là ộ ớ ạ ọ ế ừ ớ ContentProvider ư
Trong l p này ta t o m t s bi n nh tên c a Content Provider, đ ng d n URI ẫ ộ ố ế ườ ư ủ ạ ớ
dan nay de
• ID t SQLite. D li u c a ng d ng này s đ ữ ệ ủ ứ m t Content Provider. • ầ nh code sau: public class UserInfo extends ContentProvider { … } • c a Content Provider: ủ //ten cua Content Provider. public static final String PROVIDER_NAME = "myandroid.net.User"; //duong dan URI cua Content Provider, cac ung dung khac se dung duong
public static final Uri CONTENT_URI = Uri.parse("content://" +
PROVIDER_NAME + "/users");
Sau đó chúng ta s t o uriMatcher đ truy xu t Content Provider đ c d dàng: ể ấ ượ ễ ẽ ạ
• /cac chi so dung cho uriMatcher public static final int USERS = 1; public static final int USER_ID = 2;
//khoi tao uriMatcher. public static final UriMatcher uriMatcher; static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(PROVIDER_NAME, "users", USERS); uriMatcher.addURI(PROVIDER_NAME, "users/#", USER_ID);
Vì đây là m t ch ỏ ươ ỏ ộ ố ượ ng trình nh và mô ph ng nên chúng ta không tao ra l p ớ ơ ở ữ ng nên mình s t o ra 2 bi n đ l y và đ a giá tr và c s d ẽ ạ ể ấ ư ế ị
ế ầ
} • DTO đ th hi n đ i t ể ể ệ li u:ệ //hai bien de nhan gia tri id va name de dua vao co so du lieu public static final String sID = "ID"; public static final String sName = "Name"; • đ nh l ị
ẳ ph n SQLite. Đ n ph n này mình xin kh ng Sau đó chúng t o database nh ầ ư ở ạ ả ử i r ng Content Provider không ph i là cách l u tr d li u nên chúng ta ph i s ữ ữ ệ ả ạ ằ ư
ọ ể ườ ể ư ữ ữ ệ ữ ấ i có th dùng các cách khác đ l u tr , r t ể ư i:
"[Name] TEXT NOT NULL)";
d ng SQLite đ l u tr d li u. M i ng ụ ti n l ệ ợ //tao database private SQLiteDatabase gdb; private static final String DATABASE_NAME = "USERDEMO"; private static final String TABLE_NAME = "USER"; private static final int DATABASE_VERSION = 1; private static final String TABLE_CREATE = "CREATE TABLE [" + TABLE_NAME + "] (" +"[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
//su dung SQLtieOpenHelper de quan li viec luu du lieu private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME , null, DATABASE_VERSION);
}
@Override public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_CREATE);
}
@Override public void onUpgrade(SQLiteDatabase db, int version_old, int version_new) {
db.execSQL("DROP TABLE IF EXISTS titles"); onCreate(db);
}
ng th c có trong l p Content Provider mà ươ Sau đó chúng ta override các ph ng th c ầ ầ ớ ươ ở ng th c này chúng ta kh i ứ ứ ứ onCreate, trong ph i là false: ươ ế ạ ả ề c l ượ ạ
} • chúng ta c n. Đ u tiên là ph t o database và tr v true n u t o thành công, ng ạ @Override public boolean onCreate() {
//lay context hien tai bang ham getContext Context context = this.getContext(); //tao database DatabaseHelper dbHelper = new DatabaseHelper(context); //mo database de doc va ghi gdb = dbHelper.getWritableDatabase(); return (gdb == null) ? false :true;
} • là:
Trong ví d demo này mình ch override hàm insert, hàm này nh n hai tham s ụ ậ ỉ ố
Uri uri: đ ContentValues values: giá tr c n đ a vào c s d li u, đ i t
ng dân c a Content Provider ườ ủ ng này s ơ ở ữ ệ ị ầ ư ố ượ ẽ o o nh n các giá tr mà ng i dùng nh p vào ườ ậ ị
ậ @Override public Uri insert(Uri uri, ContentValues values) {
//chen du lieu vao table cua database long rowID = gdb.insert(TABLE_NAME, "", values);
//neu chen thanh cong thi thuc hien if(rowID > 0) {
//tao mot dinh dang cho dong du lieu ban moi vua them vao Uri mUri = ContentUris.withAppendedId(CONTENT_URI, rowID); //khoi dong bang ContentResolver de doi tuong mUri tao thanh
cong
getContext().getContentResolver().notifyChange(mUri, null); return mUri;
} throw new SQLException("Failed to insert new row into " + uri);
query(Uri uri, String[] projection, String
} • selection,String[] selectionArgs, String sortOrder) (). Hàm này:
Cu i cùng là hàm ố
@Override public Cursor query(Uri uri, String[] projection, String
selection,
String[] selectionArgs, String sortOrder) {
//doi tuong dung de luu cac gia tri cua cau lenh truy van, gia cu moi khong de len gia tri cu
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder(); //set doi tuong SQLiteQueryBuilder len bang can lay du lieu sqlBuilder.setTables(TABLE_NAME);
//su dung chuoi uriMatcher ma minh da tao, neu chuoi nay dan den vung du lieu cua table
//thi lay du lieu ra khoi table if(uriMatcher.match(uri) == USER_ID) sqlBuilder.appendWhere(sID + "=" + uri.getPathSegments().get(1)); //sap xep du lieu tang dan theo id if(sortOrder == null || sortOrder == "")
sortOrder = sID;
//tao cursor bang du lieu ma minh da lay ra Cursor cur = sqlBuilder.query(gdb, projection, selection,
selectionArgs, null, null, sortOrder);
//khoi dong ContentResolver de doi tuong uri duoc hoat dong va du lieu duoc du ra cur.setNotificationUri(getContext().getContentResolver(),
uri);
return cur;
} Ti p đó chúng ta c n vi
t m t s hàm trong l p MainActivity. ế ầ ế ộ ố ớ
• Hàm thêm d li u vào database b ng cách nh n d li u t ậ ữ ệ ừ ữ ệ ằ giao di n GUI: ệ
//them mot du lieu moi vao table private void onAdd() {
//lay ten do nguoi dung nhap vao EditText String name = edtName.getEditableText().toString(); //day gia tri ten vao ContentValues
ContentValues values = new ContentValues(); values.put(UserInfo.sName, name);
//dua gia tri ContentValues vao co so du lieu thong qua duong dan Uri uriInsert = getContentResolver().insert(UserInfo.CONTENT_URI,
//hien thong bao neu them du lieu thanh cong if(uriInsert != null) {
Toast.makeText(this, "User's added", Toast.LENGTH_SHORT).show();
}
values); }
• Hàm l y toàn b d li u trong c s d li u và hi n th lên giao di n: ơ ở ữ ệ ộ ữ ệ ệ ể ấ ị
//ham hien thi toan bo du lieu @SuppressWarnings("deprecation") private void onDisplay() {
StringBuilder sb = new StringBuilder();
Uri uri = UserInfo.CONTENT_URI; //khoi tao cursor voi duong dan uri va sap xep tang dan theo id Cursor c = managedQuery(uri, null, null, null, "ID desc"); if(c.moveToFirst()){
do{
String userRecord = "ID = " +
+ " Name = " +
sb.append(userRecord); sb.append("\n");
}while(c.moveToNext());
} else {
sb.append("Chua co du lieu");
}
((TextView)this.findViewById(R.id.txtDisplay)).setText(sb.toString());
c.getString(c.getColumnIndex(UserInfo.sID)) c.getString(c.getColumnIndex(UserInfo.sName)); }
< provider
android:name
= "UserInfo" android:authorities="myandroid.net.User" />
Chúng ta c n thêm m t s thông tin vào trong hàm AndroidMainfest.xml: ộ ố ầ
ư ụ trong th application. T t c source code và demo n m trong th m c ấ ả ẻ ằ
DemoSeminar/Seminar_CreateContentProvider
2.4.4 S d ng Content Provider m i t o: ử ụ ớ ạ chúng ta s s d ng Content ẽ ử ụ ờ ạ ạ ể ể Ứ ằ ị ng trên. ộ ch ạ ở ươ Chúng ta đã t o thành công m t content Provider. Bây gi ộ Provider đã t o b ng cách s d ng uri. ng dung này có m t button dùng đ hi n th toàn ử ụ b d li u có trong c s d li u c a ng d ng mà ta đã t o ụ ơ ở ư ệ ủ ứ ộ ữ ệ Code:
private void onDisplay() {
//dung de chua toan bo du lieu lay ra tu co so du lieu cua ung dung lien ket StringBuilder sb = new StringBuilder();
//chuoi uri cua content provider chia se du lieu Uri uriGetListTitles = Uri.parse("content://myandroid.net.User/users");
//cursor dung de tro den du lieu con co so du lieu thong qua doi tuong uri Cursor c = managedQuery
(uriGetListTitles,
null
, null
, null
, "ID
) ;
desc"
if(c != null) {
if(c.moveToFirst()){
do{
String bookRecord = "id = " + c.getString(c.getColumnIndex("ID")) +
" - Full Name= " +c.getString(c.getColumnIndex("Name")); sb.append(bookRecord); sb.append("\n"); }while(c.moveToNext());
}
} else {
sb.append("Khong co du lieu");
}
((TextView)this.findViewById(R.id.txtDisplay)).setText(sb.toString()); } ấ ả
T t c source code và demo n m trong th m c DemoSeminar/Seminar_UseContentProvide ư ụ ằ