Android基礎第二天

permission
n.允許;批準,正式認可,認可
user permission 使用權限
permission Denial 權限被拒絕,
is risky 有風險
mount 安裝, 鑲嵌,嵌入
mount sdcard 安裝sdcard 卡
unmount sdcard 卸載sdcard 卡

SharedPreferences

share
n.股;(參與、得到等的)份;(分享到的或貢獻出的)一份;市場占有率
vt.& vi.共有;共用;均攤
vt.分配;分開;共同承擔

preferences
[英] [?pref?r?ns][美] [?pr?f?r?ns, ?pr?fr?ns]
n.偏愛;優先權;偏愛的事物;(債權人)受優先償還的權利

Restore
vt. 歸還;交還;使恢復;修復
vt.& vi. 恢復(某種情況或感受);使復原;使復位;使復職
Data Storage 數據存貯
developer guide 開發者指南
Restore preferences 恢復/讀取 數據存貯

網 絡
還原; 還原功能; 恢復軟件; 恢復設置

//b.設置按鈕的點擊事件
//定義一個 全局變量
private Context mContext;
//把this 賦值給mContext
mContext=this;
bt_login.setOnClickListener(this);
bt_login.setOnClickListener(new OnClickListencer(){
public void onClick(View v){
Toast.makeText(mContext,"輸出語句",0).show(); }} );

toast.maketext(this, "輸出內容", 0).show(); //安卓的輸出打印相當與system.out.println("helloword")


一 :測試

軟件測試

  • 黑盒測試

不知道軟件的內部源代碼.只知道外在的輸入輸出的測試

  • 白盒測試

知道內部應用程序的源代碼

測試的粒度

  • 單元測試 junit test 測試某個方法
  • 集成測試 intergration test
  • 系統測試 system test

測試的程度

  • 壓力測試 (pressure test) 并發訪問
  • 冒煙測試 (smoke test)

monkey 猴子 用于冒煙測試

Android下的junit test

需要把應用程序部署到真實的手機或者模擬器,在dalvik虛擬機里面運行.

單元測試步驟:

  1. 編寫一個業務方法

  2. 編程一個測試 子類 繼承AndroidTestCase 類
    TestCalcService extends AndroidTestCase

  3. 在清單文件res/AndroidManifest.xml 中添加結點標簽
    <instrumentation> 和<uses-library>


<instrumentation android:name="android.test.InstrumentationTestRunner
//指定給那個測試的路徑
android:targetPackage="com.itheima.junit"> </instrumentation>


<uses-library android:name="android.test.runner"/>

4.(對3的簡化)添加測試結點標簽的簡便方法:

創建測試項目工程---Android Test Project---取名 test-- res/AndroidManifest.xml簽單文件自動生成<instrumentation> 和<uses-library>

二:logcat 日志貓

把應用程序的執行的log打印輸出,查看錯誤信息。還不行看不出來的話,私有debug 斷點查看

System.out.println();
Log.i();
int Log.i(String tag,String msg);
int Log.i(String tag,String msg,Throwable tr);
boolean isLoggable(String tag,int level);

if(cb_remember.isChecked()){
Log.i(TAG, "勾上啦,要記住密碼");
}
else{ // 如果CheckBox 控件未被勾選上, 不用記住密碼
Log.i(TAG,"為勾選,不需記住密碼"); }

三: 把andorid 的數據(字符串,用戶名和密碼 )存儲到------>私有文件info.txt里
以QQ用戶名和密碼登陸案列為例

1.寫布局
用到線性布局和相對布局
A 線性布局
<LinearLayout android:orientation="vertical" >
<EditText android:id="@+id/et_username" android:hint="請輸入用戶名" />
<EditText android:id="@+id/et_password" android:hint="請輸入密碼" />

B 相對布局
<RelativeLayout >
<CheckBox android:id="@+id/cb_rem" android:text=" 記住密碼" />
<Button android:id="@+id/bt_login" android:text="登陸" />"
</RelativeLayout>
</LinearLayout>

2.寫業務邏輯 ----Main_Activity.java----- 設計到吧手機數據存貯到私有文件里

a.找到相應控件,要對組件進行一系列的操作 . 獲取組件控件對象 et_username 和et_password  findViewById()
       控件 對象 = (控件的類型)findViewById(R.id.空間對象);
              et_username    =    (EditText) findViewById(R.id.et_username)

