2.3.1 存储数据到data目录中

当应用安装到Android后,系统会根据每个应用的包名创建一个/data/data/包名/的文件夹,访问自己包名下的目录是不需要权限的,并且Android已经提供了非常简便的API可以直接去访问该文件夹。

下面以一个案例来演示data目录的使用。

一、需求

如图1-5 所示,在用户将CheckBox选中的前提下点击登录,就将用户名和密码保存在data文件夹中,在用户不勾选CheckBox的前提下点击登录,就不保存用户名和密码,同时删除data文件中的历史数据。

如果数据已经保存到了data目录中,那么下次用户重新启动该界面的时候要求可以将用户名和密码回显到界面。


二、编写布局
【文件1-4】 activity_main.xml

1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2.     xmlns:tools="http://schemas.android.com/tools"
3.     android:layout_width="match_parent"
4.     android:layout_height="match_parent" 
5.     android:orientation="vertical">
6. 
7.     <EditText 
8.         android:id="@+id/et_name"
9.         android:layout_width="match_parent"
10.         android:layout_height="wrap_content"
11.         android:hint="请输入用户名"
12.         />
13.     <EditText 
14.         android:id="@+id/et_pwd"
15.         android:layout_width="match_parent"
16.         android:layout_height="wrap_content"
17.         android:inputType="textPassword"
18.         android:hint="请输入密码"
19.         />
20.     <RelativeLayout 
21.         android:layout_width="match_parent"
22.         android:layout_height="wrap_content"
23.         >
24.         <CheckBox 
25.             android:id="@+id/cb"
26.             android:layout_width="wrap_content"
27.             android:layout_height="wrap_content"
28.             android:text="记住密码"
29.             android:layout_centerVertical="true"
30.             />
31.         <Button 
32.             android:layout_alignParentRight="true"
33.             android:onClick="login"
34.             android:layout_width="wrap_content"
35.             android:layout_height="wrap_content"
36.             android:text="登录"
37.             />
38.         
39.     </RelativeLayout>
40. </LinearLayout>

三、编写代码
【文件1-5】 MainActivity.java

