美文网首页
Android基础第二天

Android基础第二天

作者: lengol | 来源:发表于2016-02-07 14:04 被阅读269次

    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

    相关文章

      网友评论

          本文标题:Android基础第二天

          本文链接:https://www.haomeiwen.com/subject/oxsykttx.html