b.設置控件按鈕的點擊事件監聽器,監聽點擊事件。(多個按鈕設置多個監聽事件,) 
      //但是讓MainActivity 類要實現 OnClickListener接口,重寫 OnClick(View v)方法

 setOnClickListener (View.OnClickListener l)  
   參數是個接口,這里傳入this  代表上下文
       
  bt_login.setOnClickListener(this);
                  
  //重寫OnClick(View v)方法,點擊按鈕后,觸發事件, 執行onclick()方法里的語句
         public void onClick(View v) {
        int  id =    v.getId();
      switch(id){
          //點擊的是登陸按鈕,就促發登陸事件。調用封裝的登陸方法 login();
       case R.id.bt_login:
      try {login();} 
      catch (Exception e) {e.printStackTrace();}
        break;
        
        default:
        break;
      }


c.點擊按鈕觸發事件,調用onclick方法中執行語句。 即 獲取用戶輸入的用戶名密碼  和  是否記住用戶名和密碼
            C.1 如何獲取文本框輸入的用戶名和 密碼  
           即 String  EditText類的對象.getText().toString().trim();
            
              String username= et_username.getText().toString().trim();
          C.2  如何記住文本框的 用戶名和密碼    //isrem=true  選中勾選框要記住用戶名和密碼;isrem=false,不記
                   boolean isrem= cb_rem.isChecked();

d.判斷用戶名密碼是否為空,不為空請求服務器(省略,默認請求成功)
用戶名密碼 為空 輸出 Toast.makeText(mContext, "用戶名或密碼不能為空", Toast.LENGTH_SHORT).show() ;return;
用戶名密碼 不為空 登陸成功,請求服務器 .....

e.判斷是否記住用戶名和 密碼,
      如果要記住用戶名密碼(isrem=true)    則將用戶名密碼數據保存到本地的私有目錄文件   
                 如何保存? 另建個類UserInfoUtil調 boolean saveUserInfo()方法進行保存
                     返回 true 保存成功  輸出 Toast.makeText(mContext, "用戶名或密碼保存成功", Toast.LENGTH_SHORT).show() ;
                                 返回 false 保存失敗 輸出  Toast.makeText(mContext, "用戶名或密碼保存失敗", Toast.LENGTH_SHORT).show() ;
                 
              如果不需要記住用戶名密碼(isrem=false), 直接輸出  Toast.makeText(mContext, "用戶名或密碼無需保存", Toast.LENGTH_SHORT).show() ;

f.回顯用戶名密碼  顯示在登陸界面
         1首先獲取 字符串用戶名和密碼 
       調用 UserInfoUtil類的  Map getUserInfo()方法 返回一個MAP集合, 通過鍵獲取值,這個值就是我們需要的字符串用戶名和密碼
      
     2.把獲取的字符串用戶名和密碼 設置/添加 到 文本內容里。 
          通過文本框對象操作
             文本框對象.setText(設置添加的字符串值);
              et_username.setText(username);
                3.回顯到登陸界面
        復選框對象Checked.setChecked(true)   
       cb_rem.setChecked(true); //setChecked(flag) 設置復選框為選中狀態,用戶名和密碼回顯到界面
        
   注意:另外需要建立一個類 UserInfoUtil 有兩個方法

          1.用來保存用戶名和密碼 的方法 
        boolean saveUserInfo(Context context,String username,String password)
        如何保存用戶名和密碼?------核心----通過輸出流將字符串用戶名和密碼寫到私有文件里

              1.1建立私有文件對象
           File file = new File(context.getFilesDir().getPath(),"userInfo.txt");
           1.2 建立個輸出流對象,把用戶名和密碼 寫到私有文件里
              FileOutputStream fos = new FileOutputStream(file);
               fos.write(  “字符串用戶名和密碼”.getBytes());

             2.獲取用戶名和密碼的方法  
     static Map<String,String> getUserInfo(Context context)

如何獲取用戶名和密碼?------核心----通過輸入流 把存在私有文件里的用戶名和密碼讀取出來,存在map集合里,在獲取,設置/添加到文本框,再回顯

       2.1 把用戶名和密碼從私有文件里讀取出來
            File file = new File(context.getFilesDir().getPath(),"userInfo.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 
         String line = br.readLine();
                2.2 把讀取的字符串(用戶名和密碼)分割,作為值存儲到map集合里 
     HashMap<String ,String> hashmap = new HashMap<String,String>();
                  hashmap.put("username", username);
                  hashmap.put("password", password);

                 2.3  通過鍵獲取用戶名值和密碼值 回到 第f步驟 

總結:
 通過context context對象獲取私有文件的目錄路徑,/data/data/packagename/filse
context.getFileDir().getPath()

四。 把andorid 的數據(字符串,用戶名和密碼 )存儲到------> 存儲到外來的sdcard里

注意:1.以上是把手機的數據(用戶名和密碼)存儲到私有文件里 ,而這是把手機的數據存儲在外來的sdcard卡里
但是goole為了安全,對sdcard卡進行了權限設置,所以我們 從sdcard卡 里讀取數據和往sdcard卡里寫入數據時,要獲取
sdcard卡的權限后,才能對其進行讀寫數據的操作。

1.1 手機數據保存在私有文件路勁下/data/data 和保存在sdcard卡路徑下 /mnt/sdcard 的區別?

  /data/data: context.getFileDir().getPath();
            是一個應用程序的私有目錄,只有當前應用程序有權限訪問讀寫私有文件,其他應用無權限訪問
            存放 要求安全性高的小數據  (存用戶名和密碼)  
/sdcard:  Enviroment.getExternalStorageDirectory().getPath();
            是一個外部存儲目錄,只要應用聲明了<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>的一個權限,就可以訪問讀寫sdcard卡目錄;
              存放 安全性不高的大數據, (存電影) 

   2.如何對sdcard卡獲取權限啦?
  res--AndroidManifest.xml---Permission 選Add---選user Permission----選中  name android.permission.WRITE_EXTERNAL_STORAGE

3.在Androidmanifest.xml就會生成權限標簽 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

   4. 如何獲取 sdcard卡里的文件的路徑
4.1 String filePath = "/mnt/sdcard/";// 獲取sdcard卡里的文件 路徑 //硬代碼不可取
 4.2 通過Environment類的靜態方法getExternalStorageDirectory().getPath()     獲取sdcard卡的文件目錄 
 
   即 Environment.getExternalStorageDirectory().getPath()    獲取sdcard卡里的文件的 目錄路徑  /mnt/sdcard/
           String path = Environment.getExternalStorageDirectory().getPath();

      5.使用前需要判斷sdcard卡的狀態 是否可用還是不可用
         如何判斷sdcard卡的狀態
      5.1  Environment類的staitc String getExternalStorageState()方法,獲取外sdcard卡的存儲狀態 (狀態未知需要匹配)
                       String sdcardState =  Environment.getExternalStorageState()

               5.2  Environment類有很多 String 常量,顯示sdcard卡的使用狀態
                 Environment.MEDIA_MOUNTED     顯示sdcard卡能夠讀取和寫入數據
              
         
          讓5.1的Environment.getExternalStorageState()未知狀態 和5.2已知狀態進行匹配
          Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED  二者匹配上,sdcard  卡狀態為安裝可用狀態

          if(!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)){
            //sdcard狀態是沒有掛載/裝載的情況
            Toast.makeText(mContext, "sdcard不存在或未掛載", Toast.LENGTH_SHORT).show();
            return ;}

  6.需要判斷sdcard剩余/可用空間 ,SDcard卡是否有足夠的空間存貯某個文件的數據 
                                 //獲取 sdcard卡的 目錄     把目錄作為文 件對象,
                                         File  sdcard_filedir = Environment.getExternalStorageDirectory();
                                         //獲取sdcard卡下的文件目錄 對象 還剩的空間大小(long類型)
                                             long usableSpace =sdcard_filedir.getUsableSpace();
                                              //獲取sdcard卡下的文件目錄 對象 總的空間大小(long類型)
                                             long totalSpace = sdcard_filedir.getTotalSpace();//
                
            //    可用的內存大小 usableSpace是long 類型 的,看不懂。所以還要把long 類型 的usableSpace轉成String字符串類型的內存大小, 
                                              //安卓提供了一個類Formatter     將一個long類型的文件大小  轉換成    成用戶可以看懂的M(兆),G   String類型的文件大小
                                        // String formatFileSize( Context context, usableSpace); 
                                           //context---上下文 這里用  mContext      usableSpace----long類型的文件大小對象
                               //long類型還剩 空間大小---->String類型還剩 空間大小           
                           String usableSpace_str = Formatter.formatFileSize(mContext, usableSpace);
                         //long類型總空間大小---->String類型總 空間大小           
                           String totalSpace_str = Formatter.formatFileSize(mContext, totalSpace);
                                             
                                              //對還剩的 空間大小usableSpace_str 進行判斷,能不能下電影(200M的電影)
                                             if(usableSpace < 1024 * 1024 * 200){//如果剩余空間(usableSpace未轉化的 )小于200M, 輸出內存不夠,無法下載
             Toast.makeText(mContext, "sdcard的剩余空間為:"+usableSpace_str+"內存不足,無法滿足下載;",Toast.LENGTH_SHORT).show();  
             Toast.makeText(mContext, "sdcard的總空間為:"+totalSpace_str+"內存不足,無法滿足下載;",Toast.LENGTH_SHORT).show();  
                                      
                     }

7.案列 ----- --QQ登陸案列_手機數據存貯在sdcard卡里

以QQ用戶名和密碼登陸案列為例 -------------存儲到外來的sdcard里

1.寫布局
用到線性布局和相對布局
A 線性布局
<LinearLayout android:orientation="vertical" >

<EditText android:id="@+id/et_username" android:hint="請輸入用戶名" />

<EditText android:id="@+id/et_password" android:hint="請輸入密碼" />

B 相對布局
<RelativeLayout >

<CheckBox android:id="@+id/cb_rem" android:text=" 記住密碼"  />
  <Button  android:id="@+id/bt_login"  android:text="登陸"  />"

</RelativeLayout>

</LinearLayout>

2.寫業務邏輯 ----Main_Activity.java----- 設計到吧手機數據存貯到私有文件里

a.找到相應控件,要對組件進行一系列的操作 . 獲取組件控件對象 et_username 和et_password  findViewById()
        
       控件 對象 = (控件的類型)findViewById(R.id.空間對象);
              et_username    =    (EditText) findViewById(R.id.et_username)

b.設置控件按鈕的點擊事件監聽器,監聽點擊事件。  讓MainActivity 類要實現 OnClickListener接口,重寫 OnClick(View v)方法
          //監聽傳入this  代表上下文
         bt_login.setOnClickListener(this);
                  
       //重寫OnClick(View v)方法
                 public void onClick(View v) {
                int  id =    v.getId();
              switch(id){
                  //點擊的是登陸按鈕,就促發登陸事件。調用封裝的登陸方法 login();
               case R.id.bt_login:
              try {login();} 
              catch (Exception e) {e.printStackTrace();}
                break;
                
                default:
                break;
              }


c.點擊按鈕觸發事件,調用onclick方法中執行語句。 即 獲取用戶輸入的用戶名密碼  和  是否記住用戶名和密碼
            C.1 如何獲取文本框輸入的用戶名和 密碼  
           即 String  EditText類的對象.getText().toString().trim();
            
              String username= et_username.getText().toString().trim();
          C.2  如何記住文本框的 用戶名和密碼    //isrem=true  選中勾選框要記住用戶名和密碼;isrem=false,不記
                   boolean isrem= cb_rem.isChecked();

d.判斷用戶名密碼是否為空,不為空請求服務器(省略,默認請求成功)
用戶名密碼 為空 輸出 Toast.makeText(mContext, "用戶名或密碼不能為空", Toast.LENGTH_SHORT).show() ;return;
用戶名密碼 不為空 登陸成功,請求服務器 .....

e.判斷是否記住用戶名和 密碼,
          如果要記住用戶名密碼(isrem=true)    則將用戶名密碼數據保存到本地的私有目錄文件  
         
                     //這里想下大文件電影,存貯在sdcard卡里  
             

                           1. //使用sdcard卡前,先要對sdcard卡的狀態是否正常進行判斷
                         //讓sdcard卡的狀態Environment.getExternalStorageState()與Environment的幾個已知狀態常量進行匹配
                            //Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED sdcard卡狀態為安裝可用
                        if(!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)){
                                            //如果 sdcard狀態是沒有掛載/未安裝 的情況,輸出"sdcard不存在或未掛載
                                            Toast.makeText(mContext, "sdcard不存在或未掛載", Toast.LENGTH_SHORT).show(); return ;}
                        
                                             
                         //需要判斷sdcard剩余/可用空間 ,SDcard卡是否有足夠的空間存貯某個文件的數據 
                                 //獲取 sdcard卡的 目錄     把目錄作為文 件對象,
                                         File  sdcard_filedir = Environment.getExternalStorageDirectory();
                                         //獲取sdcard卡下的文件目錄 對象 還剩的空間大小(long類型)
                                             long usableSpace =sdcard_filedir.getUsableSpace();
                                              //獲取sdcard卡下的文件目錄 對象 總的空間大小(long類型)
                                             long totalSpace = sdcard_filedir.getTotalSpace();//
                                             
                                             //    可用的內存大小 usableSpace是long 類型 的,看不懂。所以還要把long 類型 的usableSpace轉成String字符串類型的內存大小, 
                             //安卓提供了一個類Formatter     將一個long類型的文件大小  轉換成    成用戶可以看懂的M(兆),G   String類型的文件大小
                                        // String formatFileSize( Context context, usableSpace); 
                 //context---上下文 這里用  mContext      usableSpace----long類型的文件大小對象
                               //long類型還剩 空間大小---->String類型還剩 空間大小           
                           String usableSpace_str = Formatter.formatFileSize(mContext, usableSpace);
                         //long類型總空間大小---->String類型總 空間大小           
                           String totalSpace_str = Formatter.formatFileSize(mContext, totalSpace);
                                             
                                             
                                              //對還剩的 空間大小usableSpace_str 進行判斷,能不能下電影(200M的電影)
                                             if(usableSpace < 1024 * 1024 * 200){//如果剩余空間(usableSpace未轉化的 )小于200M, 輸出內存不夠,無法下載
             Toast.makeText(mContext, "sdcard的剩余空間為:"+usableSpace_str+"內存不足,無法滿足下載;",Toast.LENGTH_SHORT).show();  
             Toast.makeText(mContext, "sdcard的總空間為:"+totalSpace_str+"內存不足,無法滿足下載;",Toast.LENGTH_SHORT).show();  
                                      
                                               
                                             }

                 如何保存? 另建個類UserInfoUtil調 boolean saveUserInfo()方法進行保存
                     返回 true 保存成功  輸出 Toast.makeText(mContext, "用戶名或密碼保存成功", Toast.LENGTH_SHORT).show() ;
                                 返回 false 保存失敗 輸出  Toast.makeText(mContext, "用戶名或密碼保存失敗", Toast.LENGTH_SHORT).show() ;
                 
              如果不需要記住用戶名密碼(isrem=false), 直接輸出  Toast.makeText(mContext, "用戶名或密碼無需保存", Toast.LENGTH_SHORT).show() ;

f.回顯用戶名密碼  顯示在登陸界面
         1首先獲取 字符串用戶名和密碼 
       調用 UserInfoUtil類的  Map getUserInfo()方法 返回一個MAP集合, 通過鍵獲取值,這個值就是我們需要的字符串用戶名和密碼
      
     2.把獲取的字符串用戶名和密碼 設置/添加 到 文本內容里。 
          通過文本框對象操作
             文本框對象.setText(設置添加的字符串值);
              et_username.setText(username);
                3.回顯到登陸界面
        復選框對象Checked.setChecked(true)   
       cb_rem.setChecked(true); //setChecked(flag) 設置復選框為選中狀態,用戶名和密碼回顯到界面
    
   注意:另外需要建立一個類 UserInfoUtil 有兩個方法

          1.用來保存用戶名和密碼 的方法 
        boolean saveUserInfo(Context context,String username,String password)
        如何保存用戶名和密碼?------核心----通過輸出流將字符串用戶名和密碼寫到私有文件里

              1.1建立私有文件對象
           File file = new File(context.getFilesDir().getPath(),"userInfo.txt");
           1.2 建立個輸出流對象,把用戶名和密碼 寫到私有文件里
              FileOutputStream fos = new FileOutputStream(file);
               fos.write(  “字符串用戶名和密碼”.getBytes());

             2.獲取用戶名和密碼的方法  
     static Map<String,String> getUserInfo(Context context)

如何獲取用戶名和密碼?------核心----通過輸入流 把存在私有文件里的用戶名和密碼讀取出來,存在map集合里,在獲取,設置/添加到文本框,再回顯

       2.1 把用戶名和密碼從私有文件里讀取出來
            File file = new File(context.getFilesDir().getPath(),"userInfo.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 
         String line = br.readLine();
                2.2 把讀取的字符串(用戶名和密碼)分割,作為值存儲到map集合里 
     HashMap<String ,String> hashmap = new HashMap<String,String>();
                  hashmap.put("username", username);
                  hashmap.put("password", password);

                 2.3  通過鍵獲取用戶名值和密碼值 回到 第f步驟 

五 .文件的權限概念 (了解)

五一: Context context 上下文類 -------重要的類 -----提供了文件權限 的方法

  1. FileInputStream openFileInput( filename,); 獲取輸入流不需要模式
    filename-----私有目錄下的文件名,帶后綴名 不包含路徑

    返回一個輸入流對象,讀取一個私有目錄的私有文件的數據 (私有文件目錄 /data/data/packagename/files/userinfoi.txt)
    FileInputStream fileInputStream = context.openFileInput("userinfo.txt");

  2. FileOutputStream openFileOutput(filename, Context.MODE_PRIVATE);
    filename-----私有目錄下的文件名,不包含路徑
    mode-----對私有文件的操作模式 私有,追加,全局讀,全局寫模式
    Context.MODE_PRIVATE 或0:私有模式 只有當前運用程序才 能讀寫私有文件
    Context.MODE_APPEND :追加模式 往私有文件里追加添加/寫入數據
    Context.MODE_WORLD READABLE/WRITABLE 全局模式 別人也 可讀/寫私有文件

    通過context對象得到私有目錄下一個文件寫入流 ,往文件里輸入數據
    FileOutputStream fileOutputStream = context.openFileOutput("userinfo.txt", Context.MODE_PRIVATE);

案例 :QQ登陸案列,只是在工具包com.itheima.login.util 的類UserInfoUtil里做改進

//建立個方法, 用來保存用戶名和密碼 

public static boolean saveUserInfo(Context context,String username,String password) throws IOException {
try {
//把用戶名和密碼封裝成成字符串
String userInfo =username+"##"+password;

//得到私有目錄下一個私有文件寫入流,往私有文件里寫數據。
//name : 私有目錄文件的名稱 mode: 文件的操作模式, 私有,追加,全局讀,全局寫
FileOutputStream fos = context.openFileOutput("userInfo.txt",context.MODE_PRIVATE);
fos.write( userInfo.getBytes());//把字符串數據寫入到輸出流的私有文件里去
fos.close();return true ;}

catch (FileNotFoundException e) { e.printStackTrace();}

return false;}

//建立個方法 getUserInfo() 獲取用戶名和密碼 //回顯到登陸界面
public static Map<String,String> getUserInfo(Context context) throws IOException{

     // 通過context對象獲取一個私有目錄的文件讀取流,讀取私有文件的數據,不需要模式
    //  FileInputSream   context.openFileInput(name)   name---要讀取的私有文件名
         FileInputStream  fis=      context.openFileInput("userInfo.txt");
       BufferedReader br = new BufferedReader(new InputStreamReader( fis));//高效封裝  fis輸入流
         
         
        //讀取一行字符串,包含用戶名和密碼, 需要獲取用戶名和密碼子字符串
           String line = br.readLine();
            String[] strArr =  line.split( "##");
          //獲取解析 用戶名和密碼字符串
              String username= strArr[0];
               String password =strArr[1];
               
          //建立個hashiap集合, 把 獲取的username和 password最為值存貯到集合里去
             HashMap<String ,String> hashmap = new HashMap<String,String>();
                  hashmap.put("username", username);
                  hashmap.put("password", password);
               return null;   
}

}

五二:畫圖解釋------------------- 文件的權限

第1位 第2~4位 第5~7位 第8~10位
本人 本人的組 外人
rwx rw- r--

linux下一個文件的權限由10位標示:
1位:文件的類型,d:代表文件夾 l:代表快捷方式,另一個文件夾,指向 -:代表文件類型

2-4: 該文件所屬用戶(個人) 對本文件的訪問權限,可讀寫可執行本文件,即rwx :
5-7:該文件所屬用戶組(個人所在的組集體) 對次私有文件的訪問權限 ,可讀寫,不可執行操作文件 即rw-
8-10:其他用戶(外來的) 對該文件的訪問權限。只能讀,不能寫,不能執行 即R--

注意 :如果 是 r w x 字母就用1標示, 是-用0標示,轉換成用二進制標示,再轉換成十六進制,
是為了使用linux下的 chmod 指令對私有文件進行賦權限修改。
DOS ---> # chmod 要成為的權限(十進制) 修改的私有文件名

 第1位 第2~4位  第5~7位  第8~10位
        本人    本人的組   外人 
        rwx      rw-       r--
        111      110       100   (二進制)
 7       6        4    (十六進制)

案例 :將私有文件append.txt的權限由-rw-rw---- 改變為-rwxrw-r--模式

 --> adb shell
  進入私有文件目錄
 --> root@android:/ # cd data/data/com.itheima.filePermission

       +ls -l    查看當前設備的目錄結構
 -->root@android:/data/data/com.itheima.filePermission # ls -l
 
   drwxrwx--x u0_a48   u0_a48            2015-08-31 02:04 cache
    drwxrwx--x u0_a48   u0_a48            2015-08-31 02:04 files
    drwxr-xr-x system   system            2015-08-31 02:04 lib

進入文件 files的目錄
----> root@android:/data/data/com.itheima.filePermission # cd files
進入文件 files的目錄結構
--->root@android:/data/data/com.itheima.filePermission/files # ls -l

        -rw-rw---- u0_a48   u0_a48         18 2015-08-31 02:04 append.txt
        -rw-rw---- u0_a48   u0_a48         18 2015-08-31 02:04 private.txt
        -rw-rw-r-- u0_a48   u0_a48         18 2015-08-31 02:04 read.txt
        -rw-rw--w- u0_a48   u0_a48         18 2015-08-31 02:04 write.txt      
  使用 linux的指令 chmod 更改私有文件的權限
    輸入 # chmod  要成為的權限(十進制)   修改的私有文件
 ---> # chmod 764 append.txt 
  ---> # ls -l

-rwxrw-r-- u0_a48 u0_a48 18 2015-08-31 02:04 append.txt (權限發生了改變-rw-rw----為-rwxrw-r--)
-rw-rw---- u0_a48 u0_a48 18 2015-08-31 02:04 private.txt
-rw-rw-r-- u0_a48 u0_a48 18 2015-08-31 02:04 read.txt
-rw-rw--w- u0_a48 u0_a48 18 2015-08-31 02:04 write.txt


六 SharedPreferences類 (重點) -----用來存儲 (標記性,設置信息)數據

六一:干嘛的 ?
通過sharedPreferences對象把數據存儲到 xml文件里。
------- 系統會自動生成XML文件,把 你輸入的數據 保存在 xml文件 中

六二:sharedPreferences對象的運用:
------- 一般用來存放一些標記性的數據,一些設置信息。
標記性的數據存儲: 當你第一次注冊微信時, 微信的運用程序 會為你 保存已經注冊的信息數據(用戶名和密碼),以后當你再次
登陸微信時,微信的運用程序會匹配 你以前注冊保存的數據信息,匹配成功,即可直接登陸進入界面

設置信息數據的存儲:  手機運用程序軟件都會有 設置項,當你對運用程序進行各種設置時,運用程序會把你設置的數據信息
   保存(保存在數據庫,sharedPreferences,文件里,不能存在內存中)起來,當你再次使用 手機運用程序時,會按照你的設置要求來執行 

六三: -------使用sharedPreferences存儲數據(用戶名和密碼),(存貯在系統自動生成的xml文件里)

1.通過context對象 獲取 SharedPreferences spfs對象
// context類的方法 sharedPreferences getSharedPreferences( String name, Mode mode)
// name:sharedpreference的私有文件名(不許擴展名) mode:對私有文件的操作模式 context的常量
SharedPreferences spfs=context.getSharedPreferences("userInfo",context.MODE_PRIVATE);

2.通過 SharedPreferences spfs對象獲取一個Editor editor編輯器對象
Editor editor = spfs.edit();

3.往Editor editor編輯器對象中添加(鍵值對)數據 --------putString(key.value);
editor.putString("username",username);
editor.putString("password",password);

//4.通過Editor editor對象 提交(填寫的你鍵值對)數據
editor.commit();

--------使用sharedPreferences的方法 讀取/獲取(保存在XML里的)數據

//1.通過context對象 獲取 SharedPreferences spfs對象
SharedPreferences spfs= context.getSharedPreferences("userInfo.txt",context.MODE_PRIVATE);

2.通過sharedPreferencespfs spfs 對象,獲取存放(在Edittor對象里)的數據
// getString(key,value) //key:存放數據時的key defValue: 默認值,根據業務需求來寫 可能為空,
String username = spfs.getString("username", "");
String password = spfs.getString("password", "");

六四: 通過PreferenceManager類的getDefaultSharedPreferences(context)方法
也能獲取SharedPreferences對象,只需傳入一個context參數 更簡單

SharedPreferences spfs=PreferenceManager.getDefaultSharedPreferences(context);


七 生成xml的2種方式
xml文件可以存儲數據,可以傳輸數據 現在xml用的少都被替代啦

開發中 json 用于傳輸數據
       數據庫用于存儲數據

1.寫布局----activity_main.xml
備份按鈕
恢復按鈕

方法一: 方法一 生成xml,并把數據存儲在xml文件里
2.業務邏輯
a.將手機短信數據備份/保存到XML文件
1.將短信數據封裝/保存 到List listBean集合中
2.再將list集合中的數據 保存/寫到xml文件中。

b.將XML文件里數據恢復到手機
    1.獲取/讀取/解析xml文件中短信數據,  再把讀取的數據封裝到list集合中

    2.將解析獲取的數據打印輸出。

方法二: 使用 XmlSerializer序列化/解析xml文件 ---生成XML文件方法二 (****模板代碼重點)
------------ 使用XmlSerializer對象將數據序列化為xml格式,將獲取的數據存貯到xml文件里去

一: 在MainActivity 類中

public class MainActivity extends Activity implements OnClickListener  {

              //定義個成員變量
               private Context mcontext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
       
   mcontext =this; 
 
 ////1.找到兩個控件按鈕對象  - -- 備份按鈕    恢復按鈕 
   Button bt_backup= (Button) findViewById(R.id.bt_backup);
   Button bt_restore= (Button) findViewById(R.id.bt_restore);
   
 //2.設置 兩個按鈕點 擊事件監聽接口 
   //---- setOnClickListener (View.OnClickListener l)   參數是個接口,這里傳入this

      bt_backup.setOnClickListener(this);
      bt_restore.setOnClickListener(this);
}
//重寫接口OnClickListener的onClick(View v)方法

public void onClick(View v) {
 //View 類的 int getId ()  方法,獲取控件的id
 //獲取空間按鈕的id
 int id = v.getId();
switch (id) {
//如果選擇的id 是 備份控件按鈕對象的id ,就執行備份按鈕點擊事件語句功能,
//另單獨定義一個類SmsUtils,封裝一個靜態方法backupSms()  具備備份短信的功能  
case  R.id.bt_backup:
 
    // mcontext   指上下文  
  //  boolean  SmsUtils.backupSms( mcontext); 返回真假   為true 就輸出短信備份成功
    
try {
    if( SmsUtils.backupSms( mcontext)){
           Toast.makeText(mcontext, "備份短信成功", Toast.LENGTH_SHORT).show();   
       }else{ //否則,false 短信備份失敗
            Toast.makeText(mcontext, "備份短信失敗", Toast.LENGTH_SHORT).show();  
            }
} catch (Exception e) {    e.printStackTrace();}

break;

case R.id.bt_restore:
//如果選擇的id 是 恢復控件按鈕對象的id ,就執行恢復按鈕點擊事件語句 
 Toast.makeText(mcontext, "恢復短信成功 ", Toast.LENGTH_SHORT);
 break;

default:
    break;
}
}

}

