您的位置:首页 > 移动开发 > Android开发

android 学习笔记2-logcat 内外部文件的存储 文件权限 xml读写

2016-12-28 23:16 871 查看
1、logcat

    分5个等级,每个等级使用不同颜色

    verbose
debug
info
warn
error

    定义过滤器方便查看

    

    System.out.print输出的日志级别是info,tag是System.out

    Android提供的日志输出api
Log.v(TAG, "hello");
Log.d(TAG, "hello");
Log.i(TAG, "hello");
Log.w(TAG, "hello");
Log.e(TAG, "hello");

        

        

2、在内部存储中写文件

    Ram内存:运行内存,相当于电脑的内存

    Rom内存:内部存储空间,相当于电脑的硬盘

    sd卡:外部存储空间,相当于电脑的移动硬盘

        

    所有安装至手机的应用都会在data/data目录下生成一个包名文件夹,这个文件夹就是内部存储的路径

    应用只能在自己的包名文件夹中读写文件

    例子:

   

        //返回一个File对象,封装的路径是data/data/com.example.test/files

        //File file = new File(getFilesDir(), "info.txt");

        

        //返回一个File对象,封装的路径是data/data/com.example.test/cache

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

        try {

            FileOutputStream fos = new FileOutputStream(file);

            //把账号密码写入本地文件

            fos.write((name + "--" + pass).getBytes());//将字符串转化为字节流写到文件中

            fos.close();

        } catch (Exception e) {

            e.printStackTrace();

        }

        

        

3、在内部存储中读文件

    例子:

        private void readAccount() {

            //读取文件,回显数据,文件info.txt的内容是 test--123

            //File file = new File("data/data/com.example.test/info.txt");  //这个会保存在应用的目录files文件夹下,就算空间不够也不会删除,除非用户自己清理

            File file = new File(getFilesDir(), "info.txt");//这个会保存在应用的目录files文件夹下,就算空间不够也不会删除,除非用户自己清理

            //File file = new File(getCacheDir(), "info.txt");//这个会保存在应用的目录caches文件夹下,如果空间不够就会被清除掉

            if(file.exists()){//判断文件是否存在

                try {

                    FileInputStream fis = new FileInputStream(file);

                    //把字节流转换成字符流

                    BufferedReader br = new BufferedReader(new InputStreamReader(fis));

                    //读取文件中的文本

                    String text = br.readLine();

                    

                    String s[] = text.split("--");

                    

                    //给输入框设置文本

                    et_name.setText(s[0]);

                    et_pass.setText(s[1]);

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }

        

4、Toast显示对话框:

    Toast t = Toast.makeText(this, "登录成功", 0);

    Toast t = Toast.makeText(MainActivity.this, "登录成功", 1);

    

    第一个参数是一个上下文,一个activity也是个上下文

    第三个参数只能是 0 或 1 (0显示3s  , 1显示 5s)

    

    

5、应用中的files文件夹和cache文件夹的区别:

    files文件夹下文件,就算空间不够也不会删除,除非用户自己清理

    caches文件夹下文件,如果空间不够就会被清除掉

    

    在系统管理应用界面的清除缓存,会清除cache文件夹下的东西,清除数据,会清除整个包名目录下的东西

    

6、在外部存储读写数据:

    android 2.2之前,sd卡路径:sdcard

    android 4.3之前,sd卡路径:mnt/sdcard

    android 4.3开始,sd卡路径:storage/sdcard

    

    File file = new File("sdcard/info.txt");

    

    写sd卡需要权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    读sd卡,在4.0之前不需要权限,4.0之后可以设置为需要
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

        

        

    现在很多手机品牌会更改sd卡的路径 ,使用api获得sd卡的真实路径

    Environment.getExternalStorageDirectory()

    

    判断sd卡是否准备就绪

    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))//已挂载上了

    

    其他的读写方式和上面的内部存储一样的

    

    

7、导入android源码分析系统的应用(settings)

    导入eclipse查看有很多的红色警告,是因为系统应用访问的很多的API我们不能访问,所以会提示找不到类,但是我们只需要看怎么实现的,不需要编译。

    

    不能直接import 一个android工程,因为源码是一个android项目,但不是一个eclipse项目

    解决办法:

        在eclipse中 New  -- Other... -- Android -- Android Project from Existing Code

        显示创建了2个项目,我们只选择我们需要的项目

        

        

8、文件访问权限:

    在Android中,每一个应用是一个独立的用户

    drwxrwxrwx

        第1位:d表示文件夹,-表示文件

        第2-4位:rwx,表示这个文件的拥有者用户(owner)对该文件的权限,【例如我这个应用创建了这个文件,这个应用权限就是2-4位的权限】

        r:读

        w:写

        x:执行

        第5-7位:rwx,表示跟文件拥有者用户同组的用户(grouper)对该文件的权限,【默认两个应用不会是一个用户组的,可以手动设置2个应用为同一个用户组,主要是android自己的系统应用设置了,这个场景一般应用比较少】

        第8-10位:rwx,表示其他用户组的用户(other)对该文件的权限 【其他的应用】

    

        

    备注:可以创建一个所有用户都可以访问的文件,但是google现在不推荐这样做,会存在安全漏洞,已经被废弃掉了。建议使用ContentProvider 或BroadcastReviever替代。

        MODE_PRIVATE:-rw-rw----

        MODE_APPEND:-rw-rw----

        MODE_WORLD_WRITEABLE:-rw-rw--w-

        MODE_WORLD_READABLE:-rw-rw-r--

        FileOutputStream fos = openFileOutput("info.txt", MODE_WORLD_READABLE);

        FileOutputStream fos = openFileOutput("info.txt", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE);
