有些时候,应用程序有少量的数据需要保存,而且这些数据的格式很简单:都是普通的字符串,标量类型的值等.对于这种数据,Android提供了SharedPreferences进行保存.
SharedPreferences接口主要负责读取应用程序的Preferences数据,它提供了如下常用方法来访问SharedPreferences中的key-value对:
- boolean contains(String key):判断SharedPreferences是否包含特定key的数据。
- Map<String,?> getAll():获取SharedPreferences数据里全部的key-value对。
- getXxx(String key,xxx defValue):获取SharedPreferences数据里指定key对应的value,如果key不存在,返回默认值defValue。
SharePreferences接口本身没有提供写入数据的能力,而是通过SharedPreferences的内部接口Editor。SharedPreferences调用edit()方法即可获取它所对应的Editor对象。Editor提供了如下方法向SharedPreferences写入数据:
- clear():清空所有数据。
- putXxx(String key,xxx value)写入数据
- remove(String key)删除指定key对应的数据项。
- boolean commit():当Editor编辑完成后,调用该方法提交修改。
SharedPreferences本身是一个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharePreferences(String name,int mode)方法来获取SharedPreferences实例,该方法的第二个参数支持如下几个值。
- Context.MODE PRIVATE:数据只能被本应用程序读写。
- Context.MODE_WORLD_READABLE:数据只能被其他应用程序读,但不能写。
- Context.MODE_WORLD_WRITELABLE:数据能被其他应用程序读写。
简单实例:
java代码:
public class MainActivity extends Activity { SharedPreferences sp; SharedPreferences.Editor spe; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取一个SharedPreferences对象 sp=getSharedPreferences("test", MODE_PRIVATE); //获取Eidt对象 spe=sp.edit(); Button button_1=(Button)findViewById(R.id.read); Button button_2=(Button)findViewById(R.id.write); button_1.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { String time=sp.getString("time", null); int randNum=sp.getInt("random", 0); String result=time==null?"你暂时还未写入数据":"写入时间为"+time+"\n上次写入的随机数为"+randNum; Toast.makeText(MainActivity.this,result,5000).show(); } }); button_2.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); spe.putString("time",sdf.format(new Date())); spe.putInt("randNum", (int)(Math.random()*10)); //提交 spe.commit(); } }); } }
SharedPreferences数据总是保存在/data/data/<package name>/shared_prefs目录下,数据宗师以XML格式保存。
Android也支持IO流来访问手机存储器上的文件。
Context提供了两个方法来打开文本应用程序的数据文件夹里的文件IO流。
- FileInputStream openFileInput(String name)
- FileOutputSteam openFileOutput(String name, int mode)
除此之外,Context还提供了如下两个方法来访问应用程序的数据文件夹:
- getDir(String name,int mode):在应用程序的数据文件夹下获取或创建那么对应的子目录。
- File getFilesDirs():获取该应用程序的数据文件夹的绝对路径。
- String[] fileList():返回该应用程序的数据文件夹下的全部文件。
- deleteFile(String):删除该应用程序的数据文件夹下的指定文件。
示例:
Java代码:
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText input=(EditText)findViewById(R.id.input); Button write=(Button)findViewById(R.id.write); Button read=(Button)findViewById(R.id.read); write.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { write(input.getText().toString()); input.setText(""); } }); read.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { String result=read(); Toast.makeText(MainActivity.this, result, 10000).show(); } }); } //读取方法 public String read(){ try { FileInputStream fis=openFileInput("test.txt"); byte[] buf=new byte[1024]; int i=0; StringBuilder sb=new StringBuilder(); while((i=fis.read(buf))!=-1){ sb.append(new String(buf,0,i)); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } //写入方法 public void write(String content){ try { FileOutputStream fos=openFileOutput("test.txt",MODE_APPEND); byte[] buf=content.getBytes(); fos.write(buf); } catch (Exception e) { e.printStackTrace(); } } }
应用程序的数据默认保存在/data/date/<package name>/files目录下
2.读写SD卡上的文件
读写SD卡上的文件的一般步骤如下:
- 调用Environment的getExternalStorageState()方法判断手机上是否插入了SD卡,并且应用程序具有读写SD卡的权限。
如果插入SD卡并允许操作下面代码返回true
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
权限设置
<!-- 在SD卡中创建和删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- SD写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- 调用Environment的getExtrenalStorageDirectory()方法来获取外部存储器,即SD卡的目录。
修改上面代码如下
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText input=(EditText)findViewById(R.id.input); Button write=(Button)findViewById(R.id.write); Button read=(Button)findViewById(R.id.read); write.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { write(input.getText().toString()); input.setText(""); } }); read.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { String result=read(); Toast.makeText(MainActivity.this, result, 5000).show(); } }); } //读取方法 public String read(){ try{ //如果手机插入SD卡,而且应用程序具有访问SD的权限 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //获取SD卡对应的存储目录 File sdCardDir=Environment.getExternalStorageDirectory(); //获取指定文件对应的输入流 FileInputStream fis=new FileInputStream(sdCardDir.getCanonicalPath()+"/test2.txt"); BufferedReader br=new BufferedReader(new InputStreamReader(fis)); StringBuilder sb=new StringBuilder(); String line=null; while((line=br.readLine())!=null){ sb.append(line); } return sb.toString(); } }catch(Exception e){ e.printStackTrace(); } return null; } //写入方法 public void write(String content){ try { if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //获取SD卡目录 File sdCardDir=Environment.getExternalStorageDirectory(); File targetFile=new File(sdCardDir.getCanonicalPath()+"/test2.txt"); RandomAccessFile raf=new RandomAccessFile(targetFile, "rw"); raf.seek(targetFile.length()); raf.write(content.getBytes()); raf.close(); } } catch (Exception e) { e.printStackTrace(); } } }
Android系统集成了轻量级的数据库:SQLite.
1.SQLiteDatabase
Android提供了SQLiteDatabase代表一个数据库,一旦应用程序获得了代表指定数据库的SQLiteDatabase对象,接下来就可通过SQLiteDatebase对象来管理、操作数据库了。
SQLiteDatabase提供了如下静态方法来打开一个文件对应的数据库。
- static SQLiteDatabase openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags):打开path文件所代表的SQLite数据库。
- static SQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabase.CursorFactory factory):打开或创建file文件所代表的SQLite数据库。
- static SQLiteDatabase openOrCreatDatabase(String paht,SQLiteDatabase.CursorFactory factory):打开或创建path文件所代表的SQLite数据库。
在程序中获取SQLiteDatabase对象之后,接下来就可调用SQLiteDatabase的如下方法来操作数据库:
- execSQL(String sql,Object[] bindArgs):执行带占位符的SQL语句。
- execSQL(String sql):执行SQL语句。
- insert(String table,String nullColumnHack,ContentValues values):向执行表中插入数据。
- update(String table,ContentValues values,String whereClause,String[] whereArgs):更新指定表中的特定数据。
- delete(String table,String whereClause,String[] whereArgs):删除指定表中的特定数据。
- Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy):对执行数据表执行查询。
- Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit):对执行数据表执行查询,limit参数控制最多查询几条记录。
- Cursor query(boolean distinct,String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit):对指定表执行查询语句。其中第一个参数控制是否去除重复值。
- rawQuery(String sql,String[] selectionArgs):执行带占位符的SQL查询。
- beginTransation():开始事务。
- endTransaction():结束事务。
Cursor提供如下方法来移动查询结果的记录指针。
- move(int offset):将记录指针向上或向下移动指定的行数。offset为整数就是向下移动;为负数就是向上移动。
- boolean moveToFirst():将记录指针移动到第一行,如果移动成功则返回true。
- boolean moveToLast():
- boolean moveToNext();
- boolean moveToPosition(int position):
- boolean moveToPrevious();
2.创建数据库和表