首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

了解 Android 本地数据存储 API 利用首选项、SQLite 和内部及外部内存 API

2012-09-05 
理解 Android 本地数据存储 API利用首选项、SQLite 和内部及外部内存 APIhttp://www.ibm.com/developerwork

理解 Android 本地数据存储 API 利用首选项、SQLite 和内部及外部内存 API

http://www.ibm.com/developerworks/cn/xml/x-androidstorage/

?

存储应用程序首选项

本节介绍 Preferences API 和屏幕。Android API 提供很多方式处理首选项。其中一种方式是直接使用 SharedPreferences,并使用您自己的屏幕设计和首选项管理。第二种方法是使用 PreferenceActivity。PreferenceActivity 自动负责首选项如何呈现在屏幕上(默认情况下,看起来跟系统首选项一样),并通过使用 SharedPreferences 在用户与每个首选项交互时自动存储或保存首选项。

?

Preferences 屏幕的 XML 声明

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen        xmlns:android="http://schemas.android.com/apk/res/android"        android:id="@+id/prefs_screen"        android:key="preferencescreen"    >    <PreferenceCategory android:title="Assets">        <EditTextPreference             android:key="@string/prefs_assetname_friendslist_key"            android:title="Friends List"             android:summary="Please enter filename"            android:defaultValue="friends.txt"        />        <EditTextPreference             android:key="@string/prefs_assetname_picture_key"            android:title="Picture"             android:summary="Please enter filename"            android:defaultValue="pict2.jpg"        />    </PreferenceCategory>    <PreferenceCategory android:title="Auto Settings">        <CheckBoxPreference            android:key="@string/prefs_autodelete_key"            android:title="Delete at Startup"             android:summary="Check to clear at startup"            android:defaultValue="false"        />    </PreferenceCategory></PreferenceScreen>

?PreferenceScreen 包含 EditTextPreference 的两个实例、一个 CheckBoxPreference 和两个由 PreferenceCategory 定义的类别组(一个用于 Asset,另一个用于 Auto Settings)。

使用 SharedPreferences

?

/////////////////////////////////////////////////////////////// The following methods show how to use the SharedPreferences//////////////////////////////////////////////////////////////** * Retrieves the Auto delete preference * @return the value of auto delete */public boolean prefsGetAutoDelete() {    boolean v = false;    SharedPreferences sprefs =        PreferenceManager.getDefaultSharedPreferences(appContext);     String key = appContext.getString(R.string.prefs_autodelete_key);    try {        v = sprefs.getBoolean(key, false);    } catch (ClassCastException e) {    }    return v;}   /** * Sets the auto delete preference * @param v the value to set */public void  prefsSetAutoDelete(boolean v) {    SharedPreferences sprefs =     PreferenceManager.getDefaultSharedPreferences(appContext);     Editor e = sprefs.edit();    String key = appContext.getString(R.string.prefs_autodelete_key);                   e.putBoolean(key, v);    e.commit();}

?