1. package com.itheima.android.save.data;
2. 
3. import java.io.BufferedReader;
4. import java.io.File;
5. import java.io.FileInputStream;
6. import java.io.FileOutputStream;
7. import java.io.InputStreamReader;
8. import android.os.Bundle;
9. import android.app.Activity;
10. import android.text.TextUtils;
11. import android.view.View;
12. import android.widget.CheckBox;
13. import android.widget.EditText;
14. import android.widget.Toast;
15. /**
16.  * 
17.  * @author wzy 2015-10-23 
18.  * 将用户名和密码保存到data目录
19.  *
20.  */
21. public class MainActivity extends Activity {
22. 
23. 	private EditText et_name;
24. 	private EditText et_pwd;
25. 	private CheckBox cb;
26. 
27. 	@Override
28. 	protected void onCreate (Bundle savedInstanceState){
29. 		super.onCreate(savedInstanceState);
30. 		setContentView(R.layout.activity_main);
31. 		//获取控件对象
32. 		et_name = (EditText) findViewById(R.id.et_name);
33. 		et_pwd = (EditText) findViewById(R.id.et_pwd);
34. 		cb = (CheckBox) findViewById(R.id.cb);
35. 		/*
36. 		 * 数据的回显
37. 		 * getFilesDir()方法是父类提供的方法可以直接访问data/data/包名/files目录
38. 		 */
39. 		File file = new File(getFilesDir(), "info.txt");
40. 		//如果文件存在则回显数据
41. 		if (file.exists()) {
42. 			try {
43. 				/*
44. 				 * openFileInput(String)是父类提供的方法,
45. 				 * 可以直接获取data目录下指定文件的的输入流
46. 				 */
47. 				FileInputStream fis = openFileInput("info.txt");
48. 				//将文件输入流转化为缓存流
49. 				BufferedReader bf = new BufferedReader(new InputStreamReader(fis));
50. 				//因为保存时数据只有一行,因此读取一次就可以
51. 				String readLine = bf.readLine();
52. 				bf.close();
53. 				/*
54. 				 * 数据是用户名##密码的形式存储的,
55. 				 * 因此需要根据##对字符串进行切割
56. 				 */
57. 				String[] split = readLine.split("##");
58. 				//给EditText控件设置数据
59. 				et_name.setText(split[0]);
60. 				et_pwd.setText(split[1]);
61. 				//让CheckBox变为勾选状态,默认不勾选
62. 				cb.setChecked(true);
63. 			} catch (Exception e) {
64. 				e.printStackTrace();
65. 			}
66. 		}
67. 	}
68. 
69. 	/*
70. 	 * 给登录按钮绑定的点击事件
71. 	 */
72. 	public void login(View view) {
73. 		//从EditText中获取数据
74. 		String name = et_name.getEditableText().toString().trim();
75. 		String pwd = et_pwd.getText().toString().trim();
76. 		//校验数据
77. 		if (TextUtils.isEmpty(name)||TextUtils.isEmpty(pwd)) {
78. 			/*
79. 			 * 这里使用到了makeText的方法的重载形式,第二个参数是int类型,
80. 			 * 其对应values/strings.xml资源文件中的字符串常量
81. 			 */
82. 			Toast.makeText(this, R.string.info_txt, Toast.LENGTH_SHORT).show();
83. 			return;
84. 		} 
85. 		//获取CheckBox的选中状态
86. 		boolean checked = cb.isChecked();
87. 		//保存数据 name##pwd
88. 		File file = new File(getFilesDir(), "info.txt");
89. 		if (checked) {
90. 			try {
91. 				/*
92. 				 * openFileOutput()方法是父类提供的直接打开data目中中指定文件的输出流,
93. 				 * 输出地址:/data/data/包名/files/info.txt
94. 				 */
95. 				FileOutputStream fos = openFileOutput("info.txt", MODE_PRIVATE);
96. 				fos.write((name+"##"+pwd).getBytes());
97. 				fos.close();
98. 				
99. 			} catch (Exception e) {
100. 				e.printStackTrace();
101. 			}
102. 		}else {
103. 			//如果用户没有勾选CheckBox则删除历史文件
104. 			if (file.exists()) {
105. 				boolean delete = file.delete();
106. 				if (delete) {
107. 					Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
108. 				}else {
109. 					Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show();
110. 				}
111. 				
112. 			}else {
113. 				Toast.makeText(this, "该文件不存在,
114. 不用删除", Toast.LENGTH_SHORT).show();
115. 			}
116. 		}
117. 	}
118. }
119. 

注意:

上面使用到了如下方法,这些方法都是在ContextWrapper类中定义的,是Activity的父类,因此可以直接使用。

getFilesDir():直接获取 /data/data/包名/files文件

openFileInput("info.txt"):直接打开/data/data/包名/files/info.txt文件

openFileOutput("info.txt",MODE_PRIVATE):直接创建 /data/data/包名/files/info.txt文件

在开发过程中凡是涉及到data目录操作的,很少自己去创建输入流和输出流,而应该尽量去使用Google已经提供的方法。

openFileOutput("info.txt",MODE_PRIVATE)方法的第二个参数是设置文件的权限,这里使用了私有常量值,也就是只能当前应用访问该文件。关于文件权限的详细介绍请看1.3.3节。

1.3.3 文件的权限

Android是基于Linux的操作系统,因此Android的文件权限其实就是Linux的文件权限。

在Linux中一个文件一共有三个组别:用户、群组、其它。其中每个组包含三种权限:读r、写w、执行x  ,也就是说一个文件共有9个权限属性(如图1-6所示)。  

图1-6中的第一个属性代表文件类型,不属于权限范畴。剩下的9位从左往右1到3位是[用户],4到6位是[群组],7到9位是[其它]。   

举例:通过DDMS的File Explorer查看文件信息(如图1-7),可以看到某个文件的权限为:-rwxrw-r--   

他的意思就是[用户]对其享有读写执行的权限,[群组]享有读写权限,[其它]享有读权限。







本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
本页面更新日期: 2016年07月23日 package 包 前面提到了 包 这个概念. 什么是包? 由于非常多的人参与 Java 的开发, 这难免会遇到一个问题 – 类名冲突 . 也就是说难免会遇到重名的情况. 所以 Java 引入了包这个机制. 提供了类的多层命名空间. 用于解决类的命名冲突 / 类文件管理等问题. Java允许将一组功能相关的类放在同一个 package 下. 从而组成逻辑上的 类库单元 . 如果希望把一个类放在指定的包结构下,应该在Java源程序的第一个非注释行放置如下格式的代码:
目录: APP项目如何与插件化无缝结合(一)  APP项目如何与插件化无缝结合(二)  APP项目如何与插件化无缝结合(三)  搬砖码字不易,转载请注明转自: http://blog.csdn.net/u011176685/article/details/52006474 上面一篇主要介绍了Small的原理,相信大家应该现在心里有个大概的了解。好,我们接下来继续开始! 一、Small的使用 关于Small的使用, Small的使用 这里讲的很详细,关于这里提下我当时遇到的问题和解决办法。 1.Small作
在Windows下试了试用Ionic开发Android应用,试通了。记录了过程。列在下面,供参考。 1. JDK 我用的jdk8,这里下载: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 。我老早下载的,8u66,i586(32位的),现在是8u102: http://download.oracle.com/otn-pub/java/jdk/8u102-b14/jdk-8u102-wi
最近写的项目中有用到数据库,写了不少蛋疼的sql语句,每次都是好几行代码,而且每次都是重复的没有一点技术含量的代码,虽然也有不少基于sqlite的封装,不过用起来还是感觉不够面向对象! 为了不再写重复的代码,花了几天时间,基于SQLite3简单封装了下,实现了一行代码解决增删改查等常用的功能!并没有太过高深的知识,主要用了runtime和KVC: 首先我们创建个大家都熟悉的Person类,并声明两个属性,下面将以类此展开分析 @interface Person : NSObject @property (

以太网帧格式 - 2016-07-24 18:07:25

浅谈以太网帧格式                                       一、Ethernet帧格式的发展 1980 DEC,Intel,Xerox制订了Ethernet I的标准 1982 DEC,Intel,Xerox又制订了Ehternet II的标准 1982 IEEE开始研究Ethernet的国际标准802.3  1983 迫不及待的Novell基于IEEE的802.3的原始版开发了专用的Ethernet帧格式 1985 IEEE推出IEEE 802.3规范,后来为解决Eth
  谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK。而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了。只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在执行Cygwin,然后传递ndk-build作为参数,这样就能让Eclipse自动编译
文章系列 视频驱动V4L2子系统驱动架构 - 驱动框架 视频驱动V4L2子系统驱动架构 - ioctl 基于linux4.6.3,最后会附上一张ioctl调用总图,分析代码还是要用图来说明,这样更清晰一点,我就是这么分析的,不过平时分析的图很随便,而且很大,所以就不能在这里呈现,我在这里会贴出一个简略图 ioctl详解 进入ioctl都是从cdev-ops-ioctl进入的,一般的驱动cdev都是驱动自己初始化的,在v4l2架构中,cdev都已经初始化完成,不需要驱动开发者来初始化,下面是v4l2的cde
杂谈 最近在研究gradle ,插件化~自己碰到的坑很多.今天先总结一下 以下这三个都研究过,原理都是一样的,区别就在于用哪个更方便. 在这里我会讲述一下,这里面的原理和自己爬的坑,以便大家理解,还有少爬坑~~ 原理是需要懂得~ 不然,你遇到错误不会解决,并且你始终会是初级工程师~ 首先,按照顺序,介绍下目前三种热修复的方式: 1.Nuwa (基于gradle写的脚本,操作起来比较麻烦,需要拷贝和运行命令行~) https://github.com/jasonross/Nuwa 2.andfix (看过~
题记——  难过了,悄悄走一走;         伤心了,默默睡一觉;         优雅不是训练出来的,而是一种阅历;         淡然不是伪装出来的,而是一种沉淀;         时间飞逝,老去的只是我们的容颜;         时间仿佛一颗灵魂,越来越动人; 1、简述:     在多线程的世界中,是那么的神奇 与 高效以及合理; 2、创建线程池实例     官方推荐使用Executors类工厂方法来创建线程池管理,Executors类是官方提供的一个工厂类,里面封装了好多功能不一样的线程池,
书接上回,我们已经了解了一些关于适配的一些相关概念,接下来我们会了解一下,在设置布局时我们应该注意的地方。 尽量不去设定具体的尺寸值。 为了确保布局适应各种尺寸的屏幕,在保证功能实现的前提下,最好不要写死一些尺寸,这样的硬编码,我们最好使用“match_parent”,”wrap_content”,”weight”这些不用指定具体的尺寸值的参数,这样视图就会根据自身需要的空间去充填。这样就可以让布局去适应各种屏幕的尺寸,当屏幕有旋转时也不会受到影响。 这里我们重点说一下“weight”,用过 LiearL