Android五種數據存儲方式


android 五種數據存儲 :SharePreferences、SQLite、Contert Provider、File、網絡存儲

 

Android系統提供了四種存儲數據方式。分別為:SharePreference、SQLite、Content Provider和File。但由於Android系統中,數據基本是私有的,都是存放於”data/data”程序包名目錄下,所以要實現數據共享,正確方式是使用Content Provider

 

SQLite:SQLite是一個輕量級的數據庫,支持基本的SQL語法,是常被采用的一種數據存儲方式。Android為此數據庫提供了一個名為SQLiteDatabase的類,封裝了一些操作數據庫的api

 

SharedPreference: 除SQLite數據庫外,另一種常用的數據存儲方式,其本質就是一個xml文件,常用於存儲較簡單的參數設置。

 

File: 即常說的文件(I/O)存儲方法,常用語存儲大數量的數據,但是缺點是更新數據將是一件困難的事情。

 

ContentProvider: Android系統中能實現所有應用程序共享的一種數據存儲方式,由於數據通常在各應用間的是互相私密的,所以此存儲方式較少使用,但是其又是必不可少的一種存儲方式。例如音頻,視頻,圖片和通訊錄,一般都可以采用此種方式進行存儲。每個Content Provider都會對外提供一個公共的URI(包裝成Uri對象),如果應用程序有數據需要共享時,就需要使用Content Provider為這些數據定義一個URI,然后其他的應用程序就通過Content Provider傳入這個URI來對數據進行操作。

URI由3個部分組成:"content://"、數據的路徑、標識ID(可選)。

 

1)SQLite數據存儲

======================================================================

SQLite是一種轉為嵌入式設備設計的輕型數據庫,其只有五種數據類型,分別為:

NULL:空值

INTEGER:整數

REAL:浮點數

TEXT:字符串

BLOB:大數據

在SQLite中,並沒有專門設計BOOLEAN和DATE類型,因為BOOLEAN型可以用INTEGER的0和1代替true和false,而DATE類型則可以擁有特定格式的TEXT、REAL和INTEGER的值來代替顯示,為了能方便的操作DATE類型,SQLite提供了一組函數,

 

詳見:http://www.sqlite.org/lang_datefunc.html。這樣簡單的數據類型設計更加符合嵌入式設備的要求。關於SQLite的更多資料,請參看:http://www.sqlite.org/ 

 

在Android系統中提供了anroid.database.sqlite包,用於進行SQLite數據庫的增,刪,改,查工作,其主要方法如下:

 beginTransaction(): 開始一個事務。

 close(): 關閉連接,釋放資源。

 delete(String table, String whereClause, String[] whereArgs): 根據給定條件,刪除符合條件的記錄。

 endTransaction(): 結束一個事務。

 execSQL(String sql): 執行給定SQL語句。

 insert(String table, String nullColumnHack, ContentValues values): 根據給定條件,插入一條記錄。 

 openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory): 根據給定條件連接數據庫,如果此數據庫不存在,則創建。

 query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy): 執行查詢。

 rawQuery(String sql, String[] selectionArgs): 根據給定SQL,執行查詢。

 update(String table, ContentValues values, String whereClause, String[] whereArgs): 根據給定條件,修改符合條件的記錄。

  除了上訴主要方法外,Android還提供了諸多實用的方法,總之一句話:其實Android訪問數據庫是一件很方便的事兒。

 

 

 

可以清晰的在查詢結果中,紅線上下的數據是完全一致的,也就是說query和rawQuery方法在的不同僅僅在於所需參數的不同。rawQuery方法需要開發者手動寫出查詢SQL,而query方法是由目標表名、where子句、order by子句、having子句等諸多子句由系統組成SQL語句。兩方法同返回Cursor對象,所以兩方在使用時孰優孰劣,就看具體情況了。本人更喜歡rawQuery的方式,因為此方式更接近傳統Java開發,也可以由專業DBA來書寫SQL語句,這樣更符合MVC的思想,而且這樣的代碼可讀性更高。(query方法里面參數實在太多,有點記不住誰是order by子句,誰是having子句了)

 

Cursor對象可以理解為游標對象,凡是對數據有所了解的人,相信對此對象都不會陌生,在這里機不再累述。只提醒一點,在第一次讀取Cursor對象中的數據時,一定要先移動游標,否則此游標的位置在第一條記錄之前,會引發異常。

 

 

 