MainActivity 插入到数据库中
String fname = prefsGetFilename();if (fname != null && fname.length() > 0) {    buffer = getAsset(fname);    // Parse the JSON file    String friendslist = new String(buffer);    final JSONObject json = new JSONObject(friendslist);    JSONArray d = json.getJSONArray("data");    int l = d.length();    for (int i2=0; i2<l; i2++) {        JSONObject o = d.getJSONObject(i2);        String n = o.getString("name");        String id = o.getString("id");        dbHelper.insert(id, n);    }    // Only the original owner thread can touch its views                               MainActivity.this.runOnUiThread(new Runnable() {        public void run() {            friendsArrayAdapter.notifyDataSetChanged();        }    });         }
MainActivity Select All 和将数据绑定到 ListView
final ArrayList<Friend> dbFriends = dbHelper.listSelectAll();if (dbFriends != null) {    // Only the original owner thread can touch its views                               MainActivity.this.runOnUiThread(new Runnable() {        public void run() {            friendsArrayAdapter =             new FriendsArrayAdapter(                MainActivity.this, R.layout.rowlayout, dbFriends);            listView.setAdapter(friendsArrayAdapter);            friendsArrayAdapter.notifyDataSetChanged();        }    });}   
?从本地私有存储器读取数据???
/** * Writes content to internal storage making the content private to  * the application. The method can be easily changed to take the MODE  * as argument and let the caller dictate the visibility:  * MODE_PRIVATE, MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE, etc. *  * @param filename - the name of the file to create * @param content - the content to write */public void writeInternalStoragePrivate(        String filename, byte[] content) {    try {        //MODE_PRIVATE creates/replaces a file and makes         //  it private to your application. Other modes:        //    MODE_WORLD_WRITEABLE        //    MODE_WORLD_READABLE        //    MODE_APPEND        FileOutputStream fos =            openFileOutput(filename, Context.MODE_PRIVATE);        fos.write(content);        fos.close();    } catch (FileNotFoundException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }}
?从内部私有存储器读取数据
/** * Reads a file from internal storage * @param filename the file to read from * @return the file content */public byte[] readInternalStoragePrivate(String filename) {    int len = 1024;    byte[] buffer = new byte[len];    try {        FileInputStream fis = openFileInput(filename);        ByteArrayOutputStream baos = new ByteArrayOutputStream();        int nrb = fis.read(buffer, 0, len); // read up to len bytes        while (nrb != -1) {            baos.write(buffer, 0, nrb);            nrb = fis.read(buffer, 0, len);        }        buffer = baos.toByteArray();        fis.close();    } catch (FileNotFoundException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }    return buffer;}

?

从本地私有存储器删除数据
/** * Delete internal private file  * @param filename - the filename to delete */public void deleteInternalStoragePrivate(String filename) {    File file = getFileStreamPath(filename);    if (file != null) {        file.delete();    }}

?为公共数据使用设备的外部存储器

有了数据存储 API,您可以使用外部存储器存储数据。信息可以是私有的,您可以有选择地让其他应用程序对之具有读或写的访问权限。本节您将对此 API 进行编程,以便使用包括 getExternalStorageState()、getExternalFilesDir()、getExternalStorageDirectory() 和 getExternalStoragePublicDirectory() 在内的很多 API 来存储公共数据。您为公共数据使用下面的路径:/Android/data/<package_name>/files/。

在使用外部存储器之前,必须看看它是否可用,是否可写。下面两个代码片段展示了测试这些条件的帮助器方法。清单 23 测试外部存储器是否可用。

测试外部存储器是否可用???
/** * Helper Method to Test if external Storage is Available */public boolean isExternalStorageAvailable() {    boolean state = false;    String extStorageState = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {        state = true;    }    return state;}
?测试外部存储器是否只可读
/** * Helper Method to Test if external Storage is read only */public boolean isExternalStorageReadOnly() {    boolean state = false;    String extStorageState = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {        state = true;    }    return state;}
?写到外部内存
/** * Write to external public directory * @param filename - the filename to write to * @param content - the content to write  */public void writeToExternalStoragePublic(String filename, byte[] content) {    // API Level 7 or lower, use getExternalStorageDirectory()     //  to open a File that represents the root of the external     // storage, but writing to root is not recommended, and instead     // application should write to application-specific directory, as shown below.    String packageName = this.getPackageName();    String path = "/Android/data/" + packageName + "/files/";    if (isExternalStorageAvailable() &&        !isExternalStorageReadOnly()) {        try {            File file = new File(path, filename);            file.mkdirs();            FileOutputStream fos = new FileOutputStream(file);            fos.write(content);            fos.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}
?从外部内存读取数据
/** * Reads a file from internal storage * @param filename - the filename to read from * @return the file contents */public byte[] readExternallStoragePublic(String filename) {    int len = 1024;    byte[] buffer = new byte[len];    String packageName = this.getPackageName();    String path = "/Android/data/" + packageName + "/files/";    if (!isExternalStorageReadOnly()) {             try {            File file = new File(path, filename);                        FileInputStream fis = new FileInputStream(file);            ByteArrayOutputStream baos = new ByteArrayOutputStream();            int nrb = fis.read(buffer, 0, len); //read up to len bytes            while (nrb != -1) {                baos.write(buffer, 0, nrb);                nrb = fis.read(buffer, 0, len);            }            buffer = baos.toByteArray();            fis.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    return buffer;}
外部内存删除文件
/** * Delete external public file  * @param filename - the filename to write to */void deleteExternalStoragePublicFile(String filename) {    String packageName = this.getPackageName();    String path = "/Android/data/" + packageName + "/files/"+filename;    File file = new File(path, filename);    if (file != null) {        file.delete();    }}

?处理外部存储器需要特殊的权限 WRITE_EXTERNAL_STORAGE,它通过 AndroidManifest.xml 请求得到

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

?

外部存储 API 通过根据文件类型(比如 Pictures、Ringtones)将文件存储在预先确定的目录中,允许您公共地存储文件。本文没有介绍这种方法,但是您应该熟悉它。此外,记住外部存储器中的文件任何时候都可能消失。

如果您具有不需要长期永久保存的临时文件,那么可以将这些文件存储在高速缓存中。高速缓存是一种特殊的内存,可以用于存储中小型数据(少于兆字节),但是您一定要知道,取决于有多少内存可用,高速缓存的内容任何时候都可能被清除。

检索到内部内存高速缓存的路径
/** * Helper method to retrieve the absolute path to the application  * specific internal cache directory on the file system. These files  * will be ones that get deleted when the application is uninstalled or when  * the device runs low on storage. There is no guarantee when these  * files will be deleted. *  * Note: This uses a Level 8+ API. *  * @return the absolute path to the application specific cache  * directory */public String getInternalCacheDirectory() {    String cacheDirPath = null;    File cacheDir = getCacheDir();    if (cacheDir != null) {        cacheDirPath = cacheDir.getPath();    }    return cacheDirPath;        }
检索到外部内存高速缓存的路径
/** * Helper method to retrieve the absolute path to the application  * specific external cache directory on the file system. These files  * will be ones that get deleted when the application is uninstalled or when  * the device runs low on storage. There is no guarantee when these  * files will be deleted. *  * Note: This uses a Level 8+ API. *  * @return the absolute path to the application specific cache  * directory */public String getExternalCacheDirectory() {    String extCacheDirPath = null;    File cacheDir = getExternalCacheDir();    if (cacheDir != null) {        extCacheDirPath = cacheDir.getPath();    }    return extCacheDirPath;     }

热点排行