一、五种数据存储方式
二、文件内部存储
三、文件外部存储
案例:文件存储
附 代码补充
四、选项存储(应用设置)
案例:选项存储
附 整个案例代码补充
一、五种数据存储方式
![](http://dl2.iteye.com/upload/attachment/0111/6693/aa29ca48-b193-3c9d-ac3b-8865206034a7.png)
二、文件内部存储
1. 文件内部存储
应用程序直接将数据写入设备 Flash(ROM)的文件中,文件位于应用程序私有目录中,其他应用程序不能访问;当卸载应用程序时,文件会一同删除。
2. 数据存储位置
/data/data/app_name/files
3. 相关方法
![](http://dl2.iteye.com/upload/attachment/0109/6526/9b7d7d1b-aee3-327d-a65e-ff64f89a019c.png)
三、文件外部存储
1. 文件外部存储
android 支持将数据存储在共享的外部存储设备(可卸载的 SD 卡或 ROM)上,所有应用都可以读写文件(获得权限后),通常存储公共数据(音乐、照片、视频、下载的文件等内容)。
2. 设置访问 SDCard 的权限
(1)往 SDCard 写入数据权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(2)从 SDCard 读取数据权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
(3)在 SDCard 中创建与删除文件权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
案例:文件存储
主界面如下。当输入文件名和文件内容,点击“写入文件”,就会写入 内存 / SDCard 中;当只输入文件名,点击“读取文件”,就会读取相应文件名对应的文件内容,然后显示在“文件内容”栏中。
![](http://dl2.iteye.com/upload/attachment/0109/6535/5a2945e9-4033-38ec-88b0-ea5cbc914a3a.png)
1. strings.xml。定义所需字符串
<resources> <string name="app_name">Storage</string> <string name="action_settings">Settings</string> <string name="file_name">文件名</string> <string name="file_content">文件内容</string> <string name="append_mode">追加模式</string> <string name="btn_write">写入文件(内部存储)</string> <string name="btn_read">读取文件(内部存储)</string> <string name="btn_sd_write">写入文件(SDCard)</string> <string name="btn_sd_read">读取文件(SDCard)</string> <string name="op_success">操作成功</string> <string name="op_fail">操作失败</string> <string name="sdcard_fail">SD Card 不可用</string> </resources>
2. activity_main.xml。写主界面。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <EditText android:id="@+id/txtFileName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/file_name" android:singleLine="true" /> <EditText android:id="@+id/txtFileContent" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/txtFileName" android:hint="@string/file_content" android:lines="3" /> <CheckBox android:id="@+id/cbAppendMode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/txtFileContent" android:text="@string/append_mode" /> <Button android:id="@+id/btnWrite" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/cbAppendMode" android:onClick="onClick" android:text="@string/btn_write" /> <Button android:id="@+id/btnRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/cbAppendMode" android:layout_toRightOf="@id/btnWrite" android:onClick="onClick" android:paddingLeft="10dp" android:text="@string/btn_read" /> <Button android:id="@+id/btnSDCardWrite" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btnWrite" android:onClick="onClick" android:text="@string/btn_sd_write" /> <Button android:id="@+id/btnSDCardRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btnWrite" android:layout_toRightOf="@id/btnSDCardWrite" android:onClick="onClick" android:paddingLeft="10dp" android:text="@string/btn_sd_read" /> </RelativeLayout>
3. MainActivity。写 onClick() 方法,声明变量,初始化变量。
public void onClick(View view) { switch (view.getId()) { case R.id.btnWrite: doWrite(); break; case R.id.btnRead: doRead(); break; case R.id.btnSDCardWrite: doSDCardWrite(); break; case R.id.btnSDCardRead: doSDCardRead(); break; } }
private EditText txtFileName; private EditText txtFileContent; private CheckBox cbAppendMode;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtFileName = (EditText) findViewById(R.id.txtFileName); txtFileContent = (EditText) findViewById(R.id.txtFileContent); cbAppendMode = (CheckBox) findViewById(R.id.cbAppendMode); }
4. 文件内部存储。
(1)自定义独立的 FileService 类,封装文件内部存储的写入、读取操作。
package com.xiangdong.storage; import android.content.Context; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; /** * 内部存储文件操作(不需要权限) */ public class FileService { private Context context; // 上下文 public FileService(Context context) { this.context = context; } /** * 保存文件内容 * * @param fileName 文件名 * @param fileContent 文件内容 * @param mode 保存模式 */ public void write(String fileName, String fileContent, int mode) throws Exception { // Android 中 通过上下文,就可以直接打开文件(通过 openFileOutput),Java I/O流中还得 new /* openFileOutput :Open a private file associated with this Context's application package for writing. Creates the file if it doesn't already exist. */ FileOutputStream out = context.openFileOutput(fileName, mode); out.write(fileContent.getBytes()); out.close(); } /** * 读取文件 * * @param fileName * @return * @throws Exception */ public String read(String fileName) throws Exception { /* openFileInput :Open a private file associated with this Context's application package for reading. */ FileInputStream in = context.openFileInput(fileName); byte[] buffer = new byte[1024]; int len = 0; ByteArrayOutputStream out = new ByteArrayOutputStream(); while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } //获得文件的二进制数据 byte[] data = out.toByteArray(); in.close(); out.close(); return new String(data); } }
补充:
Activity提供了 openFileOutput() 方法可以用于把数据输出到文件中。
openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。
openFileOutput()方法的第二参数用于指定操作模式,有四种模式:
![](http://dl2.iteye.com/upload/attachment/0109/6545/8a099927-1461-3b29-9a87-54040e58a010.png)
(2)声明变量,初始化变量。
private FileService fileService;
fileService = new FileService(this);
(3)MainActivity。创建 doWrite() 方法,实现内部存储写入文件。
/** * 内部存储写入文件 */ private void doWrite() { // 先得到 文件名、文件内容 String fileName = txtFileName.getText().toString(); String fileContent = txtFileContent.getText().toString(); try { if (cbAppendMode.isChecked()) { // 追加 fileService.write(fileName, fileContent, Context.MODE_APPEND); } else { // 覆盖 // 文件仅能被创建它的程序所访问 fileService.write(fileName, fileContent, Context.MODE_PRIVATE); } showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } }
其中,用到自定义的 showToast() 方法:
private void showToast(int resId) { Toast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show(); }
(4)MainActivity。创建 doRead() 方法,实现内部存储读取文件。
/** * 内部存储读取文件 */ private void doRead() { // 获得文件名 String fileName = txtFileName.getText().toString(); try { String fileContent = fileService.read(fileName); txtFileContent.setText(fileContent); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } }
5. 文件外部存储。
(1)在功能清单文件中,授权往 SDCard 写入和读取数据。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
(2)自定义独立的 SDCardService 类,封装文件外部存储的写入、读取操作。
package com.xiangdong.storage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; /** * 外部存储(SDCard)文件操作 (需要权限 - WRITE/READ : 在功能清单中授予权限) */ public class SDCardService { public void write(File file, String fileContent, boolean append) throws Exception { FileOutputStream out = new FileOutputStream(file, append); out.write(fileContent.getBytes()); out.close(); } public String read(File file) throws Exception { FileInputStream in = new FileInputStream(file); byte[] buffer = new byte[1024]; int len = 0; ByteArrayOutputStream out = new ByteArrayOutputStream(); while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } //获得文件的二进制数据 byte[] data = out.toByteArray(); in.close(); out.close(); return new String(data); } }
(3)声明变量,初始化变量。
private SDCardService sdCardService;
sdCardService = new SDCardService();
(4)MainActivity。创建 doSDCardWrite() 方法,实现外部存储写入文件。
/** * 外部存储写入文件 */ private void doSDCardWrite() { // 先得到 文件名、文件内容 String fileName = txtFileName.getText().toString(); String fileContent = txtFileContent.getText().toString(); // 判断手机是否装有 SDCard ,并且可以进行读写 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { try { // 获得 SDCard 根目录 File sdCardDir = Environment.getExternalStorageDirectory(); // 在根目录下面,获得文件 File file = new File(sdCardDir, fileName); boolean append = false; // 默认是覆盖 if (cbAppendMode.isChecked()) { append = true; // 追加 } sdCardService.write(file, fileContent, append); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } else { showToast(R.string.sdcard_fail); } }
(5)MainActivity。创建 doSDCardRead() 方法,实现外部存储读取文件。
/** * SDCard 读取文件 */ private void doSDCardRead() { String fileName = txtFileName.getText().toString(); // 判断手机是否装有 SDCard ,并且可以进行读写 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { try { // 获取 SDCard 根目录 File sdCardDir = Environment.getExternalStorageDirectory(); // 在根目录下面,获得文件 File file = new File(sdCardDir, fileName); String fileContent = sdCardService.read(file); txtFileContent.setText(fileContent); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } else { showToast(R.string.sdcard_fail); } }
附 代码补充
MainActivity:
package com.xiangdong.storage; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; import android.os.Bundle; import android.os.Environment; import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.io.File; public class MainActivity extends Activity { private EditText txtFileName; private EditText txtFileContent; private CheckBox cbAppendMode; private FileService fileService; private SDCardService sdCardService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtFileName = (EditText) findViewById(R.id.txtFileName); txtFileContent = (EditText) findViewById(R.id.txtFileContent); cbAppendMode = (CheckBox) findViewById(R.id.cbAppendMode); fileService = new FileService(this); sdCardService = new SDCardService(); } public void onClick(View view) { switch (view.getId()) { case R.id.btnWrite: doWrite(); break; case R.id.btnRead: doRead(); break; case R.id.btnSDCardWrite: doSDCardWrite(); break; case R.id.btnSDCardRead: doSDCardRead(); break; } } /** * SDCard 读取文件 */ private void doSDCardRead() { String fileName = txtFileName.getText().toString(); // 判断手机是否装有 SDCard ,并且可以进行读写 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { try { // 获取 SDCard 根目录 File sdCardDir = Environment.getExternalStorageDirectory(); // 在根目录下面,获得文件 File file = new File(sdCardDir, fileName); String fileContent = sdCardService.read(file); txtFileContent.setText(fileContent); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } else { showToast(R.string.sdcard_fail); } } /** * 外部存储写入文件 */ private void doSDCardWrite() { // 先得到 文件名、文件内容 String fileName = txtFileName.getText().toString(); String fileContent = txtFileContent.getText().toString(); // 判断手机是否装有 SDCard ,并且可以进行读写 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { try { // 获得 SDCard 根目录 File sdCardDir = Environment.getExternalStorageDirectory(); // 在根目录下面,获得文件 File file = new File(sdCardDir, fileName); boolean append = false; // 默认是覆盖 if (cbAppendMode.isChecked()) { append = true; // 追加 } sdCardService.write(file, fileContent, append); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } else { showToast(R.string.sdcard_fail); } } /** * 内部存储读取文件 */ private void doRead() { // 获得文件名 String fileName = txtFileName.getText().toString(); try { String fileContent = fileService.read(fileName); txtFileContent.setText(fileContent); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } /** * 内部存储写入文件 */ private void doWrite() { // Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容 // Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。 // MODE_WORLD_READABLE:表示当前文件可以被其他应用读取; // MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入 // 先得到 文件名、文件内容 String fileName = txtFileName.getText().toString(); String fileContent = txtFileContent.getText().toString(); try { if (cbAppendMode.isChecked()) { // 追加 fileService.write(fileName, fileContent, Context.MODE_APPEND); } else { // 覆盖 // 文件仅能被创建它的程序所访问 fileService.write(fileName, fileContent, Context.MODE_PRIVATE); } showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } private void showToast(int resId) { Toast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show(); } // ---------------------------------------------------------------------------- @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } }
四、选项存储(应用设置)
1. 选项存储(应用设置)
选项存储,也称为应用设置。保存用户在使用应用程序时的偏好,数据以键值对形式保存在 xml 文件中。
很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,其背后是用xml文件存放数据。
2. 目标位置
/data/data/app_name/shared_prefs/
3. 两种实现方式
![](http://dl2.iteye.com/upload/attachment/0109/6562/80664ea2-4e1c-3a60-a03b-8d42d5a75034.png)
案例:选项存储
主界面如下:
![](http://dl2.iteye.com/upload/attachment/0109/6576/792c8692-e12c-3059-966d-287a93cf210a.png)
点击“设置”菜单,进入 选项屏幕:
![](http://dl2.iteye.com/upload/attachment/0109/6580/5175e28a-3a9d-3ae4-9579-af9f6b9c4463.png)
Welcome_text 修改前(Hello World):
![](http://dl2.iteye.com/upload/attachment/0109/6574/61ace005-49ec-3478-a924-6fc7cd7e6ea0.png)
Welcome_text 修改(你好!):
![](http://dl2.iteye.com/upload/attachment/0109/6572/da1c2c85-5ebd-3e36-ae54-8ad13b5f1658.png)
Welcome_text_color 修改前(black):
![](http://dl2.iteye.com/upload/attachment/0109/6570/65701cf8-9df6-3cd5-b222-dabf88a2843f.png)
Welcome_text_color 修改(blue):
![](http://dl2.iteye.com/upload/attachment/0109/6568/74d741e3-557e-32b8-872c-d08fce2acb2f.png)
选项屏幕中,“Show welcome text”是勾选了的,因此会在主界面显示“欢迎文字”。修改之后,返回主界面,如下:
![](http://dl2.iteye.com/upload/attachment/0109/6578/79831f7c-3207-3f6c-9b77-fe9c81d2a74c.png)
1. strings.xml。定义所需字符串。
<resources> <string name="app_name">Storage</string> <!-- Strings related to Settings --> <string name="pref_title_welcome_text">Welcome text</string> <string name="pref_summary_welcome_text">The welcome text to show in the main activity.</string> <string name="pref_default_welcome_text">Hello World</string> <string name="pref_title_welcome_text_color">Welcome text color</string> <string name="pref_summary_welcome_text_color">The color of the welcome text to show in the main activity.</string> <string name="pref_default_welcome_text_color">#000000</string> <string name="pref_title_show_welcome_text">Show welcome text</string> <string name="pref_summary_show_welcome_text">Shows the welcome text in the main activity.</string> </resources>
2. 在 values 下面创建 array.xml 数组文件。里面包含了 “颜色标签”的数组和“每个颜色对应的值”的数组。
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="colorLabelsArray"> <item>Aqua</item> <item>Black</item> <item>Blue</item> <item>Fushsia</item> <item>Gray</item> <item>Green</item> <item>Lime</item> <item>Maroon</item> <item>Navy</item> <item>Olive</item> <item>Purple</item> <item>Red</item> <item>Silver</item> <item>Teal</item> <item>White</item> <item>Yellow</item> </string-array> <string-array name="colorValuesArray"> <item>#00FFFF</item> <item>#000000</item> <item>#0000FF</item> <item>#FF00FF</item> <item>#808000</item> <item>#008000</item> <item>#00FF00</item> <item>#800000</item> <item>#000080</item> <item>#808080</item> <item>#800080</item> <item>#FF0000</item> <item>#C0C0C0</item> <item>#008080</item> <item>#FFFFFF</item> <item>#FFFF00</item> </string-array> </resources>
3. 定义用户接口(“选项屏幕”):在 res 下面创建一个目录:xml。在该目录下,创建 preferences.xml。
![](http://dl2.iteye.com/upload/attachment/0109/6580/5175e28a-3a9d-3ae4-9579-af9f6b9c4463.png)
(1)与定义活动、菜单一样,使用 XML 形式定义用户接口,根元素 PreferenceScreen 。
(2)文件位置: /res/xml/。
(3)元素类型:
![](http://dl2.iteye.com/upload/attachment/0109/6566/5e5f25fa-b4b2-32d9-8046-7feec924ede9.png)
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- EditTextPreference :文本框选项(允许修改欢迎文本) defaultValue 默认值 key 键 summary 摘要 title 标题 --> <!--选项的屏幕--> <EditTextPreference android:defaultValue="@string/pref_default_welcome_text" android:key="welcome_text" android:summary="@string/pref_summary_welcome_text" android:title="@string/pref_title_welcome_text" /> <ListPreference android:defaultValue="@string/pref_default_welcome_text_color" android:entries="@array/colorLabelsArray" android:entryValues="@array/colorValuesArray" android:key="welcome_text_color" android:summary="@string/pref_summary_welcome_text_color" android:title="@string/pref_title_welcome_text_color" /> <CheckBoxPreference android:defaultValue="true" android:key="show_welcome_text" android:summary="@string/pref_summary_show_welcome_text" android:title="@string/pref_title_show_welcome_text" /> </PreferenceScreen>
4. activity_main.xml。在最后加一个 TextView,用来显示“欢迎文本”。
![](http://dl2.iteye.com/upload/attachment/0109/6576/792c8692-e12c-3059-966d-287a93cf210a.png)
<TextView android:id="@+id/tvPreference" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btnSDCardWrite" android:text="@string/app_name" android:textSize="30sp" />
5. 在 Java 包下,创建 选项碎片 SettingsFragment,用来加载 选项屏幕 preferences.xml。
package com.android.storage; import android.os.Bundle; import android.preference.PreferenceFragment; /** * 选项 Fragment 界面 */ public class SettingsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 从资源文件中,加载 选项屏幕 界面 addPreferencesFromResource(R.xml.preferences); } }
6. 在 Java 包下,创建 活动类 SettingsActivity,在点击菜单中的“Settings”时,用来加载 选项碎片 SettingsFragment。
package com.android.storage; import android.app.Activity; import android.os.Bundle; /** * 选项的活动(界面) */ public class SettingsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Display the preferences fragment as the content of the activity // 在活动(界面)中显示 选项屏幕 碎片 界面 // android.R.id.content:来自 Android 的默认的 Layout: LinearLayout getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingsFragment()).commit(); } }
7. 在功能清单文件中,注册 SettingsActivity。
<activity android:name=".SettingsActivity" android:label="@string/action_settings" android:parentActivityName=".MainActivity"> </activity>
注:
创建 Activity 三步曲:布局、活动、注册。直接创建 Activity 的时候,三步会自动完成。当只创建活动,不需要布局的时候,还需要自己注册。建议:直接创建 Activity,然后删除掉不需要的 布局。
8. MainActivity。在设置菜单中,通过意图,设置 主活动界面跳转到设置活动中,而设置活动显示的是 选项屏幕 界面,因此点击设置后,显示的是 选项屏幕 的界面。
@Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { // Starts the Settings activity on top of the current activity Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); }
9. 重绘界面。(由 SettingsActivity跳转到MainActivity后,需要重绘界面,才会显示出更新之后的效果。重绘界面,用到Activity生命周期中的 onResume()方法。)
/** * 重绘界面 * (由 SettingsActivity跳转到 MainActivity后, * 需要重绘界面,才会显示出更新之后的效果。 * 重绘界面,用到Activity生命周期中的 onResume()方法。) */ @Override public void onResume() { super.onResume(); // 通过选项管理器,从目录中(data/data/app_name/shared_prefs)获得选项信息 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); // 获得 文本框控件 (为了改显示的文本) TextView welcomeTextView = (TextView) findViewById(R.id.tvPreference); // 获得 欢迎文本 String defaultWelcomeText = getResources().getString(R.string.pref_default_welcome_text); String welcomeText = preferences.getString("welcome_text", defaultWelcomeText); welcomeTextView.setText(welcomeText); // 获得 欢迎文本的字体颜色 String defaultWelcomeTextColor = getResources().getString(R.string.pref_default_welcome_text_color); String welcomeTextColor = preferences.getString("welcome_text_color", defaultWelcomeTextColor); welcomeTextView.setTextColor(Color.parseColor(welcomeTextColor)); // 显示欢迎文本 boolean showWelcomeText = preferences.getBoolean("show_welcome_text", true); if (showWelcomeText) { welcomeTextView.setVisibility(View.VISIBLE); } else { welcomeTextView.setVisibility(View.INVISIBLE); } }
附 整个案例代码补充
![](http://dl2.iteye.com/upload/attachment/0109/6599/b23bbd84-b5e0-3f08-85fc-738709ad4e92.png)
1. strings.xml。
<resources> <string name="app_name">Storage</string> <string name="file_name">文件名</string> <string name="file_content">文件内容</string> <string name="append_mode">追加模式</string> <string name="btn_writer">写入文件(内部存储)</string> <string name="btn_read">读取文件(内部存储)</string> <string name="btn_sdcard_writer">写入文件(SDCard)</string> <string name="btn_sdcard_read">读取文件(SDCard)</string> <string name="op_success">操作成功</string> <string name="op_fail">操作失败</string> <string name="sdcard_fail">SD Card 是否可用.</string> <!-- Strings related to Settings --> <string name="action_settings">Settings</string> <string name="pref_title_welcome_text">Welcome text</string> <string name="pref_summary_welcome_text">The welcome text to show in the main activity.</string> <string name="pref_default_welcome_text">Hello World</string> <string name="pref_title_welcome_text_color">Welcome text color</string> <string name="pref_summary_welcome_text_color">The color of the welcome text to show in the main activity.</string> <string name="pref_default_welcome_text_color">#000000</string> <string name="pref_title_show_welcome_text">Show welcome text</string> <string name="pref_summary_show_welcome_text">Shows the welcome text in the main activity.</string> </resources>
2. activity_main.xml。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <EditText android:id="@+id/txtFileName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/file_name" android:singleLine="true"/> <EditText android:id="@+id/txtFileContent" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/txtFileName" android:hint="@string/file_content" android:lines="3"/> <CheckBox android:id="@+id/cbAppendMode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/txtFileContent" android:text="@string/append_mode"/> <Button android:id="@+id/btnWriter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/cbAppendMode" android:onClick="onClick" android:text="@string/btn_writer"/> <Button android:id="@+id/btnRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btnWriter" android:onClick="onClick" android:text="@string/btn_read"/> <Button android:id="@+id/btnSDCardWriter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btnRead" android:onClick="onClick" android:text="@string/btn_sdcard_writer"/> <Button android:id="@+id/btnSDCardRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btnSDCardWriter" android:onClick="onClick" android:text="@string/btn_sdcard_read"/> <!-- Widget related to Settings --> <TextView android:id="@+id/tvPreference" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btnSDCardRead" android:text="@string/app_name" android:textSize="30sp"/> </RelativeLayout>
3. MainActivity。
package com.android.storage; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; import android.os.Bundle; import android.os.Environment; import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.io.File; public class MainActivity extends Activity { private EditText txtFileName; private EditText txtFileContent; private CheckBox cbAppendMode; private FileService fileService; private SDCardService sdCardService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtFileName = (EditText) findViewById(R.id.txtFileName); txtFileContent = (EditText) findViewById(R.id.txtFileContent); cbAppendMode = (CheckBox) findViewById(R.id.cbAppendMode); fileService = new FileService(this); sdCardService = new SDCardService(); } public void onClick(View view) { switch (view.getId()) { case R.id.btnWriter: doWrite(); break; case R.id.btnRead: doRead(); break; case R.id.btnSDCardWriter: doSDCardWriter(); break; case R.id.btnSDCardRead: doSDCardRead(); break; } } /** * SDCard 写入文件 */ private void doSDCardWriter() { String fileName = txtFileName.getText().toString(); String fileContent = txtFileContent.getText().toString(); // 判断手机是否装有SDCard,并且可以进行读写 if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { try { // 获取SDCard根目录 File sdCardDir = Environment.getExternalStorageDirectory(); File file = new File(sdCardDir, fileName); boolean append = false; // 默认:覆盖 if (cbAppendMode.isChecked()) { append = true; // 追加 } sdCardService.write(file, fileContent, append); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } else { showToast(R.string.sdcard_fail); } } /** * SDCard 读取文件 */ private void doSDCardRead() { String fileName = txtFileName.getText().toString(); if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { try { // 获取SDCard目录 File sdCardDir = Environment.getExternalStorageDirectory(); File file = new File(sdCardDir, fileName); String fileContent = sdCardService.read(file); txtFileContent.setText(fileContent); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } else { showToast(R.string.sdcard_fail); } } /** * 内部存储读取文件 */ private void doRead() { String fileName = txtFileName.getText().toString(); try { String fileContent = fileService.read(fileName); txtFileContent.setText(fileContent); showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } /** * 内部存储写入文件 */ private void doWrite() { // Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容 // Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。 // MODE_WORLD_READABLE:表示当前文件可以被其他应用读取; // MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入 String fileName = txtFileName.getText().toString(); String fileContent = txtFileContent.getText().toString(); try { if (cbAppendMode.isChecked()) { // 追加 abc -> abcxyz fileService.write(fileName, fileContent, Context.MODE_APPEND); } else { // 覆盖 abc -> xyz // 文件仅能被创建它的程序所访问 fileService.write(fileName, fileContent, Context.MODE_PRIVATE); } showToast(R.string.op_success); } catch (Exception e) { showToast(R.string.op_fail); } } private void showToast(int resId) { Toast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { // Starts the Settings activity on top of the current activity Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } /** * 重绘界面 * (由 SettingsActivity跳转到 MainActivity后, * 需要重绘界面,才会显示出更新之后的效果。 * 重绘界面,用到Activity生命周期中的 onResume()方法。) */ @Override public void onResume() { super.onResume(); // 通过选项管理器,从目录中(data/data/app_name/shared_prefs)获得选项信息 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); // 获得 文本框控件 (为了改显示的文本) TextView welcomeTextView = (TextView) findViewById(R.id.tvPreference); // 获得 欢迎文本 String defaultWelcomeText = getResources().getString(R.string.pref_default_welcome_text); String welcomeText = preferences.getString("welcome_text", defaultWelcomeText); welcomeTextView.setText(welcomeText); // 获得 欢迎文本的字体颜色 String defaultWelcomeTextColor = getResources().getString(R.string.pref_default_welcome_text_color); String welcomeTextColor = preferences.getString("welcome_text_color", defaultWelcomeTextColor); welcomeTextView.setTextColor(Color.parseColor(welcomeTextColor)); // 显示欢迎文本 boolean showWelcomeText = preferences.getBoolean("show_welcome_text", true); if (showWelcomeText) { welcomeTextView.setVisibility(View.VISIBLE); } else { welcomeTextView.setVisibility(View.INVISIBLE); } } }