很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件进行保存。如果是Android应用,我们最适合采用什么方式保存软件配置参数呢?Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,SharedPreferences最终使用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs/目录下:
使用下面的代码即可生成上图中的的MainActivity.xml文件:
SharedPreferences mSettinsSP=getPreferences(Activity.MODE_PRIVATE); SharedPreferences.Editor mSettinsEd=mSettinsSP.edit(); //获取播放状态 boolean mIsPlaying=mMediaPlayer.isPlaying(); //获取播放进度 int mCurrentPosition=mMediaPlayer.getCurrentPosition(); //存储播放状态和播放进度以及当前的时间 mSettinsEd.putBoolean("IsPlaying", mIsPlaying); mSettinsEd.putInt("CurrentPosition", mCurrentPosition); mSettinsEd.putString("Time", new Date().toLocaleString()); //提交保存 mSettinsEd.commit();完成存储后MainActivity.xml文件中的内容:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <boolean name="IsPlaying" value="true" /> <int name="CurrentPosition" value="99422" /> <string name="Time">2000-1-5 上午5:20:04</string> </map>因为SharedPreferences最终是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀.xml,后缀.xml会由Android自动加上;方法的第二个参数为应用间共享preferences数据的3种模式:MODE_PRIVATE、MODE_WORLD_READABL和 MODE_WORLD_WRITEABLE。MODE_PRIVATE是preferences的默认模式,代表只有创建这个preferences的程序才能访问这个preferences;MODE_WORLD_READABLE表示其他程序对这个preferences只有只读权限,MODE_WORLD_WRITEABLE则是其他程序同时拥有读写权限。另外Activity还提供了另一个getPreferences(mode)方法操作preferences,这个方法默认使用当前类不带包名的类名作为xml文件的名称。
访问本应用中的preferences代码如下:
SharedPreferences mSettinsSP=getPreferences(Activity.MODE_PRIVATE); SharedPreferences.Editor mSettinsEd=mSettinsSP.edit(); int mCurrentPosition=mSettinsSP.getInt("CurrentPosition", 0); boolean mIsPlaying=mSettinsSP.getBoolean("IsPlaying", false);
访问其他应用中的preferences,前提条件是:该preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。如:有个<package name>为com.example.testsharepreference的应用使用下面语句创建了preference。
getSharedPreferences("zkliu", Activity.MODE_WORLD_READABLE);其他应用要访问上面应用的preference,首先需要创建上面应用的Context,然后通过Context访问preference,访问preference时会在应用所在包下的shared_prefs目录找到preference :
Context otherAppsContext = createPackageContext("com.example.testsharepreference", Activity.CONTEXT_IGNORE_SECURITY); SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("zkliu", Activity.MODE_WORLD_READABLE); int mCurrentPosition=mSettinsSP.getInt("CurrentPosition", 0); boolean mIsPlaying=mSettinsSP.getBoolean("IsPlaying", false);如果不通过创建Context访问其他应用的preference,可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如:
File xmlFile = new File(“/data/data/<package name>/shared_prefs/zkliu.xml”);//<package name>应替换成应用的包名测试工程使用上次的MediaPlayer Demo,在原来的基础上增加在程序退出时保存当前的播放状态和进度到preferences,下次打开程序时根据preferences文件中的记录恢复到上一次退出程序时播放状态:
主要代码:
package com.example.testsharepreference; import java.io.IOException; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Bundle; import android.app.Activity; import android.content.SharedPreferences; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.SeekBar; import java.util.Date; public class MainActivity extends Activity implements OnClickListener ,SeekBar.OnSeekBarChangeListener{ private MediaPlayer mMediaPlayer=null;//媒体播放器 private AudioManager mAudioManager=null;//声音管理器 private Button mPlayButton=null;//播放按钮 private Button mPauseButton=null;//暂停按钮 private Button mStopButton=null;//停止按钮 private SeekBar mSoundSeekBar=null; //音量调节 private int maxStreamVolume;//最大音量 private int currentStreamVolume;//当前音量 private int mCurrentPosition;//存储当前的播放进度 private boolean mIsPlaying; private SharedPreferences mSettinsSP=null;//用SharedPreferences来存储数据 private SharedPreferences.Editor mSettinsEd=null;//使用SharedPreferences.Editor来存储数据 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMediaPlayer=MediaPlayer.create(this, R.raw.likesomeoldfriendsbackagain);//加载res/raw的happyis.mp3文件 mAudioManager=(AudioManager)this.getSystemService(AUDIO_SERVICE); mPlayButton=(Button)findViewById(R.id.Play); mPauseButton=(Button)findViewById(R.id.Pause); mStopButton=(Button)findViewById(R.id.Stop); mSoundSeekBar=(SeekBar)findViewById(R.id.SoundSeekBar); mPlayButton.setOnClickListener(this); mPauseButton.setOnClickListener(this); mStopButton.setOnClickListener(this); maxStreamVolume=mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); currentStreamVolume=mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); mSoundSeekBar.setMax(maxStreamVolume); mSoundSeekBar.setProgress(currentStreamVolume); mSoundSeekBar.setOnSeekBarChangeListener(this); //存储名称为zkliu.xml,读写模式为私有 //mSettinsSP=getSharedPreferences("zkliu",Activity.MODE_PRIVATE); mSettinsSP=getPreferences(Activity.MODE_PRIVATE); mSettinsEd=mSettinsSP.edit(); //获取上一次退出程序时的播放状态 mCurrentPosition=mSettinsSP.getInt("CurrentPosition", 0); mIsPlaying=mSettinsSP.getBoolean("IsPlaying", false); Log.e("LastPlayTime",mSettinsSP.getString("Time", "以前没有播放过")); //上一次退出程序时是播放状态,则从上一次退出的位置继续播放 if(mIsPlaying){ mMediaPlayer.seekTo(mCurrentPosition); mMediaPlayer.start(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub System.out.println("progress:"+String.valueOf(progress)); mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case R.id.Play: mMediaPlayer.start(); break; case R.id.Pause: mMediaPlayer.pause(); break; case R.id.Stop: mMediaPlayer.stop(); try{ mMediaPlayer.prepare(); } catch(IllegalStateException e){ e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } mMediaPlayer.seekTo(0); break; default: break; } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); } //退出程序时存储当前的播放状态 @Override public void onBackPressed() { // TODO Auto-generated method stub //获取播放状态 mIsPlaying=mMediaPlayer.isPlaying(); //获取播放进度 mCurrentPosition=mMediaPlayer.getCurrentPosition(); if(mIsPlaying) mMediaPlayer.stop(); mMediaPlayer.reset(); mMediaPlayer.release(); //存储播放状态和播放进度以及当前的时间 mSettinsEd.putBoolean("IsPlaying", mIsPlaying); mSettinsEd.putInt("CurrentPosition", mCurrentPosition); mSettinsEd.putString("Time", new Date().toLocaleString()); //提交保存 mSettinsEd.commit(); super.onBackPressed(); } }完整工程在我的资源中上传的有。