Android提供以下四種存儲方式:
SharePreference
SQLite
File
ContentProvider
如果要實現數據共享,正確的方式是使用ContentProvider
SharedPreference
代碼速記:
存儲數據
- SharedPreferencessp=context.getSharedPreferences("CITY",MODE_PRIVATE);//獲取對象
- Editoreditor=sp.edit();
- editor.putString("CityName",City.getCity().getCityName());//存儲數據
- editor.commit();//將數據提交
讀取數據
//定義一個讀取SP文件的方法
- publicMapread(){
- Mapdata=newHashMap();
- SharedPreferencessp=mContext.getSharedPreferences("mysp",Context.MODE_PRIVATE);
- data.put("username",sp.getString("username",""));//獲取數據;
- data.put("passwd",sp.getString("passwd",""));
- returndata;
- }
SharedPreference工具類:
SPUtils.java
- packagecom.jay.sharedpreferencedemo3;
-
- importandroid.content.Context;
- importandroid.content.SharedPreferences;
-
- importjava.util.Map;
-
- /**
- *CreatedbyJayon2015/9/20002.
- */
- publicclassSPUtils{
- /**
- *保存在手機裡的SP文件名
- */
- publicstaticfinalStringFILE_NAME="my_sp";
-
- /**
- *保存數據
- */
- publicstaticvoidput(Contextcontext,Stringkey,Objectobj){
- SharedPreferencessp=context.getSharedPreferences(FILE_NAME,context.MODE_PRIVATE);
- SharedPreferences.Editoreditor=sp.edit();
- if(objinstanceofBoolean){
- editor.putBoolean(key,(Boolean)obj);
- }elseif(objinstanceofFloat){
- editor.putFloat(key,(Float)obj);
- }elseif(objinstanceofInteger){
- editor.putInt(key,(Integer)obj);
- }elseif(objinstanceofLong){
- editor.putLong(key,(Long)obj);
- }else{
- editor.putString(key,(String)obj);
- }
- editor.commit();
- }
-
-
- /**
- *獲取指定數據
- */
- publicstaticObjectget(Contextcontext,Stringkey,ObjectdefaultObj){
- SharedPreferencessp=context.getSharedPreferences(FILE_NAME,context.MODE_PRIVATE);
- if(defaultObjinstanceofBoolean){
- returnsp.getBoolean(key,(Boolean)defaultObj);
- }elseif(defaultObjinstanceofFloat){
- returnsp.getFloat(key,(Float)defaultObj);
- }elseif(defaultObjinstanceofInteger){
- returnsp.getInt(key,(Integer)defaultObj);
- }elseif(defaultObjinstanceofLong){
- returnsp.getLong(key,(Long)defaultObj);
- }elseif(defaultObjinstanceofString){
- returnsp.getString(key,(String)defaultObj);
- }
- returnnull;
- }
-
- /**
- *刪除指定數據
- */
- publicstaticvoidremove(Contextcontext,Stringkey){
- SharedPreferencessp=context.getSharedPreferences(FILE_NAME,context.MODE_PRIVATE);
- SharedPreferences.Editoreditor=sp.edit();
- editor.remove(key);
- editor.commit();
- }
-
-
- /**
- *返回所有鍵值對
- */
- publicstaticMapgetAll(Contextcontext){
- SharedPreferencessp=context.getSharedPreferences(FILE_NAME,context.MODE_PRIVATE);
- Mapmap=sp.getAll();
- returnmap;
- }
-
- /**
- *刪除所有數據
- */
- publicstaticvoidclear(Contextcontext){
- SharedPreferencessp=context.getSharedPreferences(FILE_NAME,context.MODE_PRIVATE);
- SharedPreferences.Editoreditor=sp.edit();
- editor.clear();
- editor.commit();
- }
-
- /**
- *檢查key對應的數據是否存在
- */
- publicstaticbooleancontains(Contextcontext,Stringkey){
- SharedPreferencessp=context.getSharedPreferences(FILE_NAME,context.MODE_PRIVATE);
- returnsp.contains(key);
- }
-
- }
SQLite
- publicclassMyDBOpenHelperextendsSQLiteOpenHelper{
- publicMyDBOpenHelper(Contextcontext,Stringname,CursorFactoryfactory,
- intversion){super(context,"my.db",null,1);}
- @Override
- //數據庫第一次創建時被調用
- publicvoidonCreate(SQLiteDatabasedb){
- db.execSQL("CREATETABLEperson(personidINTEGERPRIMARYKEYAUTOINCREMENT,nameVARCHAR(20))");
-
- }
- //軟件版本號發生改變時調用
- @Override
- publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
- db.execSQL("ALTERTABLEpersonADDphoneVARCHAR(12)NULL");
- }
- }
(2).插入數據:
dbOpenHelper.getWritableDatabase()
- publicvoidsave(Personp)
- {
- SQLiteDatabasedb=dbOpenHelper.getWritableDatabase();
- db.execSQL("INSERTINTOperson(name,phone)values(?,?)",newString[]{p.getName(),p.getPhone()});
- }
3.刪除數據:同上
db.execSQL("DELETEFROM person WHEREpersonid = ?",new String[]{id});
4.修改數據:同上
db.execSQL("UPDATEperson SET name =?,phone = ? WHERE personid = ?",newString[]{p.getName(),p.getPhone(),p.getId()});
5.查詢數據:
dbOpenHelper.getReadableDatabase()
- publicPersonfind(Integerid)
- {
- SQLiteDatabasedb=dbOpenHelper.getReadableDatabase();
- Cursorcursor=db.rawQuery("SELECT*FROMpersonWHEREpersonid=?",newString[]{id.toString()});
- //存在數據才返回true
- if(cursor.moveToFirst())
- {
- intpersonid=cursor.getInt(cursor.getColumnIndex("personid"));
- Stringname=cursor.getString(cursor.getColumnIndex("name"));
- Stringphone=cursor.getString(cursor.getColumnIndex("phone"));
- returnnewPerson(personid,name,phone);
- }
- cursor.close();
- returnnull;
- }
6.數據分頁:
dbOpenHelper.getReadableDatabase()
- publicListgetScrollData(intoffset,intmaxResult)
- {
- Listperson=newArrayList();
- SQLiteDatabasedb=dbOpenHelper.getReadableDatabase();
- Cursorcursor=db.rawQuery("SELECT*FROMpersonORDERBYpersonidASCLIMIT=?,?",
- newString[]{String.valueOf(offset),String.valueOf(maxResult)});
- while(cursor.moveToNext())
- {
- intpersonid=cursor.getInt(cursor.getColumnIndex("personid"));
- Stringname=cursor.getString(cursor.getColumnIndex("name"));
- Stringphone=cursor.getString(cursor.getColumnIndex("phone"));
- person.add(newPerson(personid,name,phone));
- }
- cursor.close();
- returnperson;
- }
7.查詢記錄數:
dbOpenHelper.getReadableDatabase()
- publiclonggetCount()
- {
- SQLiteDatabasedb=dbOpenHelper.getReadableDatabase();
- Cursorcursor=db.rawQuery("SELECTCOUNT(*)FROMperson",null);
- cursor.moveToFirst();
- longresult=cursor.getLong(0);
- cursor.close();
- returnresult;
- }
PS:除了上面獲取條數的方法外還可以使用cursor.getCount()方法獲得數據的條數, 但是SQL語句要改改!比如SELECT * FROMperson;
File
文件存儲讀寫
openFileOutput(filename,mode) 往文件寫數據
openFileIntput(filename) 讀取文件中的信息到程序
getDir(name,mode) 在app的data目錄下獲取或創建name對應的子目錄
getFileDir() 獲取app的data目錄的file目錄的絕對路徑
String[]fileList() 返回app的data目錄下的全部文件
deleteFile(filename) 刪除app的data目錄下的指定文件
ContentProvider
ContentProvider相對於其它的方式比較復雜。它能夠實現跨應用之間的數據操作。利用ContentResolver對象的delete、update、insert、query等方法去操ContentProvider的對象,讓ContentProvider對象的方法去對數據操作。實現方式為:
在A程序中定義一個ContentProvider,重載其增刪查改等方法;
- 在A程序中的AndroidManifest.xml中注冊ContentProvider;
- 在B程序中通過ContentResolver和Uri來獲取ContentProvider的數據,同樣利用Resolver的增刪查改方法來獲得和處理數據。
在A程序定義一個Provider
新建一個類,繼承ContentProvider,並重載其delete()、insert()、query()、update()、getType()、onCreate()方法。譬如下面的例子,重載其onCreate和query方法
注:從5.0開始,默認短信應用外的軟件不能以寫入短信數據庫的形式發短信!
- publicclassMyProviderextendsContentProvider{
-
- @Override
- publicintdelete(Uriuri,Stringselection,String[]selectionArgs){
- //TODOAuto-generatedmethodstub
- return0;
- }
-
- @Override
- publicStringgetType(Uriuri){
- //TODOAuto-generatedmethodstub
- returnnull;
- }
-
- @Override
- publicUriinsert(Uriuri,ContentValuesvalues){
- //TODOAuto-generatedmethodstub
- returnnull;
- }
-
- @Override
- publicbooleanonCreate(){
- //新建個數據庫並插入一條數據
- SQLiteDatabasedb=this.getContext().openOrCreateDatabase("test_db2.db",Context.MODE_PRIVATE,null);
- db.execSQL("CREATETABLEt_user(idINTEGERPRIMARYKEYAUTOINCREMENT,nameTEXTNOTNULL)");
- ContentValuesvalues=newContentValues();
- values.put("name","liangjh2");
- db.insert("t_user","id",values);
- db.close();
- returnfalse;
- }
-
- @Override
- publicCursorquery(Uriuri,String[]projection,Stringselection,
- String[]selectionArgs,StringsortOrder){
- //獲取數據
- SQLiteDatabasedb=this.getContext().openOrCreateDatabase("test_db2.db",Context.MODE_PRIVATE,null);
- Cursorc=db.query("t_user",null,null,null,null,null,null);
- db.close();
- returnc;
- }
-
- @Override
- publicintupdate(Uriuri,ContentValuesvalues,Stringselection,
- String[]selectionArgs){
- //TODOAuto-generatedmethodstub
- return0;
- }
-
- }
注冊ContentProvider
在AndroidManifest.xml中聲明ContentProvider,authorities屬性定義了ContentProvider的Uri標識。關於Uri標識屬另一個范疇,自行查詢。provider標識要放在裡面。如果遇到了"Permission Denial: opening provide..."的錯誤,可以試試在節點加“android:exported="true"”。
...
在B程序獲取數據
用Context獲取到當前的ContentResolver,根據Uri地址和ContentResolver的query方法獲取A程序的數據。Uri地址和A程序中AndroidManifest.xml定義的autorities要一致。當然,同類可以進行其它的操作。
- Contextctx=MainActivity.this;
- ContentResolverresolver=ctx.getContentResolver();
- Uriuri=Uri.parse("content://com.example.androidtestdemo");
- Cursorc=resolver.query(uri,null,null,null,null);
- c.moveToFirst();
- while(!c.isAfterLast()){
- for(inti=0,j=c.getColumnCount();iLog.v("Android2",""+c.getString(i));
- }
- c.moveToNext();
- }
讀取收件箱信息:
private void getMsgs(){
Uri uri = Uri.parse("content://sms/");
ContentResolver resolver = getContentResolver();
//獲取的是哪些列的信息
Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
while(cursor.moveToNext())
{
String address = cursor.getString(0);
String date = cursor.getString(1);
String type = cursor.getString(2);
String body = cursor.getString(3);
System.out.println("地址:" + address);
System.out.println("時間:" + date);
System.out.println("類型:" + type);
System.out.println("內容:" + body);
System.out.println("======================");
}
cursor.close();
}
往AndroidManifest.xml加入讀取收件箱的權限:
android:name="android.permission.READ_SMS"/>
往收件箱裡插入一條信息
private void insertMsg() {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues conValues = new ContentValues();
conValues.put("address", "123456789");
conValues.put("type", 1);
conValues.put("date", System.currentTimeMillis());
conValues.put("body", "no zuo no die why you try!");
resolver.insert(uri, conValues);
Log.e("HeHe", "短信插入完畢~");
}
- SQLite是一個輕量級關系型數據庫,只有NULL、INTEGER、REAL(浮點數)、TEXT(字符串)和BLOB(大數據)五種類型,不存在BOOLEAN和DATE類型。
- SQLiteOpenHelper:抽象類,我們通過繼承該類,然後重寫數據庫創建以及更新的方法, 我們還可以通過該類的對象獲得數據庫實例,或者關閉數據庫!
- SQLiteDatabase:數據庫訪問類:我們可以通過該類的對象來對數據庫做一些增刪改查的操作
- Cursor:游標,有點類似於JDBC裡的resultset,結果集!可以簡單理解為指向數據庫中某 一個記錄的指針!