Saving Data 保存数据
学习使用在键值对中存储少量信息的共享首选项文件。保存相对较少的键值对集合,使用SharedPreferences。
+ Get a Handle to a SharedPreferences(获取一个SharedPreferences)
getSharedPreferences():根据第一个参数指定的名称识别的多个共享首选项文件,可以从应用中的任何 Context 调用此方法。getPreferences():使用Activity的一个共享首选项,在Activity 中使用此方法。
Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
或者
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
注意:如果创建带 MODE_WORLD_READABLE 或MODE_WORLD_WRITEABLE 的SharedPreferences文件,那么知道文件标识符的任何其他应用都可以访问您的数据。
+ Write to Shared Preferences(写入SharedPreferences)
通过调用 edit() 来创建一个 SharedPreferences.Editor。
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
学习保存基本文件,比如存储一般按顺序读取的较长数据序列 。使用 Android 文件系统通过 File API 读取和写入文件。
+ Choose Internal or External Storage(选择内部或者外部存储)
所有 Android 设备都有两个文件存储区域:“内部”和“外部”存储。
内部存储:设备提供内置的非易失性内存。外部存储:移动存储介质,比如微型 SD 卡。一些设备将永久性存储空间划分为“内部”和“外部”分区,即便没有移动存储介质,也始终有两个存储空间,并且无论外部存储设备是否可移动,API 的行为均一致。
提示:尽管应用默认安装在内部存储中,但您可在您的宣示说明中指定android:installLocation 属性,这样您的应用便可安装在在外部存储中。当 APK 非常大且它们的外部存储空间大于内部存储时,用户更青睐这个选择。
+ Obtain Permissions for External Storage(获取外部存储的权限)
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
Save a File on Internal Storage(保存文件到内部存储中)
getFilesDir():返回表示您的应用的内部目录的 File 。
getCacheDir():返回表示您的应用临时缓存文件的内部目录的 File 。
如何向文件写入一些文本:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Save a File on External Storage(保存文件到外部存储中)
调用 getExternalStorageState() 查询外部存储状态。 如果返回的状态
为 MEDIA_MOUNTED,那么可以对文件进行读写。
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
getExternalFilesDir() 获取相应的目录并向其传递指示你想要的目录类型的名称。通过这种方法创建的各个目录将添加至封装您的应用的所有外部存储文件的父目录,当用户卸载您的应用时,系统会删除这些文件。
创建个人相册的目录:
public File getAlbumStorageDir(Context context, String albumName) {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
getExternalStoragePublicDirectory() 方法获取表示外部存储上相应目录的 File 。该方法使用指定 您想要保存以便它们可以与其他公共文件在逻辑上组织在一起的文件类型的参数,比如 DIRECTORY_MUSIC 或 DIRECTORY_PICTURES。
public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
Query Free Space(查询可用空间)
系统并不保证您可以写入与 getFreeSpace() 指示的一样多的字节。如果返回的数字比您要保存的数据大小大出几 MB,或如果文件系统所占空间不到 90%,则可安全继续操作。否则,您可能不应写入存储。
Delete a File(删除文件)
如果文件保存在内部存储中,您还可以请求 Context 通过调用 deleteFile() 来定位和删除文件。
注意:当用户卸载您的应用时,Android 系统会删除以下各项:您保存在内部存储中的所有文件。您使用 getExternalFilesDir() 保存在外部存储中的所有文件。但是,您应手动删除使用 getCacheDir() 定期创建的所有缓存文件并且定期删除不再需要的其他文件。
学习使用 SQLite 数据库读写结构化数据。
注意:通过实现 BaseColumns 接口,您的内部类可继承调用的主键字段_ID ,某些 Android 类(比如光标适配器)将需要内部类拥有该字段。 这并非必需项,但可帮助您的数据库与 Android 框架协调工作。
public final class FeedReaderContract {
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
public FeedReaderContract() {}
/* Inner class that defines the table contents */
public static abstract class FeedEntry implements BaseColumns {
public static final String TABLE_NAME = "entry";
public static final String COLUMN_NAME_ENTRY_ID = "entryid";
public static final String COLUMN_NAME_TITLE = "title";
public static final String COLUMN_NAME_SUBTITLE = "subtitle";
...
}
}
注意:由于它们可能长期运行,因此请确保您在后台线程中调用 getWritableDatabase() 或 getReadableDatabase() , 比如使用 AsyncTask 或 IntentService。
public class FeedReaderDbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FeedReader.db";
public FeedReaderDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
通过将一个 ContentValues 对象传递至 insert() 方法将数据插入数据库: // Gets the data repository in write mode SQLiteDatabase db = mDbHelper.getWritableDatabase();
// Create a new map of values, where column names are the keys ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
// Insert the new row, returning the primary key value of the new row long newRowId;
newRowId = db.insert( FeedEntry.TABLE_NAME, FeedEntry.COLUMN_NAME_NULLABLE, values);
具体一些其他的数据库的增删改查操作,请自己查看了解。