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//databases đ chia s c s d li u qua các ng d ng ta dùng ẻ ơ ở ữ ệ ứ ụ ể

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//database • L u tr t ư ữ ạ

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 adapter = new ArrayAdapter(this,

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: ạ ọ Source code và demo c a ch

ạ ầ ổ ạ ệ

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 ư ụ ằ