【073】Android 数据存储(SQLite)
目录:
I. 使用 SharedPreferences 来存储应用程序的数据
II. 将应用程序的数据存储到内部存储器中
III. 将应用程序的数据存储到外部存储器中
IV. 通过 SQLite 数据库来实现数据存储
- SQLiteDatabase 类
- Cursor 接口
- SQLiteOpenHelper 类
- 具体操作步骤
V. Content Provider 简介
I. 使用 SharedPreferences 来存储应用程序的数据:
参考:Beginning Android 4 Application Development - Page 252
- 将数据存储到 SharedPreferences 对象中去,这个时候要用到 SharedPreferences.Editor 中的方法。
- 上面的过程会将数据存储在一个 xml 文件中。
在 DDMS 视图中找到 File Explore, 选择 data/data/<PackageName>/shared_prefs/*.xml
如下图所示:
- 通过 getSharedPreferences() 方法获取 SharedPreferences 对象,并将里面的数据取出。
举例效果:
代码功能:通过"修改文本"按钮可以将文本内容存储, 然后点击"显示文本"按钮就可以显示出刚才修改了的文本.
另外:在其他的 activity 中也可以直接的调用, 调用方法与下面的一样~
1 public class MainActivity extends Activity { 2 3 @Override 4 public void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 8 Button displayButton = (Button)findViewById(R.id.button1); 9 displayButton.setOnClickListener(new OnClickListener() { 10 11 public void onClick(View v) { 12 // TODO Auto-generated method stub 13 SharedPreferences appPreferences = getSharedPreferences( 14 "com.example.preferenceexer_preferences", MODE_PRIVATE); 15 Toast.makeText(MainActivity.this, appPreferences.getString("editTextPref", ""), Toast.LENGTH_SHORT).show(); 16 } 17 }); 18 19 Button modifyButton = (Button)findViewById(R.id.button2); 20 modifyButton.setOnClickListener(new OnClickListener() { 21 22 public void onClick(View v) { 23 // TODO Auto-generated method stub 24 SharedPreferences appPreferences = getSharedPreferences( 25 "com.example.preferenceexer_preferences", MODE_PRIVATE); 26 SharedPreferences.Editor prefsEditor = appPreferences.edit(); 27 prefsEditor.putString("editTextPref", ((EditText)findViewById(R.id.editText1)).getText().toString()); 28 prefsEditor.commit(); 29 } 30 }); 31 } 32 }
SharedPreferences 接口:
1. Interface for accessing and modifying preference data returned by getSharedPreferences(String, int).
getSharedPreferences(String, int):返回值:SharedPreferences
第一个参数:就是存储文件的名称, 一般以 <PackageName>_preferences 的格式, 其他应该也是可以的
第二个参数:0 代表 MODE_PRIVATE, 只允许此程序使用. 还有其他的常量.
2. SharedPreferences Methods:
- edit():返回值:SharedPreferences.Editor. 进入编辑模式.
- contains(String key):检查是否存在指定的键.
- getAll():返回值:Map<String, ?>. 从 preferences 中取回所有的值.
- getBoolean(String key, boolean defValue):取回布尔值, 第二个为参数默认值.
- getFloat(String key, float defValue):
- getInt(String key, int defValue):
- getLong(String key, long defValue):
- getString(String key, String defValue):取回字符串, 第二个参数为默认值.
- getStringSet(String key, Set<String> defValues):
SharedPreferences.Editor 接口:
1. 用来修改 SharedPreferences 对象的值。
2. SharedPreferences.Editor Methods:
- commit():提交修改的内容.
- apply():同上.
- remove(String key):删除指定的键.
- clear():全部清空.
- putBoolean(String key, boolean value):加入布尔值.
- putFloat(String key, float value):
- putInt(String key, int value):
- putLong(String key, long value):
- putString(String key, String value):加入字符串.
- putStringSet(String key, Set<String> values):
II. 将应用程序的数据存储到内部存储器中:
参考:Beginning Android 4 Application Development - Page 263
效果图:
在 DDMS 视图中找到 File Explore, 选择 data/data/<PackageName>/files/textfile.txt
如下图所示:
public class FilesActivity extends Activity {EditText textBox;static final int READ_BLOCK_SIZE = 100; //字符数组 @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);textBox = (EditText) findViewById(R.id.txtText1);}public void onClickSave(View view) {String str = textBox.getText().toString();try{ FileOutputStream fOut = openFileOutput("textfile.txt", MODE_WORLD_READABLE); //文件输出流OutputStreamWriter osw = new OutputStreamWriter(fOut); osw.write(str); osw.close(); Toast.makeText(getBaseContext(), "File saved successfully!", Toast.LENGTH_SHORT).show();textBox.setText(""); }catch (IOException ioe){ioe.printStackTrace();}}public void onClickLoad(View view) {try{FileInputStream fIn = openFileInput("textfile.txt"); //文件写入流InputStreamReader isr = new InputStreamReader(fIn);char[] inputBuffer = new char[READ_BLOCK_SIZE];String s = "";int charRead;while ((charRead = isr.read(inputBuffer))>0){String readString = String.copyValueOf(inputBuffer, 0, charRead);s += readString;inputBuffer = new char[READ_BLOCK_SIZE];} textBox.setText(s);Toast.makeText(getBaseContext(), "File loaded successfully!", Toast.LENGTH_SHORT).show(); }catch (IOException ioe) {ioe.printStackTrace();}} }
源文件下载:Files.zip
III. 将应用程序的数据存储到外部存储器中:
参考:Beginning Android 4 Application Development - Page 268
效果图:
在 DDMS 视图中找到 File Explore, 选择 mnt/sdcard/MyFiles/textfile.txt
如下图所示:
public class FilesActivity extends Activity {EditText textBox;static final int READ_BLOCK_SIZE = 100; @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);textBox = (EditText) findViewById(R.id.txtText1);}public void onClickSave(View view) {String str = textBox.getText().toString();try{//---SD Card Storage---File sdCard = Environment.getExternalStorageDirectory();File directory = new File (sdCard, "MyFiles");directory.mkdirs();File file = new File(directory, "textfile.txt");FileOutputStream fOut = new FileOutputStream(file); FileWriter fileWriter = new FileWriter(file);BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);bufferedWriter.write(str);bufferedWriter.close();Toast.makeText(getBaseContext(), "File saved successfully!", Toast.LENGTH_SHORT).show();textBox.setText("");}catch (IOException ioe){ioe.printStackTrace();}}public void onClickLoad(View view) {try{//---SD Storage---File sdCard = Environment.getExternalStorageDirectory();File directory = new File (sdCard.getAbsolutePath() + "/MyFiles");File file = new File(directory, "textfile.txt");FileInputStream fIn = new FileInputStream(file);InputStreamReader isr = new InputStreamReader(fIn); FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);char[] inputBuffer = new char[100];String strSum = "";int charRead;while ((charRead = bufferedReader.read(inputBuffer)) > 0) {strSum += new String(inputBuffer);}bufferedReader.close();textBox.setText(strSum);Toast.makeText(getBaseContext(), "File loaded successfully!", Toast.LENGTH_SHORT).show();}catch (IOException ioe) {ioe.printStackTrace();}} }
源文件下载:Files.zip
IV. 通过 SQLite 数据库来实现数据存储:
参考:Beginning Android 4 Application Development - Page 273
※ 参考:Android之SQlite存储
☀-☀ → SQLiteDatabase 类:
java.lang.Object
↳ android.database.sqlite.SQLiteClosable
↳ android.database.sqlite.SQLiteDatabase
- execSQL(String sql):执行没有返回结果的 SQL 语句.
- insert(String table, String nullColumnHack, ContentValues values):插入数据. 返回 ID 值(long).
第一个参数:欲插入行的表的名称.
第二个参数:直接 null.
第三个参数:包括了初始化行值的 map. key 对应列名称, value 对应列的值.
ContentValues:通过 ContentValues 的 put() 方法可以键值对添加进去. - delete(String table, String whereClause, String[] whereArgs):删除数据. 返回值表示删除的个数(int).
第二个参数:WHERE 语句内容, null 将删除所有列.
第三个参数:null. - update(String table, ContentValues values, String whereClause, String[] whereArgs):更新数据. 返回值为受影响的行数(int).
- rawQuery(String sql, String[] selectionArgs):返回值:Cursor.
第一个参数:SQL 查询语句, 语句结尾要有分号";"结束. - query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy):查询, 返回值:Cursor.
第一个参数:欲查询的表名称.
第二个参数:想要得到返回值的列的 list. 传递 null 则返回所有列.
第三个参数:类似一个 SQL WHERE 语句(不包括关键字, 下面一样), null 则返回所有的行.
第四个参数:用来替换文本的, 就给个 null 好了.
第五个参数:SQL GROUP BY 语句, null 则不排序.
第六个参数:SQL HAVING 语句, 不用就 null.
第七个参数:SQL ORDER BY 语句, 不用就 null. - query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit):
第八个参数:LIMIT 语句. 限制返回查询的行的个数. - query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit):
第一个参数:true 则返回的每一行是惟一的, 否则为 false.
☀-☀ →Cursor 接口:
- getColumnCount():获取所有列数.
- getColumnIndex(String columnName):通过列名称查找列索引.
- getColumnName(int columnIndex):
- getColumnNames():返回值:String[]. 返回所有列名的数组.
- getCount():返回所有的行数.
- getPosition():返回当前位于此行集合中的位置.
- getExtras():返回值:Bundle.
- getDouble(int columnIndex):
- getFloat(int columnIndex):
- getInt(int columnIndex):
- getLong(int columnIndex):
- getShort(int columnIndex):
- getString(int columnIndex):
- getType(int columnIndex):
- isBeforeFirst():返回是否现在指针指在第一行之前.
- isAfterLast():返回是否现在指针指在最后一行之后.
- isFirst():返回指针是否指在第一行.
- isLast():返回指针是否指在最后一行.
- isNull(int columnIndex):返回指定列是否为空.
- isClosed():返回此指针是否关闭.
- move(int offset):指针从当前位置向前或向后移动一定的行数.
- moveToFirst():将指针移动到第一行.
- moveToLast():将指针移动到最后一行.
- moveToPrevious():将指针向前移动一行.
- moveToNext():将指针向后移动一行.
- moveToPosition(int position):将指针移动到指定的行位置.
☀-☀ → SQLiteOpenHelper 类:
java.lang.Object
↳ android.database.sqlite.SQLiteOpenHelper
- close():关闭任何打开的数据库对象.
- getDatabaseName():返回正在运行的 SQLite 数据库的名称.
- getReadableDatabase():返回值:SQLiteDatabase. 创建 和/或 打开一个数据库.
- getWritableDatabase():返回值:SQLiteDatabase. 创建 和/或 打开一个数据库, 这个数据库将被读和写.
- onOpen(SQLiteDatabase db):当数据库运行的时候执行.
- onCreate(SQLiteDatabase db):当数据库第一次创建的时候执行.
- onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion):当数据库需要升级的时候执行.
效果展示:
数据库被默认存储在 data/data/<Package_Name>/databases 文件夹内部:
MyDB 中显示的内容如下:
第一步:新建一个 DBAdapter 类, 写入操作数据库的各种方法.
public class DBAdapter {static final String KEY_ROWID = "_id";static final String KEY_NAME = "name";static final String KEY_EMAIL = "email";static final String TAG = "DBAdapter";static final String DATABASE_NAME = "MyDB";static final String DATABASE_TABLE = "contacts";static final int DATABASE_VERSION = 2;static final String DATABASE_CREATE ="create table contacts (_id integer primary key autoincrement, "+ "name text not null, email text not null);";final Context context;DatabaseHelper DBHelper;SQLiteDatabase db;public DBAdapter(Context ctx){this.context = ctx;DBHelper = new DatabaseHelper(context);}private static class DatabaseHelper extends SQLiteOpenHelper{DatabaseHelper(Context context){super(context, DATABASE_NAME, null, DATABASE_VERSION); //新建数据库文件}@Overridepublic void onCreate(SQLiteDatabase db){try {db.execSQL(DATABASE_CREATE); //创建数据库表} catch (SQLException e) {e.printStackTrace();}}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){Log.w(TAG, "Upgrading database from version " + oldVersion + " to "+ newVersion + ", which will destroy all old data");db.execSQL("DROP TABLE IF EXISTS contacts");onCreate(db);}}//---opens the database---public DBAdapter open() throws SQLException {db = DBHelper.getWritableDatabase(); //为 SQLiteDatabase 赋值.return this;}//---closes the database---public void close() {DBHelper.close();}//---insert a contact into the database---public long insertContact(String name, String email) {ContentValues initialValues = new ContentValues();initialValues.put(KEY_NAME, name);initialValues.put(KEY_EMAIL, email);return db.insert(DATABASE_TABLE, null, initialValues);}//---deletes a particular contact---public boolean deleteContact(long rowId) {return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;}//---retrieves all the contacts---public Cursor getAllContacts(){return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,KEY_EMAIL}, null, null, null, null, null);}//---retrieves a particular contact---public Cursor getContact(long rowId) throws SQLException {Cursor mCursor =db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,null, null, null, null);if (mCursor != null) {mCursor.moveToFirst();}return mCursor;}//---updates a contact---public boolean updateContact(long rowId, String name, String email) {ContentValues args = new ContentValues();args.put(KEY_NAME, name);args.put(KEY_EMAIL, email);return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;} }
第二步:在 activity 中调用.
public class DatabasesActivity extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);DBAdapter db = new DBAdapter(this); //下面实现文件从 assets 文件夹中赋值到指定的程序目录中去. try {String destPath = "/data/data/" + getPackageName() +"/databases";File f = new File(destPath);if (!f.exists()) { f.mkdirs();f.createNewFile();//---copy the db from the assets folder into // the databases folder---CopyDB(getBaseContext().getAssets().open("mydb"),new FileOutputStream(destPath + "/MyDB"));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}//---get all contacts--- db.open();Cursor c = db.getAllContacts();if (c.moveToFirst()){do {DisplayContact(c);} while (c.moveToNext());}db.close();}public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException {//---copy 1K bytes at a time---byte[] buffer = new byte[1024];int length;while ((length = inputStream.read(buffer)) > 0) {outputStream.write(buffer, 0, length);}inputStream.close();outputStream.close();}public void DisplayContact(Cursor c){Toast.makeText(this, "id: " + c.getString(0) + "\n" + "Name: " + c.getString(1) + "\n" +"Email: " + c.getString(2), Toast.LENGTH_LONG).show();} }
源文件下载: Databases.zip
下面展示一些常用操作的实现代码:
INSERT - 插入数据
public long insertContact(String name, String email) {ContentValues initialValues = new ContentValues();initialValues.put(KEY_NAME, name);initialValues.put(KEY_EMAIL, email);return db.insert(DATABASE_TABLE, null, initialValues); }
//---add a contact--- db.open(); long id = db.insertContact("Wei-Meng Lee", "weimenglee@learn2develop.net"); id = db.insertContact("Mary Jackson", "mary@jackson.com"); db.close();
SELECT - 选择语句
public Cursor getAllContacts() {return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,KEY_EMAIL}, null, null, null, null, null); //null 为返回全部. }
//--get all contacts--- db.open(); Cursor c = db.getAllContacts(); if (c.moveToFirst()) {do {DisplayContact(c);} while (c.moveToNext()); } db.close();
SELECT - 选择语句 & WHERE - 筛选语句
public Cursor getContact(long rowId) throws SQLException {Cursor mCursor =db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null, //此处为 where 语句的内容.null, null, null, null);if (mCursor != null) {mCursor.moveToFirst();}return mCursor; }
//---get a contact--- db.open(); Cursor c = db.getContact(2); if (c.moveToFirst()) DisplayContact(c); elseToast.makeText(this, "No contact found", Toast.LENGTH_LONG).show(); db.close();
UPDATE - 更新语句
public boolean updateContact(long rowId, String name, String email) {ContentValues args = new ContentValues();args.put(KEY_NAME, name);args.put(KEY_EMAIL, email);return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; }
//---update contact--- db.open(); if (db.updateContact(1, "Wei-Meng Lee", "weimenglee@gmail.com"))Toast.makeText(this, "Update successful.", Toast.LENGTH_LONG).show(); elseToast.makeText(this, "Update failed.", Toast.LENGTH_LONG).show(); db.close();
DELETE - 删除语句
public boolean deleteContact(long rowId) {return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; //null 为删除全部. }
//---delete a contact--- db.open(); if (db.deleteContact(1))Toast.makeText(this, "Delete successful.", Toast.LENGTH_LONG).show(); elseToast.makeText(this, "Delete failed.", Toast.LENGTH_LONG).show(); db.close();
查询指定名称的个数.
public int queryStudentBySid(String sid) {Cursor cursor = SQLiteDB.query(DATABASE_TABLE_NAME, null, KEY_SID + "=" + sid, null, null, null, null);return cursor.getCount(); }
ORDER BY - 排序语句 (DESC & ASC)
public Cursor ascendStudents() {Cursor cursor = SQLiteDB.query(DATABASE_TABLE_NAME, new String[]{KEY_ID, KEY_SID, KEY_NAME, KEY_GENDER, KEY_HOMETOWN}, null, null, null, null, KEY_SID);if (cursor != null) {cursor.moveToFirst();}return cursor; }
public Cursor descendStudents() {Cursor cursor = SQLiteDB.query(DATABASE_TABLE_NAME, new String[]{KEY_ID, KEY_SID, KEY_NAME, KEY_GENDER, KEY_HOMETOWN}, null, null, null, null, KEY_SID + " DESC"); //order by 语句内容.if (cursor != null) {cursor.moveToFirst();}return cursor; }
V. Content Provider 使用简介:
参考:Beginning Android 4 Application Development - Page 293
1. Content Provider 主要是用来获取其他程序的信息,例如可以取得通讯录中的内容等。
※ 参考:总结Content Provider的使用
public class McProvider extends ListActivity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_mc_provider);Uri allContactsUri = Uri.parse("conten://contacts/people");Cursor cursor; if (android.os.Build.VERSION.SDK_INT < 11) {cursor = managedQuery(allContactsUri, null, null, null, null);}else {CursorLoader cursorLoader = new CursorLoader(this, allContactsUri, null, null, null, null);cursor = cursorLoader.loadInBackground();}String[] columns = new String[] {ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts._ID};int[] views = new int[] {R.id.contactName,R.id.contactID};SimpleCursorAdapter adapter;if (android.os.Build.VERSION.SDK_INT < 11) {adapter = new SimpleCursorAdapter(this, R.layout.activity_mc_provider, cursor, columns, views);}else {adapter = new SimpleCursorAdapter(this, R.layout.activity_mc_provider, cursor, columns, views, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);}this.setListAdapter(adapter);}
转载于:https://www.cnblogs.com/alex-bn-lee/archive/2012/08/19/2646846.html
【073】Android 数据存储(SQLite)相关推荐
- Android数据存储——SQLite数据库(模板)
本篇整合Android使用数据库,要保存一个实体类的样本. 首先看一下数据库语句: ORM:关系对象映射 添加数据: ContentValues values = new ContentValues( ...
- [Android Studio]Android 数据存储--SQLite数据库存储
- Android App开发基础篇—数据存储(SQLite数据库)
Android App开发基础篇-数据存储(SQLite数据库) 前言:Android中提供了对SQLite数据库的支持.开发人员可以在应用中创建和操作自己的数据库来存储数据,并对数据进行操作. 一. ...
- 【Android数据存储】ContentProvider详细介绍(附实例源码)
1.ContentProvider是什么? ContentProvider--内容提供者.它是一个类,这个类主要是对Android系统中进行共享的数据进行包装,并提供了一组统一的访问接口供其他程序调用 ...
- Android数据存储之GreenDao 3.0 详解
前言: 今天一大早收到GreenDao 3.0 正式发布的消息,自从2014年接触GreenDao至今,项目中一直使用GreenDao框架处理数据库操作,本人使用数据库路线 Sqlite----> ...
- Android数据存储:Shared Preferences
Android数据存储之SharedPreferences 在Android系统中提供了多种存储技术.通过这些存储技术可以将数据存储在各种存储介质上, Android 为数据存储提供了如下几种方式: ...
- android+默认存储,Android 数据存储之SP存储,内部存储,外部存储
Android 数据存储之SP存储,内部存储,外部存储 Android提供了多种数据存储的技术来永久的保存应用数据,以便于开发者能够根据自己的需求来选择合适的数据存储方案,主要有SharedPrefe ...
- Android数据存储安全实践
0x00 数据安全 Android操作系统自问世以来凭借其开放性和易用性成为当前智能手机的主流操作系统之一,作为与人们关系最密切的智能设备,越来越多的通讯录.短信.视频等隐私数据以明文的方式保存在手机 ...
- Android数据存储几种方式用法总结
Android数据存储几种方式用法总结 1.概述 Android提供了5种方式来让用户保存持久化应用程序数据.根据自己的需求来做选择,比如数据是否是应用程序私有的,是否能被其他程序访问,需要多少数据存 ...
最新文章
- 除了负载均衡,Nginx 还可以做很多:限流、缓存、黑白名单等
- Spring 系列,第 2 部分: 当 Hibernate 遇上 Spring
- android之Itent.ACTION_PICK Intent.ACTION_GET_CONTENT妙用
- Linux操作(3)—— 重定向操作
- 史上最全Java多线程面试题
- 数据库的增删改查和使用流程
- Bootstrap 警告框插件Alert
- 编写函数main求3!+6!+9!python_Python day 6(3) Python 函数式编程1
- 墨刀 vs Axure RP
- 变革中的思索,思索中的变革
- BZOJ2190 [SDOI2008]仪仗队
- 使用xshell连接腾讯云服务器
- matlab中的代数环问题及其消除方法,Matlab中的代数环问题及其消除方法.pdf
- 今之君子,其责人也详,其待己也廉
- 海康三维视频融合监控软件系统免费版,支持移动侦测告警
- 论文研读-社交媒体可视化-地图隐喻转发地图R-Map
- 基于 OE、Yocto、Arago 构建 TI 板卡的定制文件系统
- 解决Android 8.0和9.0无法获取SSID (unknow ssid)
- 能把晦涩难懂的研究工作讲清楚,Distill就奖你10000美刀
- error [XXX.zip]: start of central directory not found; zipfile corrup