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();
}
分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();
}
相关文章推荐
- Androidx学习笔记(12)-- 文件读写操作-在外部存储空间中读写文件
- Android 存储学习之在外部存储中读写文件
- Android入门学习笔记(一)|基础知识|文件数据存储读取|解析XML
- android菜鸟学习笔记17----Android数据存储(一)文件读写
- XML 文件解析 -- MarsChen Android 开发教程学习笔记
- Androidx学习笔记(10)-- 文件读写操作简介
- Android内/外部存储文件读写操作总结
- ANDROID基础学习笔记_3.1_文件权限
- 【Android开发小记--16】assets、raw、内部存储、外部存储——文件的读写
- 2、文件读写、外部存储、Xml备份
- Android学习(15) --在外部存储读写数据相关
- Android 个人学习笔记之--- DOM解析XML文件
- Android简易实战教程--第十五话《在外部存储中读写文件》
- Android 个人学习笔记之--- Pull解析XML文件
- Androidx学习笔记(34)---新闻客户端之获取新闻xml文件并解析
- 学习笔记:android下文件访问权限
- Android 存储学习之在内部存储中读写文件
- Android(java)学习笔记185:xml文件生成
- Android 在外部存储读写文件
- Android学习(14) -- 在内部存储空间中读写文件