Android_7_数据存数方式
Android_7_数据存数方式
使用SharedPreferences存储数据
-
获取SharedPreferences对象
-
调用Context对象的getSharedPreferences()方法
-
调用Activity对象的getPreferences()方
调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享. 调用Activity对象的getPreferences()方法获得的SharedPreferences对象只能在该Activity中使用. Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容 Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件. Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件. MODE_WORLD_READABLE:表示当前文件可以被其他应用读取. MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入
-
-
SharedPreferences存储数据
SharedPreferences只支持基本数据类型
public static boolean getBoolean(Context context, String key) { if (sp == null) { sp = context.getSharedPreferences(name, Context.MODE_PRIVATE); } return sp.getBoolean(key, false); }
封装过的使用SharedPreferences存储一个bool值对象,同理可以使用putInt,putString等方法保存其他类型的数据
文件存储数据
文件存储就是通过流的方式,把数据写到文件中,使用Context,Environment获得路径
Context常用方法目录:
方法:getFilesDir
释义:返回通过Context.openFileOutput()创建和存储的文件系统的绝对路径,应用程序文件,这些文件会在程序被卸载的时候全部删掉。
/data/data/package_name/files
方法:getDir
释义:这是一个可以存放你自己应用程序自定义的文件,你可以通过该方法返回的File实例来创建或者访问这个目录,注意该目录下的文件只有你自己的程序可以访问。
getDir("test", Context.MODE_WORLD_WRITEABLE)
/data/data/package_name/app_test
方法:getCacheDir
释义:返回应用程序指定的缓存目录,这些文件在设备内存不足时会优先被删除掉,所以存放在这里的文件是没有任何保障的,可能会随时丢掉。
/data/data/package_name/cache
方法:getExternalFilesDir
释义:使用这个方法需要写外部存储的权限“”,这个目录是与应用程序相关的外部文件系统,这些文件只属于你的应用,不能被其它人访问。同样,这个目录下的文件在程序被卸载时也会被一同删除。该方法也可以指定返回某一资源类型,这些类型可以是:
Environment#DIRECTORY_MUSIC 音乐
Environment#DIRECTORY_PODCASTS 音频
Environment#DIRECTORY_RINGTONES 铃声
Environment#DIRECTORY_ALARMS 闹铃
Environment#DIRECTORY_NOTIFICATIONS 通知铃声
Environment#DIRECTORY_PICTURES 图片
Environment#DIRECTORY_MOVIES 视频
getExternalFilesDir( "/" )
/storage/sdcard0/Android/data/package_name/files
getExternalFilesDir( Environment.DIRECTORY_PICTURES )
/storage/sdcard0/Android/data/package_name/files/Pictures
方法:getExternalCacheDir
使用这个方法需要写外部存储的权限“”,调用该方法会返回应用程序的外部文件系统(Environment.getExternalStorageDirectory())目录的绝对路径,它是用来存放应用的缓存文件,它和getCacheDir目录一样,目录下的文件都会在程序被卸载的时候被清除掉。
/storage/sdcard0/Android/data/package_name/cache
方法:getDatabasePath
释义:保存通过Context.openOrCreateDatabase 创建的数据库文件
getDatabasePath("DATABASE_NAME") )
/data/data/package_name/databases/DATABASE_NAME
方法:getPackageCodePath
释义:返回android 安装包的完整路径,这个包是一个zip的压缩文件,它包括应用程序的代码和assets文件。
/data/app/package_name-2.apk
方法:getPackageResourcePath
释义:返回android 安装包的完整路径,这个包是一个ZIP的要锁文件,它包括应用程序的私有资源。
/data/app/package_name-2.apk
方法:getObbDir
释义:返回应用程序的OBB文件目录(如果有的话),注意如果该应用程序没有任何OBB文件,这个目录是不存在的。
/storage/sdcard0/Android/obb/package_name
Environment
Environment类去获取外部存储目录,在访问外部存储之前一定要先判断外部存储是否已经是可使用(已挂载&可使用)状态。并且需要在AndroidManifest.xml文件中添加外部存储读和写的权限。
Environment类中提供了几个静态常量用于标识外部存储的状态,这些状态都是String类型
MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除。
MEDIA_CHECKING 正在检查存储媒体。
MEDIA_MOUNTED 存储媒体已经挂载,并且挂载点可读/写。
MEDIA_MOUNTED_READ_ONLY 存储媒体已经挂载,挂载点只读。
MEDIA_NOFS 存储媒体是空白或是不支持的文件系统。
MEDIA_REMOVED 存储媒体被移除。
MEDIA_SHARED 存储媒体正在通过USB共享。
MEDIA_UNMOUNTABLE 存储媒体无法挂载。
MEDIA_UNMOUNTED 存储媒体没有挂载。
可以通过静态方法getExternalStorageState()来获取外部存储的状态,如果程序需要在外部存储里面读写数据,必须要先判断。
SQLite数据库存储数据
-
SQLite是一款开源的、嵌入式关系型数据库,没有独立运行的进程,与所服务的应用程序在应用程序 进程空间内共生共存。它的代码与应用程序代码也是在一起的,或者说嵌入其中,作为托管它的程序 的一部分。因此不存在数据库的客户端和服务器,使用SQLite一般只需要带上它的一个动态库,就可 以享受它的全部功能。
-
SQLite支持的数据类型
SQLite采用动态数据存储类型,会根据存入的值自动进行判断。SQLite支持以下5种数据类型: (1)NULL:空值 (2)INTEGER:带符号的整型 (3)REAL:浮点型 (4)TEXT:字符串文本 (5)BLOB:二进制对象
-
创建SQLite数据库
创建类继承自SQLiteOpenHelper,并复写其onCreate(),onUpgrade(),onDeleteDB()方法,其中onCreate()方法会在创建数据库后调用,在这里使用sql语句建表,在onUpgrade()方法中,是数据库升级时对比版本对表或数据进行修改,onDeleteDb()是数据库被删除时回调的方法
public class AndroidSQLiteOpenHelper extends SQLiteOpenHelper { // 数据库名称 public static final String DBNAME = "android.db"; // 数据库版本 public static final int VERSION = 2; // 建表语句,大小写不敏感 private static final String CREATETABLE = "create table " + Person.TABLENAME + "(id string, name string, gender int, age int)"; public AndroidSQLiteOpenHelper(Context context) { super(context, DBNAME, null, VERSION); } // 创建表 @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATETABLE); } // 更新表 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { this.deleteDB(db); this.onCreate(db); } // 删除表 private void deleteDB(SQLiteDatabase db) { db.execSQL("drop table if exists " + Person.TABLENAME); } }
-
使用SQLite中的数据
实例化上一步中定义的SQLiteOpenHelper子类对象,调用getWritableDatabase()方法可以获得SQLiteDataBase对象,使用SQLiteDataBase对象就可以直接对数据库进行操作了
public DatabaseManager(Context context) { dbHelper = new AndroidSQLiteOpenHelper(context); } // 插入记录 public int insert(Person person) { Log.e("SQLite", "----insert----"); SQLiteDatabase db = dbHelper.getWritableDatabase(); db.beginTransaction(); try { db.execSQL("insert into " + Person.TABLENAME + " values(?, ?, ?, ?)", new Object[] { person.id, person.name, person.gender, person.age }); db.setTransactionSuccessful(); } catch (Exception e) { return 0; } finally { db.endTransaction(); } db.close(); return 1; } // 删除记录 public int delete(Person person) { Log.e("SQLite", "----delete----"); SQLiteDatabase db = dbHelper.getWritableDatabase(); db.beginTransaction(); try { db.execSQL("delete from " + Person.TABLENAME + " where id = ?", new Object[] { person.id }); db.setTransactionSuccessful(); } catch (Exception e) { return 0; } finally { db.endTransaction(); } db.close(); return 1; } // 更新记录 public int update(Person person) { Log.e("SQLite", "----update----"); SQLiteDatabase db = dbHelper.getWritableDatabase(); db.beginTransaction(); try { db.execSQL("update " + Person.TABLENAME + " set name=?, gender=?, age=? where id=?", new Object[] { person.name, person.gender, person.age, person.id }); db.setTransactionSuccessful(); } catch (Exception e) { return 0; } finally { db.endTransaction(); } db.close(); return 1; } // 查询记录 public ArrayList<Person> query(String id) { Log.e("SQLite", "----query----"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor; Person person; ArrayList<Person> list = new ArrayList<Person>(); // 若fileId为null或""则查询所有记录 if (id == null || id.equals("")) { cursor = db.rawQuery("select * from " + Person.TABLENAME, null); } else { cursor = db.rawQuery("select * from " + Person.TABLENAME + " where id=?", new String[] { id }); } while (cursor.moveToNext()) { person = new Person(); person.id = cursor.getString(cursor.getColumnIndex("id")); person.name = cursor.getString(cursor.getColumnIndex("name")); person.gender = cursor.getString(cursor.getColumnIndex("gender")); person.age = cursor.getInt(cursor.getColumnIndex("age")); Log.e("SQLite", person.toString()); list.add(person); } cursor.close(); db.close(); if (list.size() == 0) { Log.e("SQLite", "****表中无数据****"); } return list; } }
网络存储数据
所谓网络存储就是把数据存储到服务器上,这个过程需要使用网络请求
使用ContentProvider存储数据
-
ContentProvider作为Android四大组件之一,一般自己很少定义ContentProvider,现多用在访问系统提供的数据上,ContentProvider可以实现在应用程序之间共享数据.
1、ContentProvider使用表的形式来组织数据,无论数据的来源是什么,ContentProvider都会认为是一种表,然后把数据组织成表格 2、ContentProvider提供的方法 query:查询 insert:插入 update:更新 delete:删除 getType:得到数据类型 onCreate:创建数据时调用的回调函数
-
使用步骤
1、 定义一个CONTENT_URI常量(里面的字符串必须是唯一)
Public static final Uri CONTENT_URI = Uri.parse("content://com.MyContentprovider"); 如果有子表,URI为: Public static final Uri CONTENT_URI = Uri.parse("content://com.MyContentProvider/users");
2、 定义一个类,继承ContentProvider
Public class MyContentProvider extends ContentProvider
3、实现ContentProvider的所有方法(query、insert、update、delete、getType、onCreate)
public class MyContentProvider extends ContentProvider { //访问表的所有列 public static final int INCOMING_USER_COLLECTION = 1; //访问单独的列 public static final int INCOMING_USER_SINGLE = 2; //操作URI的类 public static final UriMatcher uriMatcher; //为UriMatcher添加自定义的URI static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user", INCOMING_USER_COLLECTION); uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user/#", INCOMING_USER_SINGLE); } private DatabaseHelp dh; //为数据库表字段起别名 public static HashMap userProjectionMap; static { userProjectionMap = new HashMap(); userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID); userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME); } /** * 删除表数据 */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { System.out.println("delete"); //得到一个可写的数据库 SQLiteDatabase db = dh.getWritableDatabase(); //执行删除,得到删除的行数 int count = db.delete(UserTableMetaData.TABLE_NAME, selection, selectionArgs); return count; } /** * 数据库访问类型 */ @Override public String getType(Uri uri) { System.out.println("getType"); //根据用户请求,得到数据类型 switch (uriMatcher.match(uri)) { case INCOMING_USER_COLLECTION: return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE; case INCOMING_USER_SINGLE: return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE_ITEM; default: throw new IllegalArgumentException("UnKnown URI"+uri); } } /** * 插入数据 */ @Override public Uri insert(Uri uri, ContentValues values) { //得到一个可写的数据库 SQLiteDatabase db = dh.getWritableDatabase(); //向指定的表插入数据,得到返回的Id long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values); if(rowId > 0){//判断插入是否执行成功 //如果添加成功,利用新添加的Id和 Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId); //通知监听器,数据已经改变 getContext().getContentResolver().notifyChange(insertedUserUri, null); return insertedUserUri; } return uri; } /** * 创建ContentProvider时调用的回调函数 */ @Override public boolean onCreate() { System.out.println("onCreate"); //得到数据库帮助类 dh = new DatabaseHelp(getContext(),MyContentProviderMetaData.DATABASE_NAME); return false; } /** * 查询数据库 */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //创建一个执行查询的Sqlite SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); //判断用户请求,查询所有还是单个 switch(uriMatcher.match(uri)){ case INCOMING_USER_COLLECTION: //设置要查询的表名 qb.setTables(UserTableMetaData.TABLE_NAME); //设置表字段的别名 qb.setProjectionMap(userProjectionMap); break; case INCOMING_USER_SINGLE: qb.setTables(UserTableMetaData.TABLE_NAME); qb.setProjectionMap(userProjectionMap); //追加条件,getPathSegments()得到用户请求的Uri地址截取的数组,get(1)得到去掉地址中/以后的第二个元素 qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1)); break; } //设置排序 String orderBy; if(TextUtils.isEmpty(sortOrder)){ orderBy = UserTableMetaData.DEFAULT_SORT_ORDER; } else{ orderBy = sortOrder; } //得到一个可读的数据库 SQLiteDatabase db = dh.getReadableDatabase(); //执行查询,把输入传入 Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); //设置监听 c.setNotificationUri(getContext().getContentResolver(), uri); return c; } /** * 更新数据库 */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { System.out.println("update"); //得到一个可写的数据库 SQLiteDatabase db = dh.getWritableDatabase(); //执行更新语句,得到更新的条数 int count = db.update(UserTableMetaData.TABLE_NAME, values, selection, selectionArgs); return count; } }
4、在AndroidMinifest.xml中进行声明
<provider
android:name=".cp.MyContentProvider"
android:authorities="com.cp.MyContentProvider"
android:exported="true" >
</provider>
- 这样一个ContentProvider就定义完成了,可以在另一个程序使用ContentResolver进行在应该间互相使用数据了