2.案例:

 

http://blog.csdn.net/developer_jiangqq/article/details/7043487

 

 

======================================================================

(2)SharedPreference數據存儲

======================================================================

除了SQLite數據庫外,SharedPreferences也是一種輕型的數據存儲方式,它的本質是基於XML文件存儲key-value鍵值對數據,通常用來存儲一些簡單的配置信息。其存儲位置在/data/data/<包名>/shared_prefs目錄下。SharedPreferences對象本身只能獲取數據而不支持存儲和修改,存儲修改是通過Editor對象實現。實現SharedPreferences存儲的步驟如下:

  一、根據Context獲取SharedPreferences對象

  二、利用edit()方法獲取Editor對象。

  三、通過Editor對象存儲key-value鍵值對數據。

四、通過commit()方法提交數據。

 

1.getSharedPreferences(String name, int mode)

得到名為‘name’的偏好文件。同時你可以更改和返回他的值。任何調用者在調用同樣名字的偏好文件時只有一個實例返回,這就意味着這些調用者都可以看到其他調用者做出的更改。

name為本組件的配置文件名( 自己定義,也就是一個文件名),當這個文件不存在時,直接創建,如果已經存在,則直接使用,

mode為操作模式,默認的模式為0或MODE_PRIVATE,還可以使用MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE

mode指定為MODE_PRIVATE,則該配置文件只能被自己的應用程序訪問。

mode指定為MODE_WORLD_READABLE,則該配置文件除了自己訪問外還可以被其它應該程序讀取。

mode指定為MODE_WORLD_WRITEABLE,則該配置文件除了自己訪問外還可以被其它應該程序讀取和寫入

2,PreferenceManager的方法getSharedPreferences()

這個方法是一個普通的方法,必須有PreferenceManager的實例調用才行

3.getDefaultSharedPreferences方法

這個方法是靜態的,因此可以直接調用,同時它與我們調用getSharedPreferences()方法得到的返回值是一樣的,只是調用的方式不同罷了。

 

因為SharedPreferences背后是使用xml文件保存數據,getSharedPreferences(name,mode)方法的第一個參數用於指定該文件的名稱,名稱不用帶后綴,后綴會由Android自動加上。方法的第二個參數指定文件的操作模式,共有四種操作模式,這四種模式前面介紹使用文件方式保存數據時已經講解過。如果希望SharedPreferences背后使用的xml文件能被其他應用讀和寫,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE權限。

另外Activity還提供了另一個getPreferences(mode)方法操作SharedPreferences,這個方法默認使用當前類不帶包名的類名作為文件的名稱。

 

如果訪問其他應用中的Preference,前提條件是:該preference創建時指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE權限。如:有個<package name>為cn.yang.action的應用使用下面語句創建了preference。

getSharedPreferences("TEST", Context.MODE_WORLD_READABLE);

其他應用要訪問上面應用的preference,首先需要創建上面應用的Context,然后通過Context 訪問preference ,訪問preference時會在應用所在包下的shared_prefs目錄找到preference :

Context otherAppsContext = createPackageContext("cn.wsl.action", Context.CONTEXT_IGNORE_SECURITY);

SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("TEST", Context.MODE_WORLD_READABLE);

String name = sharedPreferences.getString("name", "");

int age = sharedPreferences.getInt("sex", "");

 

如果不通過創建Context訪問其他應用的preference,也可以以讀取xml文件方式直接訪問其他應用preference對應的xml文件,如: 

File xmlFile = new File(“/data/data/<package name>/shared_prefs/itcast.xml”);//<package name>應替換成應用的包名。

 

具體實現代碼如下:

 

public class MainActivity extends Activity {

      @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

        

        //獲取SharedPreferences對象

         Context ctx = MainActivity.this;       

         SharedPreferences sp = ctx.getSharedPreferences("SI", MODE_PRIVATE);

        //存入數據

       Editor editor = sp.edit();//獲取編輯器

        editor.putString("STRING_KEY", "string1");

       editor.putInt("INT_KEY", 0);

       editor.putBoolean("BOOLEAN_KEY", true);

       editor.commit();

        

        //返回STRING_KEY的值

       Log.d("SP", sp.getString("STRING_KEY", "none"));

        //如果NOT_EXIST不存在,則返回值為"none"

       Log.d("SP", sp.getString("NOT_EXIST", "none"));

    }

}