fos.write("lalala".getBytes());

    

    

9、使用SharedPreference读写文件,是写到一个xml文件中的,比较适合存储零散的数据

        往SharedPreference里写数据

            //拿到一个SharedPreference对象

            SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);//这个是activity自带的一个API

            //拿到编辑器

            Editor ed = sp.edit();

            //写数据

            ed.putBoolean("name", name);

            ed.commit();

    从SharedPreference里取数据
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
//从SharedPreference里取数据
String name = sp.getBoolean("name", "");

    

10、使用xml文件备份数据-使用StringBuffer拼接。

    我们一般备份短信都是用的xml文件保存,备份数据通常都是备份至sd卡中

    

    可以用StringBuffer拼接字符串,但是容易出错,而且如果字符串里面本来就包含了  <body> 等标签数据,解析的时候就会出现问题。

        a、创建用于存数据的类sms.java

        public class Sms {

            private String body;

            private long date;

            private int type;

            private String address;

            public Sms(String body, long date, int type, String address) {

                super();

                this.body = body;

                this.date = date;

                this.type = type;

                this.address = address;

            }

            public String getBody() {

                return body;

            }

            public void setBody(String body) {

                this.body = body;

            }

            public long getDate() {

                return date;

            }

            public void setDate(long date) {

                this.date = date;

            }

            public int getType() {

                return type;

            }

            public void setType(int type) {

                this.type = type;

            }

            public String getAddress() {

                return address;

            }

            public void setAddress(String address) {

                this.address = address;

            }

            

        }

        

        b、生成数据:

            smsList = new ArrayList<Sms>();用ArrayList保存

            for (int i = 0; i < 10; i++) {

                Sms sms = new Sms("hello" + i, System.currentTimeMillis(), 1, "12345678900");

                smsList.add(sms);

            }

            

        c、将数据写到xml文件中

        StringBuffer sb = new StringBuffer();

            sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");//添加头

            sb.append("<smss>");//添加根节点

            

            for (Sms sms : smsList) {//添加每条短信的标签

                sb.append("<sms>");

                

                sb.append("<body>");

                sb.append(sms.getBody()+"<body>");

                sb.append("</body>");

                

                sb.append("<date>");

                sb.append(sms.getDate());

                sb.append("</date>");

                

                sb.append("<type>");

                sb.append(sms.getType());

                sb.append("</type>");

                

                sb.append("<address>");

                sb.append(sms.getAddress());

                sb.append("</address>");

                

                sb.append("</sms>");

            }

            

            sb.append("</smss>");

            

            File file = new File("sdcard/sms.xml");

            try {

                FileOutputStream fos = new FileOutputStream(file);

                fos.write(sb.toString().getBytes());

            } catch (Exception e) {

                 TODO Auto-generated catch block

                e.printStackTrace();

            }

        d、这样就完成了。

    

11、使用XMl序列化器生成xml文件

        //获取xml序列化器
XmlSerializer xs = Xml.newSerializer();
File file = new File("sdcard/sms2.xml");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
//初始化
//xml文件中什么编码生成
xs.setOutput(fos, "utf-8");
//开始生成xml文件
//生成头结点
xs.startDocument("utf-8", true);//这个编码是xml文件头的utf-8编码

//生成开始标签
xs.startTag(null, "smss");

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

xs.startTag(null, "body");
xs.text(sms.getBody() + "<body>");
xs.endTag(null, "body");

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

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

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

xs.endTag(null, "sms");
}

//生成结束标签
xs.endTag(null, "smss");

//告知序列化器生成xml结束
xs.endDocument();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

        

12、xml文件存好了,现在需要进行解析

        一般都是解析网络中获取的xml,发一个http请求,传回来xml数据

        

        a、获取src文件夹下的文件

            InputStream is = getClassLoader().getResourceAsStream("weather.xml");

        

        b、获取xmlpull解析器,XmlPullParser是一个接口不能new的

            XmlPullParser xp = Xml.newPullParser();

            

        c、初始化
xp.setInput(is, "gbk");//我们一般使用utf-8编码,当时我们window是用gbk的,如果用utf-8会出现乱码

            

        d、是以事件类型作为驱动解析的,读取一行解析一行

            //获取当前节点的事件类型
int type = xp.getEventType();

        e、处理流程

            City city = null;//City是一个用于存储数据的类
while(type != XmlPullParser.END_DOCUMENT){
switch (type) {
case XmlPullParser.START_TAG:
//获取当前节点的名字
if("weather".equals(xp.getName())){
cityList = new ArrayList<City>();//读到根节点,就创建一个ArrayList<City>,用于存储多个城市的天气信息
}
else if("city".equals(xp.getName())){
city = new City();//读到city这个标签,就创建一个City对象,用于当前城市的天气信息
}
else if("name".equals(xp.getName())){
//获取下一个节点的文本
String name = xp.nextText();
city.setName(name);
}
else if("temp".equals(xp.getName())){
//获取下一个节点的文本,把指针移动至当前节点的结束节点
String temp = xp.nextText();
city.setTemp(temp);
}
else if("pm25".equals(xp.getName())){
//获取下一个节点的文本
String pm25 = xp.nextText();
city.setPm25(pm25);
}
break;
case XmlPullParser.END_TAG:
if("city".equals(xp.getName())){
cityList.add(city);
}
break;

}
//把指针移动至下一个节点,并返回该节点的事件类型
type = xp.next();
}

               

    

    

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: