传智播客—Android(三) 数据存储之二 SharedPreferences
在此之前的学习内容是数据存储之一文件存储。在本地存储中常用的有,文件、配置文件、数据库。前面的学习主要是针对本地文件的。我认为可以把SharedPreferences看做是配置文件,虽然它也是采用XML格式存储的。
比如我们使用的桌面软件中,通常会有一个“选项”菜单,选项是对软件的常规或核心设置。在Android中我们使用SharedPreferences来完成这种对配置文件的读写。在JavaSE和JavaEE中常用的是*.properties,在Windows平台下常使用*.ini文件。
它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs目录下
public class AndroidSharedPreferences extends Activity { private static final String TAG = "AndroidSharedPreferences"; private EditText etName; private EditText etAge; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取按钮 Button btSet = (Button) this.findViewById(R.id.bt_set); Button btRead = (Button) this.findViewById(R.id.bt_read); // 获取编辑框 etName = (EditText) this.findViewById(R.id.et_name); etAge = (EditText) this.findViewById(R.id.et_age); // 添加事件 btSet.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 获取名称和年龄 String name = etName.getText().toString(); String age = etAge.getText().toString(); // 创建SharedPreferences,不要加上后缀名,参数二是权限。可以使其他应用都能访问 SharedPreferences sp = getSharedPreferences("preferences", Context.MODE_PRIVATE); // 添加数据,一定要使用edit函数 Editor editor = sp.edit(); editor.putString("name", name); editor.putInt("age", Integer.parseInt(age)); // 保存数据 ,类是与事务 if (editor.commit()) Toast.makeText(AndroidSharedPreferences.this, R.string.save_success, 1).show(); else Toast.makeText(AndroidSharedPreferences.this, R.string.save_failed, 1).show(); } }); btRead.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 创建SharedPreferences SharedPreferences sp = getSharedPreferences("preferences", Context.MODE_PRIVATE); // 获取数据 String name = sp.getString("name", "defName"); String age = sp.getInt("age", 0) + ""; // 显示数据 etName.setText(name); etAge.setText(age); } }); } }
如果想其他应用都能能使用本sharedPreference,可以使用他的路径名来读取文件。通过SharedPreferences创建的配置文件,不需要指定路径和文件后缀名,读取的时候也是。通常情况下,配置只是提供给本应用程序使用的。在这里我们介绍一个小知识点,即其他程序想使用本应用程序的配置,那应该如何使用SharedPreferences呢?如下:
//构建其他应用的上下文 Context otherAppContext = createPackageContext("com.changcheng.sharedpreferences", Context.CONTEXT_IGNORE_SECURITY); ///可以像使用自己saredPreferenf的文件一样操作 SharedPreferences sharedPreferences = otherAppContext.getSharedPreferences("preferences", Context.MODE_WORLD_READABLE); //注意,为了使其他程序可以访问本应用程序的配置。那么在我们使用 getSharedPreferences创建配置的时候必须为它的文件访问模式设置为允许其他程序读取或写入等。
因为SharedPreferences背后是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式前面介绍使用文件方式保存数据时已经讲解过。如果希望SharedPreferences背后使用的xml文件能被其他应用读和写,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。
另外Activity还提供了另一个getPreferences(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。
其他资料:
访问SharedPreferences中的数据代码如下:
SharedPreferences sharedPreferences = getSharedPreferences("itcast", Context.MODE_PRIVATE);
//getString()第二个参数为缺省值,如果preference中不存在该key,将返回缺省值
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 1);
如果访问其他应用中的Preference,前提条件是:该preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。如:有个<package name>为cn.itcast.action的应用使用下面语句创建了preference。
getSharedPreferences("itcast", Context.MODE_WORLD_READABLE);
其他应用要访问上面应用的preference,首先需要创建上面应用的Context,然后通过Context 访问preference ,访问preference时会在应用所在包下的shared_prefs目录找到preference :
Context otherAppsContext = createPackageContext("cn.itcast.action", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("itcast", Context.MODE_WORLD_READABLE);
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 0);
如果不通过创建Context访问其他应用的preference,可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如:
File xmlFile = new File(“/data/data/<package name>/shared_prefs/itcast.xml”);//<package name>应替换成应用的包名
补充: Preferences
http://www.cnblogs.com/wservices/archive/2010/07/08/1773449.html
http://www.vogella.de/articles/Android/article.html
Android之PreferenceActivity
看到很多书中都没有对PreferenceActivity做介绍,而我正好又在项目中用到,所以就把自己的使用的在这总结一下,也方便日后查找。
PerferenceActivity是什么,看下面的截图:
Android系统截图(左) MusicPlayer Setting截图(右)
好了,我们看到Android系统本身就大量用到了PreferenceActivity来对系统进行信息配置和管理,那么它是怎么保存数据的呢,如何创建PrefenceActivity的呢,更关键是怎样触发相应事件的呢。
先看第一个问题,PreferenceActivity是如何保存的数据。对Android系统了解的都知道,Android系统有四种基本的数据保存方法,一是SharedPreference,二是文件,三是SQLite,四是ContentProvider。看出来了吧,Preference,对就是使用SharedPreferneces以键值对的形式进行保存的,当然,我们也可以通过SharedPreferences来获取PreferenceActivity设置的值。
第二个问题:如何创建一个PreferenceActivity。 其实Eclipse提供了相应的创建工具,和创建Layout是基本相同的。步骤如下:
创建Android项目,并添加一个Android xml文件。注意,这次选择的不是Layout,而是Preference,而且注意Folder路径是 res/xml.
添加完成之后,在res/xml/下打开添加的preference.xml文件。可以看到Android也为我们提供两种编辑模式,可视化的结构设计及xml源码设计。推荐使用structure进行创建。如图所示:
下面我们看看PrefeneceActivity都提供了哪几种元素可供使用。点击Add按钮,在打开的新窗口中可以看到以下几项:
CheckBoxPreference:CheckBox选择项,对应的值的ture或flase。如图:
EditTextPreference:输入编辑框,值为String类型,会弹出对话框供输入。
ListPreference: 列表选择,弹出对话框供选择。
Preference:只进行文本显示,需要与其他进行组合使用。
PreferenceCategory:用于分组。效果如下:
PreferenceScreen:PreferenceActivity的根元素,必须为它。
RingtonePreference:系统玲声选择。
OK,Preferenc的基本元素介绍完毕,下一节将使用它们创建一个完整的Preference并进行显示。
-------------------------------------------------------------------------------
分析MusicPlayer Setting,第一部分为“我的位置”,包括“使用无线网线”和“使用GPS”两个部分,而且都是CheckBox,根据上节学习,应该包括一个PreferenceCategory和两个CheckBoxPreference。
Xml代码:
<PreferenceCategory android:title="我的位置" android:key="set_local"><CheckBoxPreference android:key="apply_wifi"android:summary="使用无线网络在应用程序(例如Google地图)中查看位置"
android:title="使用无线网络" android:defaultValue="true"></CheckBoxPreference><CheckBoxPreference android:key="apply_gps"android:summary="定位到街道级别(需要消耗更多的电量以及天气允许)"
android:title="使用GPS"></CheckBoxPreference></PreferenceCategory>
以上代码当然也可以用Android提供的IDE工具直接生成。视频结构如下:
PreferenceCategory属性分析:
title:显示的标题
key:唯一标识(至少在同一程序中是唯一),SharedPreferences也将通过此Key值进行数据保存,也可以通过key值获取保存的信息 (以下相同)。
CheckBoxPreference属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
summary:副标题(小字体显示)
defaultValue:默认值(当然,此处只能是true或false了)
Preference.xml的第二部分为“无线和网络设置”,此部分包括的内容比较多,也稍微复杂,一步一步来分析。
xml代码:
<PreferenceCategory android:title="无线和网络设置"><CheckBoxPreference android:key="apply_fly"android:summary="禁用所有无线连接" android:title="飞行模式"></CheckBoxPreference><CheckBoxPreference android:key="apply_internet"android:summary="禁用通过USB共享Internet连接"
android:title="Internet共享"></CheckBoxPreference><CheckBoxPreference android:key="apply_wifi"android:summary="打开Wi-Fi" android:title="Wi-Fi"></CheckBoxPreference><Preference android:summary="设置和管理无线接入点" android:title="Wi-Fi设置"android:dependency="apply_wifi" android:key="wifi_setting"></Preference><CheckBoxPreference android:key="apply_bluetooth"android:summary="启用蓝牙" android:title="蓝牙"></CheckBoxPreference><Preference android:summary="管理连接、设备设备名称和可检测性"android:title="蓝牙设置" android:dependency="apply_bluetooth"android:key="bluetooth_setting"></Preference><EditTextPreference android:key="number_edit"android:title="输入电话号码"></EditTextPreference><ListPreference android:title="部门设置" android:entries="@array/department"android:entryValues="@array/department_value"
android:dialogTitle="选择部门"android:key="depart_value"></ListPreference><RingtonePreference android:ringtoneType="all" android:title="玲聲"
android:showDefault="true" android:key="ring_key"
android:showSilent="true"></RingtonePreference></PreferenceCategory>
对应的Structure图:
第二部分中前三个都为CheckBoxPreference,不心多说,从<Preferenceandroid:key="bluetooth_setting"/>开始。
Preference属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
summary:副标题(小字体显示)
dependency:附属(嘛意思),即标识此元素附属于某一个元素(通常为CheckBoxPreference),dependency值为所附属元素的key。上面代码中的Preference元素附属于key等于“apply_bluetooth”的CheckPreference元素,当CheckPreference值为true时,Preference则为可用,否则为不可用。
EditTextPreperence属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
ListPreference属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
dialogTitle:弹出对话框的标题
entries:列表中显示的值。为一个数组,通读通过资源文件进行设置。
entryValues:列表中实际保存的值,也entries对应。为一个数组,通读通过资源文件进行设置。以下代码显示的是arrays.xml文件中内容:
<resources><string-array name="department"><item>综合部</item><item>行政部</item><item>外贸部</item></string-array><string-array name="department_value"><item>001</item><item>002</item><item>003</item></string-array></resources>
RingtonePreference :玲声(暂时没有用到过),暂时略过。
OK,Preference.xml内容已经分析完毕,属性都大致相同,相信亲自动力一试也就那么回事。那么如何把Preference.xml中内容展现出来呢?
Layout是通过继续自Activity的类来进行显示的,前面提到过,PreferenceActivity是专门用于显示preference的,所以只要创建一个继承自PreferenceActivity类即可。代码如下:
public class Setting extends PreferenceActivity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 所的的值将会自动保存到SharePreferencesaddPreferencesFromResource(R.xml.preference);}}
接下来就是运行程序,显示劳动成果。至此,工作已经完成大半,所有的值都会保存到SharedPreferences中,我们也可以读取到保存的结果。
还有一个重要的问题,就是如何响应PreferenceActivity的操作。其实只要重写PreferenceActivity的 onPreferenceTreeClick的方法就可以了,通过参数preference来判断是对那一个元素进行的,并根据需要进行操作。
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,Preference preference) {return false;}
Ok,到此关于PreferenceActvity的想关内容就完了,日后有什么重大发现会补上。
更多相关文章
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
- Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
- Android软件安全与逆向分析入门-壹-初识反编译
- Android实现语音数据实时采集、播放