這段代碼執行過后,即在/data/data/com.test/shared_prefs目錄下生成了一個SI.xml文件,一個應用可以創建多個這樣的xml文件。如圖所示: 

 

 

 SP.xml文件的具體內容如下:

 

 <?xml version='1.0' encoding='utf-8' standalone='yes' ?>

<map>

<string name="STRING_KEY">string</string>

 <int name="INT_KEY" value="0" />

<boolean name="BOOLEAN_KEY" value="true" />

</map>

 

 

在程序代碼中,通過getXXX方法,可以方便的獲得對應Key的Value值,如果key值錯誤或者此key無對應value值,SharedPreferences提供了一個賦予默認值的機會,以此保證程序的健壯性。如下圖運行結果中因為並無值為"NOT_EXIST"的Key,所以Log打印出的是其默認值:“none”。在訪問一個不存在key值這個過程中,並無任何異常拋出。  

 

  SharedPreferences對象與SQLite數據庫相比,免去了創建數據庫,創建表,寫SQL語句等諸多操作,相對而言更加方便,簡潔。但是SharedPreferences也有其自身缺陷,比如其職能存儲boolean,int,float,long和String五種簡單的數據類型,比如其無法進行條件查詢等。所以不論SharedPreferences的數據存儲操作是如何簡單,它也只能是存儲方式的一種補充,而無法完全替代如SQLite數據庫這樣的其他數據存儲方式。

 

2.案例說明:

private void saveflag(int flag){

SharedPreferences sp=this.getSharedPreferences("scrolltag", Context.MODE_PRIVATE);

Editor editor=sp.edit();

editor.putInt("flagtag", flag);

editor.commit();

}

private int getflag(){

SharedPreferences sharedPreferences =getSharedPreferences("scrolltag", Context.MODE_PRIVATE);

int flag=sharedPreferences.getInt("flagtag", 0);

return flag;

}

 

//此方法可以在任何程序中添加該段代碼,來獲取cn.com.shine.hotel應用中的數據了,前提是在該應用生成xml文件的時候的權限應該是 Context.MODE_WORLD_READABLE,或者是:讀寫

private String getScrollTextOther(){

String str=null;

Context otherAppsContext = null;

try {

otherAppsContext = createPackageContext("cn.com.shine.hotel",Context.CONTEXT_IGNORE_SECURITY);

SharedPreferences sp =otherAppsContext.getSharedPreferences("scrolltext",Context.MODE_WORLD_READABLE);

str=sp.getString("scrolltext", "");

} catch (NameNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return str;

}

 

 

======================================================================

(3)ContentProvider數據存儲

======================================================================

ContentProvider是安卓平台中,在不同應用程序之間實現數據共享的一種機制。一個應用程序如果需要讓別的程序可以操作自己的數據,即可采用這種機制。並且此種方式忽略了底層的數據存儲實現,ContentProvider提供了一種統一的通過Uri實現數據操作的方式。其步驟為:

  1. 在當前應用程序中定義一個ContentProvider。

  2. 在當前應用程序的AndroidManifest.xml中注冊此ContentProvider

  3. 其他應用程序通過ContentResolver和Uri來獲取此ContentProvider的數據。

 

 ContentResolver提供了諸如insert(), delete(), query()和update()之類的方法。用於實現對ContentProvider中數據的存取操作。

  Uri是一個通用資源標志符,將其分為A,B,C,D 4個部分:

    A:無法改變的標准前綴,包括;"content://"、"tel://"等。當前綴是"content://"時,說明通過一個Content Provider控制這些數據  

    B:URI的標識,它通過authorities屬性聲明,用於定義了是哪個ContentProvider提供這些數據。對於第三方應用程序,為了保證URI標識的唯一性,它必須是一個完整的、小寫的   類名。例如;"content://com.test.data.myprovider"

    C:路徑,可以近似的理解為需要操作的數據庫中表的名字,如:"content://hx.android.text.myprovider/name"中的name

    D:如果URI中包含表示需要獲取的記錄的ID;則就返回該id對應的數據,如果沒有ID,就表示返回全部;

 

 下面進行案展示:演示一下如何在應用程序之間相互獲取數據:

在應用程序A中,繼承ContentProvider類,並重寫其中方法:

 

 

 

 

 

 

public class MyProvider extends ContentProvider{

    @Override

    public int delete(Uri uri, String selection, String[] selectionArgs) {

        // TODO Auto-generated method stub

        return 0;

    }

 

    @Override

    public String getType(Uri uri) {

        // TODO Auto-generated method stub

        return null;

    }

 

    @Override

    public Uri insert(Uri uri, ContentValues values) {

        return null;

    }

 

    //在Create中初始化一個數據庫

    @Override

    public boolean onCreate() {

        SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);

        db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");

        ContentValues values = new ContentValues();

        values.put("name", "test");

        db.insert("tab", "_id", values);

        db.close();

        return true;

    }

 

    //實現query方法

    @Override

    public Cursor query(Uri uri, String[] projection, String selection,

            String[] selectionArgs, String sortOrder) {

        SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);

        Cursor c = db.query("tab", null, null, null, null, null,null);

        return c;

    }

 

    @Override

    public int update(Uri uri, ContentValues values, String selection,

            String[] selectionArgs) {

        // TODO Auto-generated method stub

        return 0;

    }

}

 