二: 另外還需要一個類------SmsUtils------封裝一個方法backupSms(Context context)使用XmlSerializer序列化xml文件

public class SmsUtils {
 // 使用 XmlSerializer序列化xml文件
public static boolean backupSms(Context context){
     try{  
     //0.從集合中獲取 短信字符串所有數據
    ArrayList<SmsBean> allSms = SmsDao.getAllSms();
       
       //1.通過Xml類 ,獲取 一個XmlSerializer   xs  對象,調用其的各種方法 
 XmlSerializer      xs=   Xml.newSerializer();
 
  //2. 告訴XmlSerializer對象 我要將序列化的數據寫入/存入到那個文件里去。 
// 設置XmlSerializer的一些參數,  比如:設置xml寫入到哪個私有文件中
   /*setOutput (OutputStream os, String encoding) 
     *  os---xml文件寫入流 ----將序列化好的數據通過輸出流  存儲/寫入  到那個xml文件里去
    *      ----- 輸出流對象:os =  context.openFileOutput("backupsms.xml",context.MODE_PRIVATE);
     *                                     backupsms.xml:用來存儲序列化后的數據
     *    encoding---- 流 的編碼表--utf-8 */
   xs.setOutput( context.openFileOutput("backupsms.xml",context.MODE_PRIVATE), "utf-8");
 //  3.序列化一個xml的聲明頭    <?xml version='1.0' encoding ='utf-8' standlone='yes' ?>
       // -----startDocument(String encoding, Boolean standalone)  
          //encoding---與XML對應 的編碼 utf-8       standalone  是否獨立 一般 true
     xs.startDocument("utf-8", true);
           
//4.序列化xml的一個根節點的開始標簽/節點<Smss> 
    /* startTag(String namespace, String name)
     *namespace:命名空間----這里為null
     *      name: 開始標簽的名稱---這里是Smss
     *  */      
               xs.startTag(null, "Smss");
          
 
//5.循環遍歷list集合序列化一條條短信 //步驟0的集合 allSms
         for(SmsBean smsBean :allSms){
               //獲取開始標簽----<Sms>
                xs.startTag(null, "Sms");
            
                
               /*attribute(String namespace, String name, String value)   自定義寫一個XML標簽的屬性
                *  */   
             //namespace = null   name:標簽的屬性的名稱   value:屬性值
                xs.attribute(null, "id", smsBean.id+"");
                 
                  //獲取開始標簽 namespace=null 表簽名---"num"
                     xs.startTag(null,"num");
                     
                      //獲取標簽<num id ="1">.......</num>的中間文本內容
                       xs.text(smsBean.num);
                     
                     //獲取結束標簽 namespace=null 表簽名---"num"
                     xs.endTag(null,"num");
                      
                      //獲取標簽<msg>.....</msg>文本內容
                    xs.startTag(null,"msg");
                  xs.text(smsBean.msg);
                   xs.endTag(null,"msg");
                 
                   //獲取標簽<data>.....</tata>文本內容
                 xs.startTag(null,"date");
                       xs.text(smsBean.date);
                  xs.endTag(null,"date");
                     
               //獲取結束標簽----</Sms>
                xs.endTag(null, "Sms"); 
              
         }           
                
                  
 
//6.序列化一個根節點的 結束節點  </Smss>
       xs.endTag(null, "Smss");
//7.將xml的所有內容 寫入到文件中,完成xml的序列化
     xs.endDocument();    
    return true;    
    }catch (Exception e) {e.printStackTrace();}
       
 return false;
}  

}

