Android視訊學習(一):資料儲存與介面展示1

塵埃zza發表於2016-09-07

主要包含內容:

  • 在內部儲存空間中讀寫檔案
  • 在外部儲存讀寫資料
  • 檢視原始碼查詢獲取sd卡剩餘容量的程式碼
  • Linux檔案的訪問許可權
  • openFileOutput
  • SharedPreference
  • 生成XML檔案備份簡訊

檔案讀寫操作

  • Ram記憶體:執行記憶體,相當於電腦的記憶體
  • Rom記憶體:內部儲存空間,相當於電腦的硬碟
  • sd卡:外部儲存空間,相當於電腦的行動硬碟

在內部儲存空間中讀寫檔案

  • 所有安裝至手機的應用都會在data/data目錄下生成一個包名資料夾,這個資料夾就是內部儲存的路徑
  • 應用只能在自己的包名資料夾中讀寫檔案

小案例:使用者輸入賬號密碼,勾選“記住賬號密碼”,點選登入按鈕,登入的同時持久化儲存賬號和密碼

1. 定義佈局
2. 完成按鈕的點選事件
  • 彈土司提示使用者登入成功
Toast.makeText(this, "登入成功", Toast.LENGTH_SHORT).show();
3. 拿到使用者輸入的資料
  • 判斷使用者是否勾選儲存賬號密碼
CheckBox cb = (CheckBox) findViewById(R.id.cb);
        if(cb.isChecked()){ 
        }
4. 開啟io流把檔案寫入內部儲存
  • 直接開啟檔案輸出流寫資料
        //持久化儲存資料
            File file = new File("data/data/com.itheima.rwinrom/info.txt");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write((name + "##" + pass).getBytes());
            fos.close();
  • 讀取資料前先檢測檔案是否存在
        if(file.exists())
  • 讀取儲存的資料,也是直接開檔案輸入流讀取
        File file = new File("data/data/com.itheima.rwinrom/info.txt");
        FileInputStream fis = new FileInputStream(file);
        //把位元組流轉換成字元流
        BufferedReader br = new BufferedReader(new InputStreamReader(fis));
        String text = br.readLine();
        String[] s = text.split("##");
  • 讀取到資料之後,回顯至輸入框
        et_name.setText(s[0]);
        et_pass.setText(s[1]);
  • 應用只能在自己的包名目錄下建立檔案,不能到別人家去建立

直接複製專案

  • 需要改動的地方:
    • 專案名字
    • 應用包名
    • R檔案重新導包

使用路徑api讀寫檔案

  • getFilesDir()得到的file物件的路徑是data/data/com.itheima.rwinrom2/files
    • 存放在這個路徑下的檔案,只要你不刪,它就一直在
  • getCacheDir()得到的file物件的路徑是data/data/com.itheima.rwinrom2/cache

    • 存放在這個路徑下的檔案,當記憶體不足時,有可能被刪除
  • 系統管理應用介面的清除快取,會清除cache資料夾下的東西,清除資料,會清除整個包名目錄下的東西


在外部儲存讀寫資料

sd卡的路徑

  • 2.2之前,sd卡路徑:sdcard
  • 4.3之前,sd卡路徑:mnt/sdcard
  • 4.3開始,sd卡路徑:storage/sdcard

  • 最簡單的開啟sd卡的方式

File file = new File("sdcard/info.txt");
  • 寫sd卡需要許可權
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • 讀sd卡,在4.0之前不需要許可權,4.0之後可以設定為需要
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  • 使用api獲得sd卡的真實路徑,部分手機品牌會更改sd卡
Environment.getExternalStorageDirectory()
  • 判斷sd卡是否準備就緒
  • Environment.MEDIA_MOUNTED 可用
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))