在其AndroidManifest.xml中聲明此ContentProvider,其中authorities屬性定義了此ContentProvider的Uri標識

<provider android:name=".MyProvider" android:authorities="com.test.MyProvider"/>

在應用程序B中,通過ContentResolver獲取程序A的ContentProvider中的數據。

 

public class MainActivity extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        

        //獲取上下文

        Context ctx = MainActivity.this;

        //獲取ContentResolver對象

        ContentResolver resolver = ctx.getContentResolver();

        //獲取Uri對象

        Uri uri = Uri.parse("content://com.test.MyProvider");

        //獲取數據

        Cursor c = resolver.query(uri, null, null, null, null);

        c.moveToFirst();

        for(int i=0; i<c.getCount(); i++){

            int index = c.getColumnIndexOrThrow("name");

            String src = c.getString(index);

            Log.d("", src);

            c.moveToNext();

        }

    }

}

應用程序B的運行結果如下,從此圖可以發現我們在程序B中成功的獲取到了程序A中的數據:

 

再觀察兩個應用程序的結構,如下圖,其中紅框是應用程序A的程序結構,可以清楚看到其有一個名為“test_db.db3”的數據庫,藍框是應用程序B的程序結構,其並沒有任何數據庫用於存儲數據。由此圖,可以確定應用程序B中查詢出來的數據結果是來自於應用程序A。

 

 

http://www.cnblogs.com/dyllove98/archive/2013/07/17/3196821.html

 

http://blog.csdn.net/biaozhiyuan/article/details/7298095

 

  以上就是ContentProvider的使用方式,這種存儲方式相比SQLite和SharedPreferences,其復雜性是顯而易見的,但是在處處可見“雲”的今天,程序間的數據交互需求令ContentProvider存儲機制變成必不可少的一部分。

 

======================================================================

(4)File數據存儲

======================================================================

使用File進行存儲 我們有時候可以將數據直接以文件的形式保存在設備中,

 

例如:文本文件,圖片文件等等

 

使用File進行存儲操作主要使用到以下的

 

(1):public abstract FileInputStream openFileInput (String name)

 

這個主要是打開文件,返回FileInputStream

 

(2):public abstract FileOutputStream openFileOutput (String name, int mode)

 

這個主要是寫入文件,如果該文件不存在,直接進行創建,返回FileOutputStream

 

Mode(主要有以下的一種的模式)

 

 

MODE_PRIVATE //私有

 

(3):FileInputStream(獲取文件輸入流)與FileOutputStream (獲取文件輸出流)這兩類在JavaIO 操作中很常見

 

接下來進行操作 保存成功之后講文件保存在當前應該程序的包名下的files/(可以改變存儲的其他路徑)

 

 

 

package com.jiangqq.file;  

  

import java.io.FileInputStream;  

import java.io.FileOutputStream;  

  

import android.app.Activity;  

import android.os.Bundle;  

import android.view.View;  

import android.view.View.OnClickListener;  

import android.widget.Button;  

import android.widget.EditText;  

import android.widget.Toast;  

  

public class FileAcitivy extends Activity  

{  

    private Button bt1, bt2;  

    private EditText et1, et2;  

  

