由于要用到关于保存图片的问题,所以就顺便翻译一下api文档中的这篇文章了。
Android provides several options for you to save persistent application data. The solution you choose depends on your specific needs, such as whether the data should be private to your application or accessible to other applications (and the user) and how much space your data requires.
Your data storage options are the following:
Android提供了几种选择给我们来保存现在应用的数据,你所选择的方法取决于你确切的需求,例如你的数据是否是对你的应用是私密的,还是对其他的应用也是可以得到的,和你所存储的数据需要多大的空间。
你的数据存储有以下几种选择
Shared Preferences
以键值对的形式存储我们的私密数据。
内部存储
将数据保存在设备的存储空间
外部空间
将数据保存在外部的可存储分享设备上
sql数据库
保存一些有组织结构的私密数据
网络连接
保存一些网页上的数据到你的网络服务器中。
Android provides a way for you to expose even your private data to other applications — with a content provider. A content provider is an optional component that exposes read/write access to your application data, subject to whatever restrictions you want to impose. For more information about using content providers, see the Content Providers documentation.
Android本身提供了一个方法帮助你去将自己私密的数据暴漏给其他的应用通过content provider,一个content provider 是一个可选择的组件用来暴露读写我们应用数据的权利,根据我们自己定制的数据暴露的限制。
The SharedPreferences
class provides a general framework that allows you to save and retrieve persistent key-value pairs of primitive data types. You can use SharedPreferences
to save any primitive data: booleans, floats, ints, longs, and strings. This data will persist across user sessions (even if your application is killed).
Shared preferences are not strictly for saving "user preferences," such as what ringtone a user has chosen. If you're interested in creating user preferences for your application, seePreferenceActivity
, which provides an Activity framework for you to create user preferences, which will be automatically persisted (using shared preferences).
To get a SharedPreferences
object for your application, use one of two methods:
getSharedPreferences()
- Use this if you need multiple preferences files identified by name, which you specify with the first parameter.getPreferences()
- Use this if you need only one preferences file for your Activity. Because this will be the only preferences file for your Activity, you don't supply a nameSharePreferences类提供了一个综合的框架它允许我们保存和查询一些现在的一些简单的数据类型的键值对,你可以利用SharedPreferences来保存的数据类型有,Boolean,floats,ints等。这些数据将会通过用户的sessions存留,尽管你的应用被kill掉了。为你的应用获得sharedPreference对象,可以使用下面两种方法:getSharedPreferences(),如果你需要一个多参数通过名字进行的确认的文件,你可以通过第一个参数进行确认。getpreferences()如果你的activity仅仅只需要一个参数文件使用这个方法,以为这个将会是唯一的参数文件对你的activity,你不能够为其提供一个名字。下面是代码实例:
To write values:
edit()
to get a SharedPreferences.Editor
.putBoolean()
and putString()
.commit()
To read values, use SharedPreferences
methods such as getBoolean()
and getString()
.
Here is an example that saves a preference for silent keypress mode in a calculator:
1.通过edit()方法得到一个sharedPreferences.Editor2.添加一个值比如putBoolean()等
3.置入新的值通过commit()方法。
要读取一些值得话,可以通过getBoolean()等方法。
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
@Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
}
}
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.
你可以直接将文件保存在设备内部的存储空间中,默认的,文件将会被保存到内部存储空间,对你的应用是私密的和其它的应用是不能够获取到他们的,当用户卸载掉应用之后数据将会被删除。
创建一个私密文件夹并写进去数据。
To create and write a private file to the internal storage:
openFileOutput()
with the name of the file and the operating mode. This returns a FileOutputStream
.write()
.close()
.For example:
String FILENAME = "hello_file"; String string = "hello world!"; FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(string.getBytes()); fos.close();
MODE_PRIVATE
will create the file (or replace a file of the same name) and make it private to your application. Other modes available are: MODE_APPEND
, MODE_WORLD_READABLE
, and MODE_WORLD_WRITEABLE
.
MODE_PRIVATE
将会创建一个文件(或者是取代同名的文件)然后让这个文件成为对你的应用私密的,其它的可用的模式还有:
MODE_APPEND
, MODE_WORLD_READABLE
, and MODE_WORLD_WRITEABLE
.
从内部存储空间读取一个文件
To read a file from internal storage:
openFileInput()
and pass it the name of the file to read. This returns a FileInputStream
.read()
.close()
. Tip: If you want to save a static file in your application at compile time, save the file in your project res/raw/
directory. You can open it with openRawResource()
, passing the R.raw.
resource ID. This method returns an InputStream
that you can use to read the file (but you cannot write to the original file).
如果你想保存一些静态的文件在你的应用中在编译的时间,保存你的文件在你的项目中res/raw的目录下,你可以通过使用openRawResource()来打开文件,通过这些文件的ID来对其进行调用,这个方法将会返回一个输入流来帮助你使用读取文件,但是你不能够向这些文件中写入。
If you'd like to cache some data, rather than store it persistently, you should use getCacheDir()
to open a File
that represents the internal directory where your application should save temporary cache files.
When the device is low on internal storage space, Android may delete these cache files to recover space. However, you should not rely on the system to clean up these files for you. You should always maintain the cache files yourself and stay within a reasonable limit of space consumed, such as 1MB. When the user uninstalls your application, these files are removed.
保存缓冲文件
如果你希望通过缓存的方式来保存这些数据,而不是长久的将其进行保存,你应该使用getCacheDir()方法来实现去打开一个文件在这里你的应用应该保存一些暂时的缓存文件。
getFilesDir()
getDir()
deleteFile()
fileList()
getFileDir(),获得一个绝对路径到达你内部文件存储的目录下。
getDir(),在你的存储空间中创造一个目录。
deleteFile(),删除你在内部存储空间保存的文件。
fileList(),返回一个通过你的应用保存的文件的数组。
Every Android-compatible device supports a shared "external storage" that you can use to save files. This can be a removable storage media (such as an SD card) or an internal (non-removable) storage. Files saved to the external storage are world-readable and can be modified by the user when they enable USB mass storage to transfer files on a computer.
Caution: External storage can become unavailable if the user mounts the external storage on a computer or removes the media, and there's no security enforced upon files y ou save to the external storage. All applications can read and write files placed on the external storage and the user can remove them.
注意:外部存储设备可能变成不可用,如果用户将外部存储设备在电脑上进行加载或者说移除文件,这就是我们将其保存在外部存储设备上不安全的地方,所有的应用都可以读取,修改文件。
In order to read or write files on the external storage, your app must acquire the READ_EXTERNAL_STORAGE
orWRITE_EXTERNAL_STORAGE
system permissions. For example:
...
If you need to both read and write files, then you need to request only the WRITE_EXTERNAL_STORAGE
permission, because it implicitly requires read access as well.
Note: Beginning with Android 4.4, these permissions are not required if you're reading or writing only files that are private to your app. For more information, see the section below about saving files that are app-private.
如果你需要读取文件的和写文件,那么你需要仅仅WRITE_EXTERNAL_STORAGE这一个权限。
Before you do any work with the external storage, you should always call getExternalStorageState()
to check whether the media is available. The media might be mounted to a computer, missing, read-only, or in some other state. For example, here are a couple methods you can use to check the availability:
/* 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;
}
getExternalStorageState()
method returns other states that you might want to check, such as whether the media is being shared (connected to a computer), is missing entirely, has been removed badly, etc. You can use these to notify the user with more information when your application needs to access the media.
这个方法返回另一个状态,你可能需要检测的,列入是否连接到电脑,是否丢失或者移除扥等,你可以使用这些去提醒你的用户使用更多的消息当你的应用需要使用这些的时候。
Include an empty file named .nomedia
in your external files directory (note the dot prefix in the filename). This prevents media scanner from reading your media files and providing them to other apps through the MediaStore
content provider. However, if your files are truly private to your app, you should save them in an app-private directory.
Generally, new files that the user may acquire through your app should be saved to a "public" location on the device where other apps can access them and the user can easily copy them from the device. When doing so, you should use to one of the shared public directories, such as Music/
, Pictures/
, and Ringtones/
.
保存可以被其它app分享的文件
通常,用户获得一些新的文件可能需要通过你的app应该被保存为公共的位置在你的设备上,其它的app'也可以访问他们,复制他们从设备上,当这么做的时候,我们应该使用一个分享的公用目录。
To get a File
representing the appropriate public directory, callgetExternalStoragePublicDirectory()
, passing it the type of directory you want, such as DIRECTORY_MUSIC
, DIRECTORY_PICTURES
,DIRECTORY_RINGTONES
, or others. By saving your files to the corresponding media-type directory, the system's media scanner can properly categorize your files in the system (for instance, ringtones appear in system settings as ringtones, not as music).
为了获得一个代表正确公共目录的文件,我们调用getExternalStoragePublicDirectory()这个方法通过你想得到的目录类型,比如说,
DIRECTORY_MUSIC
, DIRECTORY_PICTURES
,DIRECTORY_RINGTONES或者是其它的,系统通过扫描会正确的将在系统中的文件夹进行分类整理。
例如这里是一个创建一个目录为一个新的相册,在公共相册的目录。
For example, here's a method that creates a directory for a new photo album in the public pictures directory:
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;
}
If you are handling files that are not intended for other apps to use (such as graphic textures or sound effects used by only your app), you should use a private storage directory on the external storage by callinggetExternalFilesDir()
. This method also takes a type
argument to specify the type of subdirectory (such asDIRECTORY_MOVIES
). If you don't need a specific media directory, pass null
to receive the root directory of your app's private directory.
如果你要处理的文件并不是给其它的app用的,比如图形纹理或者是音效在你的app中,你应该用一个私密的存储目录在外部存储上通过使用方法getExternalFilesDir(),这个方法也带有一个类型内容提要来表明子目录下所存储文件的类型,如果你不需要一个确认的媒体目录,传一个null值接收你app的私密目录下的根目录。
Beginning with Android 4.4, reading or writing files in your app's private directories does not require theREAD_EXTERNAL_STORAGE
or WRITE_EXTERNAL_STORAGE
permissions. So you can declare the permission should be requested only on the lower versions of Android by adding the maxSdkVersion
attribute:
从Android 4.4开始,从你的app私密目录下读写文件不需要READ_EXTERNAL_STORAGE
or WRITE_EXTERNAL_STORAGE这两个权限了,因此你仅需要在一些低版本的Android中加上这些属性。
...
Note: When the user uninstalls your application, this directory and all its contents are deleted. Also, the system media scanner does not read files in these directories, so they are not accessible from the MediaStore
content provider. As such, you should not use these directories for media that ultimately belongs to the user, such as photos captured or edited with your app, or music the user has purchased with your app—those files should be saved in the public directories.
当你卸载你的app的时候,这个目录和你的内容都会本删除,当然你的系统媒体查看器不能够从这些文件中读取出来,因此它们通过MediaStore
content provider是不能够获得的,同样的,比如当我们通过我们的app拍的照片或者是编辑的内容,或者是用户在app上购买的音乐,这些文件应该将其存在公共的目录下。
Sometimes, a device that has allocated a partition of the internal memory for use as the external storage may also offer an SD card slot. When such a device is running Android 4.3 and lower, the getExternalFilesDir()
method provides access to only the internal partition and your app cannot read or write to the SD card. Beginning with Android 4.4, however, you can access both locations by calling getExternalFilesDirs()
, which returns a File
array with entries each location. The first entry in the array is considered the primary external storage and you should use that location unless it's full or unavailable. If you'd like to access both possible locations while also supporting Android 4.3 and lower, use the support library's static method,ContextCompat.getExternalFilesDirs()
. This also returns a File
array, but always includes only one entry on Android 4.3 and lower.
大多时候,一个设备上都会有单独隔离出来的区域作为外部存储,或者有预留的sd卡的卡槽,例如,当我们在Android 4.3或者更低的版本上运行的时候, getExternalFilesDir()这个方法就会提供一个通道,仅仅在你的内部存储的隔离区而且你的app是无法从sd卡上进行读写操作的,在Android 4.4之前,然后你可以得到地址通过调用
getExternalFilesDirs()方法,这个方法将会返回一个文件数组带有把每一个地址的入口,
Caution Although the directories provided by getExternalFilesDir()
and getExternalFilesDirs()
are not accessible by the MediaStore
content provider, other apps with the READ_EXTERNAL_STORAGE
permission can access all files on the external storage, including these. If you need to completely restrict access for your files, you should instead write your files to the internal storage.
To open a File
that represents the external storage directory where you should save cache files, callgetExternalCacheDir()
. If the user uninstalls your application, these files will be automatically deleted.
Similar to ContextCompat.getExternalFilesDirs()
, mentioned above, you can also access a cache directory on a secondary external storage (if available) by calling ContextCompat.getExternalCacheDirs()
.
Tip: To preserve file space and maintain your app's performance, it's important that you carefully manage your cache files and remove those that aren't needed anymore throughout your app's lifecycle.
Android provides full support for SQLite databases. Any databases you create will be accessible by name to any class in the application, but not outside the application.
The recommended method to create a new SQLite database is to create a subclass of SQLiteOpenHelper
and override the onCreate()
method, in which you can execute a SQLite command to create tables in the database. For example:
public class DictionaryOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DICTIONARY_TABLE_NAME = "dictionary";
private static final String DICTIONARY_TABLE_CREATE =
"CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
KEY_WORD + " TEXT, " +
KEY_DEFINITION + " TEXT);";
DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DICTIONARY_TABLE_CREATE);
}
}
You can then get an instance of your SQLiteOpenHelper
implementation using the constructor you've defined. To write to and read from the database, call getWritableDatabase()
and getReadableDatabase()
, respectively. These both return a SQLiteDatabase
object that represents the database and provides methods for SQLite operations.
Android does not impose any limitations beyond the standard SQLite concepts. We do recommend including an autoincrement value key field that can be used as a unique ID to quickly find a record. This is not required for private data, but if you implement a content provider, you must include a unique ID using theBaseColumns._ID
constant.
You can execute SQLite queries using the SQLiteDatabase
query()
methods, which accept various query parameters, such as the table to query, the projection, selection, columns, grouping, and others. For complex queries, such as those that require column aliases, you should use SQLiteQueryBuilder
, which provides several convienent methods for building queries.
Every SQLite query will return a Cursor
that points to all the rows found by the query. The Cursor
is always the mechanism with which you can navigate results from a database query and read rows and columns.
For sample apps that demonstrate how to use SQLite databases in Android, see the Note Pad and Searchable Dictionary applications.