`
XiangdongLee
  • 浏览: 91332 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

【攻克Android (18)】数据存储

 
阅读更多
本文围绕以下五个部分展开:

一、五种数据存储方式
二、文件内部存储
三、文件外部存储
案例:文件存储
        附   代码补充
四、选项存储(应用设置)
案例:选项存储

附   整个案例代码补充





一、五种数据存储方式




二、文件内部存储

        1. 文件内部存储

        应用程序直接将数据写入设备 Flash(ROM)的文件中,文件位于应用程序私有目录中,其他应用程序不能访问;当卸载应用程序时,文件会一同删除。

        2. 数据存储位置

        /data/data/app_name/files

        3. 相关方法




三、文件外部存储

        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 中;当只输入文件名,点击“读取文件”,就会读取相应文件名对应的文件内容,然后显示在“文件内容”栏中。



        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()方法的第二参数用于指定操作模式,有四种模式:



        (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. 两种实现方式




案例:选项存储

        主界面如下:



        点击“设置”菜单,进入 选项屏幕:



        Welcome_text 修改前(Hello World):



        Welcome_text 修改(你好!):



        Welcome_text_color 修改前(black):



        Welcome_text_color 修改(blue):



        选项屏幕中,“Show welcome text”是勾选了的,因此会在主界面显示“欢迎文字”。修改之后,返回主界面,如下:



        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。



        (1)与定义活动、菜单一样,使用 XML 形式定义用户接口,根元素 PreferenceScreen 。

        (2)文件位置: /res/xml/。

        (3)元素类型:



<?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,用来显示“欢迎文本”。



<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);
        }
    }



附   整个案例代码补充



        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);
        }
    }
}
  • 大小: 23.2 KB
  • 大小: 35.7 KB
  • 大小: 22.2 KB
  • 大小: 7.3 KB
  • 大小: 25.7 KB
  • 大小: 28.1 KB
  • 大小: 28.4 KB
  • 大小: 24.4 KB
  • 大小: 57.1 KB
  • 大小: 25.3 KB
  • 大小: 24.5 KB
  • 大小: 25.6 KB
  • 大小: 13.8 KB
  • 大小: 23.8 KB
分享到:
评论

相关推荐

    攻克Data-数据采集与存储-适用于各个平台数据爬虫

    "攻克Data-数据采集与存储-适用于各个平台数据爬虫"这个主题聚焦于如何有效地从各种平台抓取并存储数据。在这个过程中,爬虫技术扮演了关键角色,它能够自动化地从互联网上获取大量信息。现在,让我们深入探讨相关...

    攻克Data动态获取网页评论,保存数据库

    【攻克Data动态获取网页评论,保存数据库】是一个关于利用特定工具——攻克Data,来抓取网页上的评论数据并存储到数据库的过程。这个过程涉及到网络爬虫技术、JSON解析以及数据库管理等多个IT领域的知识点。 1. **...

    大学生攻克Linux系统教程

    本教程将介绍C语言和Python作为入门语言,讲解基本语法、数据结构、流程控制,以及如何在Linux下编译和运行程序。此外,还将介绍版本控制工具Git,以及构建自动化工具Make,帮助初学者建立良好的编程习惯。 总的来...

    Android应用源码之Fanfoudroid(饭否网开源项目)-IT计算机-毕业设计.zip

    这个项目不仅涵盖了Android应用的基本架构,还涉及到网络通信、数据存储、UI设计等多方面内容,是学习Android开发的绝佳实例。 首先,从Android应用的基本架构来看,“Fanfoudroid”采用了MVP(Model-View-...

    NIDays 2004——NI攻克数据采集编程的难关播报.WMV

    NIDays 2004——NI攻克数据采集编程的难关播报WMV,该资料为视频文件,是NIDAYS 2004北京站攻克数据采集编程的难关研讨会录播,如需查看请下载。

    24学时攻克c++

    根据提供的信息,“24学时攻克C++”这本书旨在通过一系列高效的学习计划帮助读者在较短的时间内掌握C++编程语言。尽管仅上传了23页的内容,我们仍然可以从书名、描述以及部分可见的内容中推断出一些关键知识点。 ##...

    24小时攻克c++代码

    《24小时攻克C++代码》是一门针对C++编程语言深入浅出的学习教程,旨在帮助初学者在短时间内掌握C++编程基础,并逐步提升至进阶水平。C++是一种广泛应用的面向对象编程语言,它的强大功能和高效性能使得它在系统软件...

    【备战2014】高考历史 精讲巧解分类攻克18

    【备战2014】高考历史 精讲巧解分类攻克18

    攻克可穿戴医疗存储器件封装难题.doc

    可穿戴医疗设备如助听器,需要存储用户特定的校准数据、测试结果和数据日志,这通常由非易失性存储器(如EEPROM或闪存)来实现。随着设备越来越隐蔽,对存储密度的需求也随之增加。为了应对这一挑战,业界开始采用...

    基于云计算的大数据存储安全分析与研究.pdf

    云计算环境下的大数据存储安全问题直接关系到数据的价值和应用效率,因此,探讨如何安全存储大数据成为推动云计算技术发展的重要课题。 首先,云计算技术的主要特点包括存储空间广阔、计算效率高、服务优质、成本较...

    基于大数据的高维数据挖掘研究.pdf

    在大数据时代,数据存储、管理和处理成为难以攻克的难题。 2. 高维数据挖掘的必要性:高维数据挖掘是指从大型、多维的数据集中提取有用信息和知识的过程。传统数据挖掘方法在面对高维数据时,往往因为“维度的诅咒...

    24学时攻克c++_笔记

    在C++中,变量用于存储数据,而常量则用于表示固定的值。良好的编码习惯包括:每个变量单独声明,初始化变量时尽可能给予初始值,使用有意义的标识符,以及对于具有物理意义的常量使用枚举或宏定义。 ### 4. 表达式...

    医疗大数据分析应用平台.doc

    医疗数据的存储形式多种多样,例如各种结构化数据表、非(半)结构化文本文档、医疗影像等。医疗大数据对国家乃至全球的疾病防控、新药研发和顽疾攻克都有着巨大的作用。 大数据技术和云计算技术是医疗大数据分析...

    24学时攻克C++源码及习题答案

    9. **文件操作**:掌握读写文件的基本方法,实现数据的持久化存储。 10. **实践项目**:通过编写小型项目,如文本处理、图形用户界面或简单的游戏,将理论知识应用到实践中。 在压缩包中的习题和源码,应该是为了...

    8天攻克8000英语词汇

    8天攻克8000词汇,word版,方便学习,背单词的好东东

    滴滴敏捷数据中台实践.pdf

    同时,数据治理方面注重数据资产、安全合规和服务驱动,全面量化并重点攻克难点。数据文化的培养也至关重要,通过持续改进和尊重人的作用来推动数据系统的进步。 滴滴的数据基础设施包括数据系统工具链,涵盖了数据...

    大学生攻克Linux系统教程.rar

    大学生攻克Linux系统教程(又名天下没有难学的Linux)。一位在校大学生整理的教程,献给每一位要征服Linux的学习者-五星级的Linux教程。 本书汇集众多Linux学习者的心血与贡献,有很多作者在默默的为你呼喊,感谢...

    Android自动来电录音

    在Android平台上实现自动来电录音是一项技术挑战,但并非无法攻克。Android系统提供了丰富的API和工具,使得开发者可以创建各种功能丰富的应用,包括来电录音。在本文中,我们将深入探讨如何利用Android的...

    计算机考研数据结构复习指导Word版

    这份"计算机考研数据结构复习指导Word版"提供了一条有效的学习路径,帮助考生们精准定位并攻克这个领域的关键点。 复习指导文档《复习指导(数据结构部分).doc》可能涵盖了以下内容: 1. **基本概念**:数据结构...

    新东方8天攻克8000单词魔鬼训练营

    标题中的“新东方8天攻克8000单词魔鬼训练营”揭示了一个高效学习英语单词的课程项目。新东方作为知名的教育机构,以其在英语教学领域的专业性而著称,这个训练营可能是一个针对英语学习者设计的高强度、短期记忆...

Global site tag (gtag.js) - Google Analytics