    private static final String FILENAME = "temp_file.txt";  

  

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.main);  

        bt1 = (Button) this.findViewById(R.id.bt1);  

        bt2 = (Button) this.findViewById(R.id.bt2);  

        et1 = (EditText) this.findViewById(R.id.et1);  

        et2 = (EditText) this.findViewById(R.id.et2);  

        bt1.setOnClickListener(new OnClickListener() {  

  

            @Override  

            public void onClick(View v) {  

                write(et1.getText().toString());  

                Toast.makeText(FileAcitivy.this, "文件寫入成功", Toast.LENGTH_LONG)  

                        .show();  

            }  

        });  

        bt2.setOnClickListener(new OnClickListener() {  

  

            @Override  

            public void onClick(View v) {  

                et2.setText(read());  

                Toast.makeText(FileAcitivy.this, "文件讀出成功", Toast.LENGTH_LONG)  

                        .show();  

            }  

        });  

    }  

  

    // 讀文件方法   

    private String read() {  

        try {  

            FileInputStream inputStream = openFileInput(FILENAME);  

            byte[] b = new byte[inputStream.available()];  

            inputStream.read(b);  

            return new String(b);  

        } catch (Exception e) {  

        }  

        return null;  

    }  

  

    // 寫文件   

    private void write(String content) {  

        try {  

            FileOutputStream fos = openFileOutput(FILENAME, MODE_APPEND);  

            fos.write(content.getBytes());  

            fos.close();  

        } catch (Exception e) {  

        }  

    }  

}  

 

2.文件存儲,Activity提供了openFileOutput()方法可以用於把數據輸出到文件中,具體的實現過程與在J2SE環境中保存數據到文件中是一樣的。

public void save()

    {

        try {

            FileOutputStream outStream=this.openFileOutput("a.txt",Context.MODE_WORLD_READABLE);

            outStream.write(text.getText().toString().getBytes());

            outStream.close();

            Toast.makeText(MyActivity.this,"Saved",Toast.LENGTH_LONG).show();

        } catch (FileNotFoundException e) {

            return;

        }

        catch (IOException e){

            return ;

        }

    }

openFileOutput()方法的第一參數用於指定文件名稱,不能包含路徑分隔符“/” ,如果文件不存在,Android 會自動創建它。創建的文件保存在/data/data/<package name>/files目錄,如: /data/data/cn.itcast.action/files/itcast.txt ,通過點擊Eclipse菜單“Window”-“Show View”-“Other”,在對話窗口中展開android文件夾,選擇下面的File Explorer視圖,然后在File Explorer視圖中展開/data/data/<package name>/files目錄就可以看到該文件。

openFileOutput()方法的第二參數用於指定操作模式,有四種模式,分別為: Context.MODE_PRIVATE    =  0

Context.MODE_APPEND    =  32768

Context.MODE_WORLD_READABLE =  1

Context.MODE_WORLD_WRITEABLE =  2

Context.MODE_PRIVATE:為默認操作模式,代表該文件是私有數據,只能被應用本身訪問,在該模式下,寫入的內容會覆蓋原文件的內容,如果想把新寫入的內容追加到原文件中。可以使用Context.MODE_APPEND

Context.MODE_APPEND:模式會檢查文件是否存在,存在就往文件追加內容,否則就創建新文件。

Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用來控制其他應用是否有權限讀寫該文件。

MODE_WORLD_READABLE:表示當前文件可以被其他應用讀取;MODE_WORLD_WRITEABLE:表示當前文件可以被其他應用寫入。

如果希望文件被其他應用讀和寫,可以傳入:

openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);

 

android有一套自己的安全模型,當應用程序(.apk)在安裝時系統就會分配給他一個userid,當該應用要去訪問其他資源比如文件的時候,就需要userid匹配。默認情況下,任何應用創建的文件,sharedpreferences,數據庫都應該是私有的(位於/data/data/<package name>/files),其他程序無法訪問。除非在創建時指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有這樣其他程序才能正確訪問。

 

 

public void load()

{

    try {

        FileInputStream inStream=this.openFileInput("a.txt");

        ByteArrayOutputStream stream=new ByteArrayOutputStream();

        byte[] buffer=new byte[1024];

        int length=-1;

        while((length=inStream.read(buffer))!=-1)   {

            stream.write(buffer,0,length);

        }

        stream.close();

        inStream.close();

        text.setText(stream.toString());

        Toast.makeText(MyActivity.this,"Loaded",Toast.LENGTH_LONG).show();

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    }

    catch (IOException e){

        return ;

    }

}

 

 