檢視原始碼查詢獲取sd卡剩餘容量的程式碼

  • 匯入Settings專案
  • 查詢“可用空間”得到
    <string name="memory_available" msgid="418542433817289474">"可用空間"</string>
  • 查詢”memory_available”,得到
    <Preference android:key="memory_sd_avail" 
            style="?android:attr/preferenceInformationStyle" 
            android:title="@string/memory_available"
            android:summary="00"/>
  • 查詢”memory_sd_avail”,得到
        //這個字串就是sd卡剩餘容量
        formatSize(availableBlocks * blockSize) + readOnly
        //這兩個引數相乘,得到sd卡以位元組為單位的剩餘容量
        availableBlocks * blockSize
  • 儲存裝置會被分為若干個區塊,每個區塊有固定的大小
  • 每個區塊的大小 * 區塊總數 = 儲存裝置的總大小
  • 每個區塊的大小 * 可用區塊的數量 = 儲存裝置可用大小

  • 判斷當前版本是否是4.3或以上

Build.VERSION.SDK_INT >= 18

Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2

Linux檔案的訪問許可權

  • 在Android中,預設每一個應用是一個獨立的使用者
  • drwxrwxrwx
  • 第1位:d表示資料夾,-表示檔案
  • 第2-4位:rwx,表示這個檔案的擁有者使用者(owner)對該檔案的許可權
    • r:讀
    • w:寫
    • x:執行
  • 第5-7位:rwx,表示跟檔案擁有者使用者同組的使用者(grouper)對該檔案的許可權
  • 第8-10位:rwx,表示其他使用者組的使用者(other)對該檔案的許可權

openFileOutput

預設路徑
/data/date/<包名>/files
四種模式
使用多個模式:使用|運算子
* MODE_PRIVATE:-rw-rw—-
* MODE_APPEND:-rw-rw—-
* MODE_WORLD_WRITEABLE:-rw-rw–w-
* MODE_WORLD_READABLE:-rw-rw-r–


SharedPreference

用SharedPreference儲存鍵值對
原理生成是XML檔案

  • 往SharedPreference裡寫資料
        //拿到一個SharedPreference物件
        SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
        //拿到編輯器
        Editor ed = sp.edit();
        //寫資料
        ed.putBoolean("name", name);
        ed.commit();
  • 從SharedPreference裡取資料
        SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
        //從SharedPreference裡取資料
        String name = sp.getBoolean("name", "");

生成XML檔案備份簡訊

  • 建立幾個虛擬的簡訊物件,存在list中
  • 備份資料通常都是備份至sd卡

使用StringBuffer拼接字串(不推薦用)

  • 把整個xml檔案所有節點append到sb物件裡
        sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
        //新增smss的開始節點
        sb.append("<smss>");
        .......
  • 把sb寫到輸出流中
    fos.write(sb.toString().getBytes());

使用XMl序列化器生成xml檔案

  • 得到xml序列化器物件
    XmlSerializer xs = Xml.newSerializer();
  • 給序列化器設定輸出流
        File file = new File(Environment.getExternalStorageDirectory(), "backupsms.xml");
        FileOutputStream fos = new FileOutputStream(file);
        //給序列化器指定好輸出流
        xs.setOutput(fos, "utf-8");
  • 開始生成xml檔案
        //生成頭節點
        xs.startDocument("utf-8", true);
        //開始生成標籤
        xs.startTag(null, "smss");

        for (Sms sms : smsList) {
                xs.startTag(null, "sms");

                xs.startTag(null, "body");
                //使用StringBuffer拼接字串會出錯
                xs.text(sms.getBody() + "<body>");
                xs.endTag(null, "body");

                xs.startTag(null, "type");
                xs.text(sms.getType() + "");
                xs.endTag(null, "type");

                xs.startTag(null, "date");
                xs.text(sms.getDate() + "");
                xs.endTag(null, "date");

                xs.startTag(null, "address");
                xs.text(sms.getAddress());
                xs.endTag(null, "address");

                xs.endTag(null, "sms");
        }
        //生成結束節點
        xs.endTag(null, "smss");
        //生成尾節點
        xs.endDocument();

程式碼下載

相關文章