三:還需要一個SmsDao類----定義了一個方法getAllSms()------獲取所有的短信的字段數據內容

public class SmsDao {

//定義了一個getAllSms()方法,返回一個集合ArrayList,
//SmsBean是個bean類,封裝了短信的各個字段
public static  ArrayList<SmsBean>  getAllSms() {
      
 //建立個集合對象 
ArrayList<SmsBean>  arrayList = new ArrayList<SmsBean>();
        
  //建立 smsBean1  對象,初始化各個短信類 的字段        作為元素 添加到 集合里
SmsBean smsBean1 = new SmsBean();
smsBean1.id = 1;  
smsBean1.num = "110";
smsBean1.msg = "來警局做個筆錄";
smsBean1.date = "2015-08-29";
arrayList.add(smsBean1);

  //建立 smsBean2  對象,初始化 各個短信類的字段        作為元素 添加到 集合里
SmsBean smsBean2 = new SmsBean();
smsBean2.id = 2;
smsBean2.num = "120";
smsBean2.msg = "最近咋樣";
smsBean2.date = "2015-08-29";
arrayList.add(smsBean2);

  //建立 smsBean3  對象,初始化 各個短信類的字段        作為元素 添加到 集合里
SmsBean smsBean3 = new SmsBean();
smsBean3.id = 3;
smsBean3.num = "119";
smsBean3.msg = "火滅了嗎";
smsBean3.date = "2015-08-29";
arrayList.add(smsBean3);


      //創建個
return arrayList;

}

四:還需要一個類Bean類---- SmsBean 類 封裝短信的各種字段

public class SmsBean {
      //封裝了短信的各種字段
    public String num ;
    public String msg;
    public String date;
    public int id;
}

XmlSerializer序列化xml文件所涉及到的方法
接口 XmlSerializer里的抽象方法

attribute(String namespace, String name, String value)   獲取一個XML標簽的屬性
命名空間  namespace = null    name:標簽的屬性的名稱    value:屬性值
xs.attribute(null, "id", smsBean.id+"");

endDocument()    完成寫入到XML里是數據 ,完成序列化
setOutput(Writer writer)  設置一個字符寫入流,把字符數據序列化到/寫入到某個文件里去
setOutput(OutputStream os, String encoding)  設置一個字節寫入流,把字節數據序列化到/寫入到某個文件里去
startDocument(String encoding, Boolean standalone)  寫一個XML文件的聲明頭 
 即 <?xml declaration with encoding>

//encoding---與XML對應 的編碼 utf-8       standalone  是否獨立 一般 true
 xs.startDocument("utf-8", true);                            

startTag(String namespace, String name)  生成開始標簽 
namespace:命名空間----這里為null  name: 開始標簽的名稱---這里是Smss
<Sms id="1">   </Sms>   
xs.startTag(null, "Smss"); 

endTag(String namespace, String name)    namespace = null  name--結束標簽名
 獲取一個結束標簽  只要是結束標簽都可生成 </smss>
xs.endTag(null, "smss");     
text(String text)   生成XML的標簽里文本內容
android.util.Xml 類
static XmlSerializer     newSerializer() 生成一個XmlSerializer序列化對象 
static XmlPullParser     newPullParser()    生成一個XmlPullParser序列化對象

八 .使用pull解析/獲取 xml格式的數據

xml的解析

dom解析:基于加載全文的解析方式
sax解析:基于事件的逐行解析方式

pull解析:同sax