對於私有文件只能被創建該文件的應用訪問,如果希望文件能被其他應用讀和寫,可以在創建文件時,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE權限。

Activity還提供了getCacheDir()和getFilesDir()方法:

getCacheDir()方法用於獲取/data/data/<package name>/cache目錄

getFilesDir()方法用於獲取/data/data/<package name>/files目錄

 

 

使用Activity的openFileOutput()方法保存文件,文件是存放在手機空間上,一般手機的存儲空間不是很大,存放些小文件還行,如果要存放像視頻這樣的大文件,是不可行的。對於像視頻這樣的大文件,我們可以把它存放在SDCard。 SDCard是干什么的?你可以把它看作是移動硬盤或U盤。 

 

在模擬器中使用SDCard,你需要先創建一張SDCard卡(當然不是真的SDCard,只是鏡像文件)。創建SDCard可以在Eclipse創建模擬器時隨同創建,也可以使用DOS命令進行創建,如下: 

在Dos窗口中進入android SDK安裝路徑的tools目錄,輸入以下命令創建一張容量為2G的SDCard,文件后綴可以隨便取,建議使用.img: 

mksdcard 2048M D:\AndroidTool\sdcard.img 

在程序中訪問SDCard,你需要申請訪問SDCard的權限。 

在AndroidManifest.xml中加入訪問SDCard的權限如下: 

<!-- 在SDCard中創建與刪除文件權限 --> 

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 

<!-- 往SDCard寫入數據權限 --> 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

 

 

要往SDCard存放文件,程序必須先判斷手機是否裝有SDCard,並且可以進行讀寫。 

注意:訪問SDCard必須在AndroidManifest.xml中加入訪問SDCard的權限 

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ 

         File sdCardDir = Environment.getExternalStorageDirectory();//獲取SDCard目錄 

         File saveFile = new File(sdCardDir, “a.txt”); 

       FileOutputStream outStream = new FileOutputStream(saveFile);

         outStream.write("test".getBytes()); 

         outStream.close(); 

Environment.getExternalStorageState()方法用於獲取SDCard的狀態,如果手機裝有SDCard,並且可以進行讀寫,那么方法返回的狀態等於Environment.MEDIA_MOUNTED。 

Environment.getExternalStorageDirectory()方法用於獲取SDCard的目錄,當然要獲取SDCard的目錄,你也可以這樣寫: 

File sdCardDir = new File("/sdcard"); //獲取SDCard目錄 

File saveFile = new File(sdCardDir, "itcast.txt");  

//上面兩句代碼可以合成一句: File saveFile = new File("/sdcard/a.txt"); 

FileOutputStream outStream = new FileOutputStream(saveFile); 

outStream.write("test".getBytes()); 

outStream.close(); 

 

 

 

 5.網絡存儲:

 

Android提供了通過網絡來實現數據的存儲和獲取的方法。

 我們可以調用WebService返回的數據或是解析HTTP協議實現網絡數據交互。

 具體需要熟悉java.net.*,Android.net.*這兩個包的內容,詳細的類與方法的說明,請參考SDK。

 下面是一個通過地區名稱查詢該地區的天氣預報,以POST發送的方式發送請求到webservicex.net站點,訪問WebService.webservicex.net站點上提供查詢天氣預報的服務。

 代碼如下:

package com.android.weather; 
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.os.Bundle;

public class MyAndroidWeatherActivity extends Activity {
    //定義需要獲取的內容來源地址
    private static final String SERVER_URL = 
        "http://www.webservicex.net/WeatherForecast.asmx/GetWeatherByPlaceName";
    
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        HttpPost request = new HttpPost(SERVER_URL); //根據內容來源地址創建一個Http請求
        // 添加一個變量 
        List<NameValuePair> params = new ArrayList<NameValuePair>(); 
        // 設置一個地區名稱
        params.add(new BasicNameValuePair("PlaceName", "NewYork"));  //添加必須的參數
        
        
        try { 
            //設置參數的編碼
            request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); 
            //發送請求並獲取反饋
            HttpResponse httpResponse = new DefaultHttpClient().execute(request);
             
            // 解析返回的內容
            if(httpResponse.getStatusLine().getStatusCode() != 404){ 
               String result = EntityUtils.toString(httpResponse.getEntity()); 
               System.out.println(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
       } 
    }
}

  別忘記了在配置文件中設置訪問網絡權限:

 <uses-permission android:name="android.permission.INTERNET" /> 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM