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阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容