  • PULL解析 逐行解析---
    1 獲取每行的事件類型,進行解析
  1. 再獲取下一行的事件類型
    3.逐行遍歷所有的行數據,判斷文檔沒有結束的條件下
    //1.獲取到一個xml解析器
    XmlPullParser parser = Xml.newPullParser();
    //2.設置解析器的初始化參數
     FileInputStream inputStream = new FileInputStream(file);
    parser.setInput(inputStream, "utf-8");
    //3.解析xml文件
    XmlPullParser.START_TAG 開始節點
    XmlPullParser.END_TAG 結束節點
    parser.nextText(); <tag>foo</tag> 取兩個節點中的foo文本
    parser.getName(); 獲取當前節點的名稱
    parser.next(); 讓解析器解析下一個節點.

XmlPullParser 接口的 的方法

void     setInput(Reader in)
setInput(InputStream inputStream, String inputEncoding) 設置一個XML文件的讀取流
要 解析/獲取 輸入流對象中 的 XML文件里的數據、
//從backupsms2.xml文件中讀取數據
xpp.setInput(context.openFileInput("backupsms2.xml"),  "utf-8");
setInput(InputStream inputStream, String inputEncoding) 設置一個XML文件的寫入流
int     getEventType()  獲取事件的類型,
當事件類型不為 結束文檔標簽時,就可遍歷事件類型里的數據
事件類型等于 結束文檔標簽時 ,遍歷 結束
public abstract int next ()獲取下一行的 事件的類型,
xpp.next ()
String  nextText()  獲取標簽事件的文本內容
String   getName()  獲取標簽名 //獲取開始標簽名  //獲取結束標簽名
String  getAttributeValue(String namespace, String name) 通過標簽的屬性名name,來獲取標簽的屬性值 

工作空間 namespace=null
name---屬性的名,標簽的屬性名稱

XmlPullParser 接口的 的常量

XmlPullParser.END_DOCUMENT 表示文檔的結束
XmlPullParser.START_TAG 表示開始標簽
XmlPullParser.END_TAG 表示結束標簽

一。 文件存儲

  1. 應用程序可以把數據存儲在自己私有的文件夾里面.只能存儲在自己建立的文件夾里.(書寫是不要寫錯了,否則報異常)
    DDMS-->File Explorer /data/data/自建的包名/自建的文件名(系統也可以幫你建)
    DDMS-->File Explorer /data/data/com.itheima.qqlogin(包名)/ info.txt...
    不能存貯在別的文件夾里,否則也是異常找不到文件
//在andorid直接這樣建立文件對象錯誤報異常, file can not find ,手機會把文件對象存儲在內部存儲根目錄里,且只讀,不能往文件里寫入
              //存入數據的   把數據存儲在自己私有的文件夾里面
            //  File file = new File("info.txt");
File file = new File("data/data/com.itheima.qqlogin/info.txt");
             //建立個輸出流對象,把輸入的號碼和密碼寫入/保存到 文件info.txt里
FileOutputStream fos = new FileOutputStream(file);
                //把qq號碼和密碼拼接為個字符串str存儲進文件里去
                   String str =qq+"#"+pwd;
fos.write(str.getBytes()); //andorid的數據  QQ號碼和密碼  就寫入到了文件info.txt里
  1. 獲取在保存在文件info.txt里 的數據(號碼和密碼),并把數據(號碼和密碼)回顯到手機登陸界面上

