一、Android数据存储分类
A:Shared Preferences:存储私有的数据以键值对的形式
文件的路径为:/data/data/应用程序主包名/shared_prefs/文件名 文件以Xml的形式存储的.
-
1.读取数据的步骤:
- A:调用Context对象的getSharedPreferences(文件名,文件的操作模式)得到SharedPreferences对象
this.sharedPreferences=this.getSharedPreferences(fileName, Context.MODE_PRIVATE); - B:调用SharedPreferences对象的getXXX(key,[默认值])根据指定的键获取数据,如果键不存在则返回默认值
String userName=this.sharedPreferences.getString(“userName”,"");
- A:调用Context对象的getSharedPreferences(文件名,文件的操作模式)得到SharedPreferences对象
文件的操作模式:
Context.MODE_PRIVATE=0:代表当前文件只能供本应用程序使用,其它应用程序无法访问本文件.每次写入新数据时都会覆盖之前写的数据.
Context.MODE_APPEND=32768:代表当前文件只能供本应用程序使用,其它应用程序无法访问本文件,但每次写入新数据会追加到之前数据的后面
Context.MODE_WORLD_READABLE=1:代表当前文件所有应用程序都可以读取,但不能写入数据
Context.MODE_WORLD_WRITEABLE=2:代表当前文件所有应用程序都可以写入数据,但不能读取数据.
Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE或者
Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE:代表本文件可以全局读写
- 2.写出数据的步骤:
- A:调用Context对象的getSharedPreferences(文件名,文件的操作模式)得到SharedPreferences对象
this.sharedPreferences=this.getSharedPreferences(fileName, Context.MODE_PRIVATE); - B:调用SharedPreferences对象的edit()方法得到Editor对象
SharedPreferences.Editor editor=this.sharedPreferences.edit(); - C:调用编辑器对象的putXXX(key,value)设置需要保存的数据
editor.putString(“userName”,userName); - D:调用编辑器对象的commit()方法提交数据
editor.commit();
- A:调用Context对象的getSharedPreferences(文件名,文件的操作模式)得到SharedPreferences对象
getSharedPreferences(fileName, Context.MODE_PRIVATE)和getPreferences(Context.MODE_PRIVATE)的区别:
A:getSharedPreferences(fileName, Context.MODE_PRIVATE)必须指定文件名;
getPreferences(Context.MODE_PRIVATE):使用当前Activity的简单类名作为文件名
B:getSharedPreferences(fileName, Context.MODE_PRIVATE)是Context对象的方法
getPreferences(Context.MODE_PRIVATE):是Activity的方法.
使用SharedPreferences可以存储的数据类型:
java的八大基本数据类型及String,Set类型的数据
B:内部存储:在设备的内存中存储私有数据
内部存储的路径:/data/data/应用程序主包名/files/文件名
采用内部存储写数据的步骤:
- 1.调用上下文对象的openFileOutput(文件名,文件的操作模式)返回文件输出流对象
fileOutputStream=this.context.openFileOutput("hsj.bak",Context.MODE_PRIVATE);
- 2.调用文件输出流对象的write(byte[] data)将指定的数据写出到内部存储中
fileOutputStream.write(content.getBytes());
- 3.关闭输出流对象
fileOutputStream.close();
fileOutputStream=null;
读取内部存储读取数据的步骤
- 1.调用上下文对象的openFileInput(文件名)返回文件输入流对象
fileInputStream= this.context.openFileInput("hsj.bak");
- 2.调用文件输入流对象的read()方法读取数据
byte[] buffer=new byte[1024];
int len=0;
while((len=fileInputStream.read(buffer))!=-1){
sb.append(new String(buffer,0,len));
}
- 3.关闭文件输入流对象
fileInputStream.close();
C:外部存储:在外部设备(手机SDCard等)存储共享数据 最原始路径为: /mnt/sdcard;不同版本手机的路径会有所不同;
采用外部存储写入数据的步骤
- 1.判断手机的SDCard是否存在并且可用
String state= Environment.getExternalStorageState();
//mounted:代表当前手机的SDCard存在并且可用
if(Environment.MEDIA_MOUNTED.equals(state)){
return true;
}
- 2.得到外部存储设备的根目录并组拼出写入数据文件
File root=Environment.getExternalStorageDirectory();
File destFile=new File(root,"sdcard.bak");
- 3.使用组拼出来的文件包装成输出流对象
outputStream=new FileOutputStream(destFile);
- 4.调用输出流对象的write()方法写出数据
outputStream.write(content.getBytes());
- 5.关闭输出流对象
outputStream.close();
从外部存储设备中读取数据的步骤:
- 1.判断手机的SDCard是否存在并且可用
String state= Environment.getExternalStorageState();
//mounted:代表当前手机的SDCard存在并且可用
if(Environment.MEDIA_MOUNTED.equals(state)){
return true;
}
- 2.得到外部存储设备的根目录并组拼出写出数据文件
File root=Environment.getExternalStorageDirectory();
File destFile=new File(root,"sdcard.bak");
- 3.使用组拼出来的文件包装成输入流对象
inputStream=new FileInputStream(destFile);
- 4.使用输入流读取数据
byte[] buffer=new byte[1024];
int len=0;
while((len=inputStream.read(buffer))!=-1){
sb.append(new String(buffer,0,len));
}
- 5.关闭输入流
inputStream.close();
D:SQLite数据库存储:存储结构化数据
数据库的使用工具类的编写步骤:
- 1.编写一个类继承SQLiteOpenHelper并重写父类的抽象方法:
onCreate(SQLiteDatabase db):
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
- 2.根据需要提供相应的构造函数,由于父类中没有无参构造函数,因此本来中必须显示提供一个构造函数能够调用父类的有参构造函数,否则报错
public class DBUtils extends SQLiteOpenHelper {
/**
* 数据库的名称
*/
private static final String DATABASE_NAME="MyDb.db";
/**
* 数据库的版本号
*/
// private static final int VERSION=1;
//private static final int VERSION=2;
private static final int VERSION=1;
/**
* 1.声明一个私有的静态的本类类型的对象
*/
private static DBUtils dbUtils;
/*
* 创建一个辅助类对象用于创建,打开和管理数据库,由于这个方法返回非常快,因此不会马上创建数据库,而是在我们调用了
* getWriteableDatabase()或者getReadableDatabase()时才会真正的帮助我们创建数据库
* @param context 上下文对象
* @param name 数据库文件的名称,如果为null则使用内存数据库
* @param factory 用于创建游标对象的游标工厂对象,默认为null
* @param version 数据库的版本号用于升级或者降级数据库时使用
*
public DBUtils(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}*/
/**
* 2.构造函数私有化
* @param context
*/
private DBUtils(Context context){
super(context,DATABASE_NAME,null,VERSION);
System.out.println("====DBUtils(Context context)====");
}
/**
* 3.通过公有的静态方法返回本类类型的对象
* @param context
* @return
*/
public static DBUtils getInstance(Context context){
if(dbUtils==null){
dbUtils=new DBUtils(context);
}
return dbUtils;
}
/**
* 第一次创建数据库时自动调用的方法,创建表和初始化表中的数据在这里发生
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
/*
组成创建表的SQL语句:
CREATE TABLE IF NOT EXISTS t_person (
id INTEGER PRIMARY KEY AUTOINCREMENT,--编号
name VARCHAR(20) UNIQUE,--姓名
age INTEGER DEFAULT 1 CHECK(age BETWEEN 1 AND 150),--年龄,如果没有显示给值,则使用默认值1,并且年龄的范围必须在1到150之间,否则报违背检查约束的错误
addr VARCHAR(200)
);
*/
StringBuilder sb_createTable=new StringBuilder("CREATE TABLE IF NOT EXISTS ");
sb_createTable.append(Person_Const.TABLE_NAME_PERSON).append(" ( ");
sb_createTable.append(Person_Const.TABLE_NAME_PERSON_ID).append(" INTEGER PRIMARY KEY AUTOINCREMENT,");
sb_createTable.append(Person_Const.TABLE_NAME_PERSON_NAME).append(" VARCHAR(20) UNIQUE,");
sb_createTable.append(Person_Const.TABLE_NAME_PERSON_AGE).append(" INTEGER DEFAULT 1 CHECK(age BETWEEN 1 AND 150),");
sb_createTable.append(Person_Const.TABLE_NAME_PERSON_ADDR).append(" VARCHAR(200) ");
sb_createTable.append(");");
//db.execSQL(非select语句的sql语句):
db.execSQL(sb_createTable.toString());
/*
向表中插入测试数据:
INSERT INTO t_person VALUES(null,?,?,?);
*/
StringBuilder sb_insert=new StringBuilder("INSERT INTO ")
.append(Person_Const.TABLE_NAME_PERSON)
.append(" VALUES ").append("(null,?,?,?")
.append(");");
db.execSQL(sb_insert.toString(),new Object[]{"张三",20,"北京"});
db.execSQL(sb_insert.toString(),new Object[]{"李四",22,"上海"});
db.execSQL(sb_insert.toString(),new Object[]{"王五",18,"广州"});
db.execSQL(sb_insert.toString(),new Object[]{"小龙",1,"深圳"});
db.execSQL(sb_insert.toString(),new Object[]{"小倩",18,"杭州"});
db.execSQL(sb_insert.toString(),new Object[]{"小丽",20,"福建"});
db.execSQL(sb_insert.toString(),new Object[]{"小妞",22,"郑州"});
db.execSQL(sb_insert.toString(),new Object[]{"小青",25,"武汉"});
db.execSQL(sb_insert.toString(),new Object[]{"小白",23,"合肥"});
db.execSQL(sb_insert.toString(),new Object[]{"小梅",23,"沧州"});
db.execSQL(sb_insert.toString(),new Object[]{"小郭",21,"漠河"});
}
/**
* 当数据库版本升级时自动调用的方法
* @param db 数据库对象
* @param oldVersion 数据库的老版本号
* @param newVersion 数据库升级后的新版本号
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//当数据库升级时把变化的数据写在这里
}
/**
* 数据库版本降级时自动调用的方法
* @param db 数据库对象
* @param oldVersion 老版本号
* @param newVersion 新版本号
*/
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//把在onUpgrade()方法中做的变化还原成之前的状态
}
/**
* 每次打开数据库时都会自动调用的方法
* @param db 数据库对象
*/
@Override
public void onOpen(SQLiteDatabase db) {
}
}
打开指定路径下的数据库对象并返回SQLiteDatabase对象
SQLiteDatabase db= SQLiteDatabase.openDatabase(
path,//访问的数据库的路径
null, //游标工厂对象
SQLiteDatabase.OPEN_READONLY//以什么样的方式打开数据库的标志
);
E:网络存储:将Android手机端的数据存储到远程服务器中.
分类:基于HTTP协议:
A:HttpURLConnection
B:HttpClient
基于Socket通信:
A:TCP
B:UDP
二、得到手机常用路径
1、 /mnt/sdcard
File root=Environment.getExternalStorageDirectory();
2、 /system
File root=Environment.getRootDirectory();
3、 /cache
File root=Environment.getDownloadCacheDirectory();
4、 /data
File root=Environment.getDataDirectory();
5、 /storage/emulated/0/Music
//String type=Environment.DIRECTORY_MUSIC;
String type=Environment.DIRECTORY_PICTURES;
File root=Environment.getExternalStoragePublicDirectory(type);
三、获取手机SDCard的容量
1、获取手机SDCard的总容量
public long getSDCardTotalCapacity(){
if(this.isSDCardUse()){
// /mnt/sdcard
File root=Environment.getExternalStorageDirectory();
//根据SDCard的路径得到状态文件系统对象
StatFs statFs=new StatFs(root.getPath());
//得到每一块数据的大小,以字节为单位
long blockSize=statFs.getBlockSize();
System.out.println("blockSize="+blockSize);
//得到当前手机SDCard一共有多少个数据块
long blockCount=statFs.getBlockCount();
System.out.println("blockCount="+blockCount);
//return blockCount*blockSize;//默认以字节为单位
return blockCount*blockSize/1024/1024/1024;//默认以字节为单位,换算成GB
}else{
throw new RuntimeException("当前手机SDCard不存在或者不可用!");
}
}
2、获取手机SDCard可用容量
public long getSDCardAvailableCapacity(){
if(this.isSDCardUse()){
// /mnt/sdcard
File root=Environment.getExternalStorageDirectory();
//根据SDCard的路径得到状态文件系统对象
StatFs statFs=new StatFs(root.getAbsolutePath());
//得到每一块数据的大小,以字节为单位
int blockSize=statFs.getBlockSize();
//得到当前手机SDCard可用容量的SDCard块数
int availableBlocks=statFs.getAvailableBlocks();
//return availableBlocks*blockSize;//默认以字节为单位
return availableBlocks*blockSize/1024/1024/1024;//默认以字节为单位,换算成GB
}else{
throw new RuntimeException("当前手机SDCard不存在或者不可用!");
}
}
3、获取手机SDCard剩余容量
public long getSDCardFreeCapacity(){
if(this.isSDCardUse()){
// /mnt/sdcard
File root=Environment.getExternalStorageDirectory();
//根据SDCard的路径得到状态文件系统对象
StatFs statFs=new StatFs(root.getAbsolutePath());
//得到每一块数据的大小,以字节为单位
int blockSize=statFs.getBlockSize();
//得到当前手机SDCard可用容量的SDCard块数
int freeBlocks=statFs.getFreeBlocks();
//return freeBlocks*blockSize;//默认以字节为单位
return freeBlocks*blockSize/1024/1024/1024;//默认以字节为单位,换算成MB
}else{
throw new RuntimeException("当前手机SDCard不存在或者不可用!");
}
}