    File file = new File("data/data/com.itheima.qqlogin/info.txt");

    if(file.exists()&&file.length()>0){
    try {
    BufferedReader br =
    new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    //讀取字符串數據 740701&&1234
    String infoline = br.readLine();
    //把字符串分割 split = "#"
    String[] strArr =infoline.split("#");
    //qq號碼是
    String qqnum = strArr[0];
    //密碼是
    String pwd = strArr[1];
    //把字符串qq號碼和密碼 顯示到 登陸的界面上
    et_qq.setText(qqnum);
    et_password.setText(pwd);
    } catch (Exception e) {e.printStackTrace();}

    }

3.硬代碼不實用

File file = new File("data/data/com.itheima.qqlogin/info.txt"); //硬代碼不適用
//選個活代碼  File file = new File(dir,name);
//dir  文件所在目錄     this.getFilesDir()      獲取文件的所在目錄絕對路徑   this 指MainActivity 也指上下文
this.getFileDir() ===  /data/data/<當前應用程序自建包名>/ files文件名
//name   文件名
File file = new File(this.getFilesDir(),"info.txt");    

EG:

File file = new File(this.getFilesDir(),"info.txt");
//建立個輸出流對象,把輸入的號碼和密碼寫入/保存到 文件info.txt里
FileOutputStream fos = new FileOutputStream(file);
//把qq號碼和密碼拼接為個字符串str存儲進文件里去
 String str =qq+"#"+pwd;
fos.write(str.getBytes());
fos.close();
//若無異常,打印輸出數據就保存成功
Toast.makeText(this, "數據保存成功" , 0).show();
//若異常數據保存失敗
e.printStackTrace();
Toast.makeText(this, "數據包存失敗", 0).show();

this===上下文 復雜功能很多

應用程序運行的環境.
this.getAssets() 獲取assets包里資源文件夾
this.getResources() 獲取資源目錄 res
this.getResources().getDrawable(int id ) 獲取res/drawable 下的圖片
this.getResources().getDtring() 獲取字符串

  • this.getFileDir() ---> 獲取文件的所在目錄絕對路徑 (即 路徑 data/data/包名/files)
  •                      把手機的重要信息數據保(用戶名,密碼,參數)存保存到files配置文件里。當要刪除這些文件里的數據時,系統會給出提示:你確定要刪除配置文件嗎?
    
  • this.getCacheDir() ---> 獲取緩存目錄 (即data/data/包名/文件名cache)
  •                           緩存目錄,清除文件里的數據時,系統沒有提示
    
  •                             當手機的內存不足時,Cache會自動刪除 此目錄下的文件,釋放空間
                            從網上下載的臨時不重要的數據可以保存在這個this.getCacheDir() 緩存目錄下
    

andorid 的數據(字符串,圖片)存儲到------>外存儲卡/sd卡上

1.如何打開權限的所在地
AndroidManifest.xml--- Permissions--點擊Add 選擇 uses Permission(使用權限)
----android.permission.WRITE_EXTERNAL_STORAGE 選擇允許寫入外來存貯空間
-----android.permission.READ_EXTERNAL_STORAGE 選擇允許讀取外來的文件(機密文件,艷照)數據到手機界面

setting ---開發者選項---選擇對sd卡進行讀寫保護 :就是說要想讀取外來SD卡的數據,需要得到請求才可以

  1. 應用程序可以把數據存儲在外存儲卡,sd卡(聲明權限)

    File file = new File("/mnt/sdcard/info.txt"); //SD卡的路徑死路徑,不可取

谷歌提供了個api方法 獲取外部SD存儲卡的目錄路徑
Environment.getExternalStorageDirectory() /獲取外部SD存儲卡的目錄路徑

File file = new File(Environment.getExternalStorageDirectory(),"info.txt");

  1. 使用外來的SD卡。 先要對檢查sd卡是否可用, 檢查sd卡的剩余空間.

-------------判斷檢查sd卡是否可用
if(! Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ){
Toast.makeText(this, "sd卡不可用,請檢查sd卡的狀態", 0).show();
return;} //輸出SD卡不卡用,結束
else{Toast.makeText(this, "sd卡 可用, ", 0).show();} //輸出SD卡可用

-------------檢查sd卡的可用空間.
long size = Environment.getExternalStorageDirectory().getUsableSpace();
String freesplace = Formatter.formatFileSize(this, size);
Toast.makeText(this, "外來設備sd卡可用空間是 "+freesplace, 0).show(); //輸出外來設備sd卡可用空間是31.48M

//檢查外來的SD存儲卡,是否存在,是否可用
//獲取外存儲設備(SD卡)的狀態(是否可用,內存是否夠大)  
                 
try {
// 檢查sd是否存在,是否可用.
//String  getExternalStorageState()   獲取外存儲設備(SD卡)的狀態(可讀可寫,不可讀不可寫)
//MEDIA_MOUNTED   當前的SD卡可讀可寫

//如果當前的SD卡為不可讀寫的卡
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

    //就輸出語句  sd卡不可用,請檢查sd卡的狀態    //this 上下文
    //android 的輸出語句  Toast.makeText(this, "輸出語句", 0).show();
    Toast.makeText(this, "sd卡不可用,請檢查sd卡的狀態", 0).show();
    return;
    
    // 檢查sd卡的可用空間.
    //Environment.getExternalStorageDirectory()  /獲取外部SD存儲卡的目錄路徑
    //  getTotalSpace()  獲取 SD卡 的總空間
    // long  getUsableSpace()  獲取 SD卡 的可用空間  == long getFreeSpace() 
    long size =     Environment.getExternalStorageDirectory().getUsableSpace();
    
    //Formatter.formatFileSize(Context contsxt ,long number) 把long類型的可用空間單位轉成 String類型的可用空間單位
    String freesplace =  Formatter.formatFileSize(this, size);
    Toast.makeText(this, "外來設備sd卡可用空間是 "+freesplace, 0).show();  //輸出外來設備sd卡可用空間是31.48M
}

}
//手機數據保存在外來SD卡上
File file = new File(Environment.getExternalStorageDirectory(),"info.txt");
  1. 參數 sharedperference
    使用步驟:

    1. 獲取到 sp = this.getSharedPreferences("config", 0);
    2. 獲取編輯器 Editor editor = sp.edit();
    3. editor.putString(key,value) putInt() putDouble()
    4. editor.commit();
    5. 獲取數據 sp.getString(key,dafvalue); sp.getInt()...
  2. SD卡的不同稱呼

華為手機: stroage01/emolater01

文件權限

  • 應用程序在data/data/自己包名/目錄下創建的文件 默認都是私有的, 別的應用程序是不可以訪問的(不能讀取這個文件 里的數據,也不能往這個文件里寫入數據)

一 般 的手機的文件默認是私有的,程序員不能讀取文件的數據,也不能寫入數據到文件里。那咋辦啦?
把手機給root就可以啦,程序員就可以操作這個私有文件啦,但是手機不安全啦,廠商也不保修啦

class MainActivity extends Activity
//讀取外來私有 文件   結果讀取文件失敗
public void read(View view ){
    try{
        FileInputStream fis = new FileInputStream(file);
        BufferedReader br = new  BufferedReader(new InputStreamReader(fis));
        String line= br.readLine();
        Toast.makeText(this, line, 0).show();  //讀取成功 輸出讀取的內容
    } catch(Exception e){ //如若讀取失敗 拋出異常,  
        e.printStackTrace();
        Toast.makeText(this, "讀取文件失敗", 0).show();} //讀取文件失敗
}

// 寫數據到 私有 文件 結果寫入數據到文件里失敗

public void write(View view ){
    try{ //建立個文件對象file,   把手機的數據寫入到這個文件里 
        File file = new File("/data/data/com.itheima.filemode/files/private.txt");     
        FileOutputStream fos =new FileOutputStream(file);
        fos.write(" 把手機數據寫入到文件private.txt里".getBytes());
        fos.close();
        Toast.makeText(this, "數據寫入到文件里成功",0);
        //接下來就要讀取這個文件里的數據,把讀取的數據顯示到登陸界面
        FileInputStream fis = new FileInputStream(file);
        BufferedReader br = new  BufferedReader(new InputStreamReader(fis));
        String line= br.readLine(); //讀取文件private.txt里的數據
        Toast.makeText(this, line, 0).show();  //輸出讀取的內容
      } catch(Exception e){ //如若讀取失敗,拋出異常,
           e.printStackTrace();
           Toast.makeText(this, "讀取文件private.txt數據失敗", 0).show();  //寫入數據失敗
      }
}

如何獲取一個可讀可寫的公開的文件

  FileOutputStream openFileOutput(String name,int mode) 
  *   name 即文件名
  *  mode=0 /MODE PRIVATE   默認操作 ,私有的 
  *    mode =MODE WORLD READABLE  和 MODE WORLD WRITE   文件可讀可寫模式,
  FileOutputStream openFileOutput ("public.txt")

//生成一個可讀可寫的公開的文件 公開權限的文件

public void getPublicFile(View view){
     //如何獲取一個可讀可寫的公開的文件
     /*FileOutputStream openFileOutput(String name,int mode) 
      *   name 即文件名
      *  mode=0 /MODE PRIVATE   默認操作  
      *    mode =MODE WORLD READABLE  和 MODE WORLD WRITE   文件可讀可寫模式
      *      */
    try{
        FileOutputStream fos =  openFileOutput("public.txt",Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
         fos.write("public".getBytes());
         fos.write("寫數據到public文件里成功".getBytes());
         fos.close();
    } catch (Exception e) {
        e.printStackTrace();
         Toast.makeText(this, "寫入數據到文件失敗", 0);
    }
}

//讀取外來有公文件 結果讀取成功
class MainActivity extends Activity
public void read(View view ){
try{
File file = new File("/data/data/com.itheima.filemode/files/public.txt");
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line= br.readLine();
Toast.makeText(this, line, 0).show(); //讀取成功 輸出讀取的內容
} catch(Exception e){ //如若讀取失敗 拋出異常,
e.printStackTrace();
Toast.makeText(this, "讀取文件失敗", 0).show();} //讀取文件失敗
}

// 寫數據到 公有文件, 結果寫入數據到文件成功

public void write(View view ){
    try{ //建立個文件對象file,   把手機的數據寫入到這個文件里 
        File file = new File("/data/data/com.itheima.filemode/files/public.txt");     
        FileOutputStream fos =new FileOutputStream(file);
        fos.write(" 把手機數據寫入到文件public.txt里".getBytes());
        fos.close();
        Toast.makeText(this, "數據寫入到文件里成功",0);
        //接下來就要讀取這個文件里的數據,把讀取的數據顯示到登陸界面
        FileInputStream fis = new FileInputStream(file);
        BufferedReader br = new  BufferedReader(new InputStreamReader(fis));
        String line= br.readLine(); //讀取文件private.txt里的數據
        Toast.makeText(this, line, 0).show();  //輸出讀取的內容
    } catch(Exception e){ //如若讀取失敗,拋出異常,
        e.printStackTrace();
        Toast.makeText(this, "讀取文件public.txt數據失敗", 0).show();  //寫入數據失敗
                      }
}

文件的權限

 permisson(權限)
files                                drwxrwx--x (d代表文件)
私有文件  private.txt                   -rw- --- --- 私有  (- 代表文件)   對自己可讀可寫 對別人不可讀寫      
共有文件   public.txt                    -rw-rw-rw-  公開
只讀文件  readOnly.txt                   - rw-rw-r-- 只讀
只寫文件  writeOnly.txt                   -rw- rw- -w- 只寫 

chmod  change  mode  更改文件訪問的模式 
chmod  change   mode-- 600 
chmod  change    mode-- 600
chmod  change    mode-- 600
chmod  change    mode-- 600

生成xml文件

  • StringBuilder

  • Xml序列化器

      // 1.得到xml文件的序列化器
      XmlSerializer serializer = Xml.newSerializer();
      // 2.指定序列化器的一些初始參數
      File file = new File(getFilesDir(), name + ".xml");
      FileOutputStream os = new FileOutputStream(file);
      serializer.setOutput(os, "utf-8");
      // 3.寫xml文件.
      serializer.startDocument("utf-8", true); 寫開頭
      serializer.endDocument(); 寫結尾
      serializer.startTag(null, "number"); 開始標簽
      serializer.endTag(null, "number"); 結束標簽
      serializer.text() 寫文本標簽
      serializer.attribute(null, name, value) 寫屬性
    

xml的解析

  • SAX

  • DOM & DOM4j

  • PULL解析

      //1.獲取到一個xml解析器
      XmlPullParser parser = Xml.newPullParser();
      //2.設置解析器的初始化參數
      FileInputStream inputStream = new FileInputStream(file);
      parser.setInput(inputStream, "utf-8");
      //3.解析xml文件
      XmlPullParser.START_TAG 開始節點
      XmlPullParser.END_TAG 結束節點
      parser.nextText(); <tag>foo</tag> 取兩個節點中的foo文本
      parser.getName(); 獲取當前節點的名稱
      parser.next(); 讓解析器解析下一個節點.
    

http://www.096.me/api.php?phone=13512345678&mode=xml

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容