Android 存储(本地存储 SD卡存储 SharedPreference SQLite ContentProvider)
本文出自:http://blog.csdn.net/dt235201314/article/details/73176149
源码下载欢迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer
一丶慨述
本周的学习内容是Android存储,要求:数据库Sqlite相关操作,常用的文件存取方式,以及实用场景学习,主要学习Sqlite,SD卡文件操作,SharedPreference
二丶效果演示:
三丶功能介绍及主要内容
1.图一完成创建文件存储在手机内存中并读取删除,文件操作相关知识;
2.图二完成创建文件存储在手机SD卡中并读取删除,文件操作相关知识;
3.图三完成Sharedpreference存储用户偏好数据,读取删除数据等操作。可通过不同APP读取,暂不讲加密
4.图四完成SQLite完成玩家信息增删改查
参考博客:
以及大神“小猪”博客:http://blog.csdn.net/coder_pig
四丶代码讲解
1.文件存储
主要方法:
Demo1:
FileHelper.Java
/** * <pre> * author : JinBiao * CSDN : http://my.csdn.net/DT235201314 * time : 2017/06/11 * desc : 文件协助类 * 1.文件操作模式: * 1.Context.MODE_PRIVATE:私有操作模式,默认模式,代表该文件是私有数据,只能被应用本身访问, * 在该模式下,写入的内容会覆盖源文件的内容,如果想把新写入的内容追加到原文件中,可以使用Context.MODE_APPEND 2.Context.MODE_APPEND:追加操作模式:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件 3.Context.MODE_WORLD_READABLE:表示当前文件可以被其他应用读取。 4.Context.MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。 如果希望文件被其他应用读和写,可以传入: openFileOutput("1234.txt", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE); 另外,文件默认放在/data/data//files目录下 对于文件的获取,Android中提供了getCacheDir()和getFilesDir()方法: getCacheDir()方法用于获取/data/data//cache目录 getFilesDir()方法用于获取/data/data//files目录 * version: 1.0 * </pre> */ public class FileHelper { private Context mContext; public FileHelper() { } public FileHelper(Context mContext) { super(); this.mContext = mContext; } /** * 这里定义的是一个文件保存的方法,写入到文件中,所以是输出流 **/ public void save(String filename, String filecontent) throws Exception { //这里我们使用私有模式,创建出来的文件只能被本应用访问,还会覆盖原文件哦 FileOutputStream output = mContext.openFileOutput(filename, Context.MODE_PRIVATE); output.write(filecontent.getBytes()); //将String字符串以字节流的形式写入到输出流中 output.close(); //关闭输出流 } /** * 这里定义的是文件读取的方法 */ public String read(String filename) throws IOException { //打开文件输入流 FileInputStream input = mContext.openFileInput(filename); byte[] temp = new byte[1024]; StringBuilder sb = new StringBuilder(""); int len = 0; //读取文件内容: while ((len = input.read(temp)) > 0) { sb.append(new String(temp, 0, len)); } //关闭输入流 input.close(); return sb.toString(); } }
点击事件操作
@Override public void onClick(View v) { switch (v.getId()) { case R.id.btnclean: // deleteFile(editname.getText().toString()); editdetail.setText(""); editname.setText(""); break; case R.id.btnsave: FileHelper fHelper = new FileHelper(mContext); String filename = editname.getText().toString(); String filedetail = editdetail.getText().toString(); try { fHelper.save(filename, filedetail); Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show(); } break; case R.id.btnread: String detail = ""; FileHelper fHelper2 = new FileHelper(getApplicationContext()); try { String fname = editname.getText().toString(); detail = fHelper2.read(fname); } catch (IOException e) { e.printStackTrace(); } Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show(); break; } }
Demo2
读取流程图:
SDFileHelper.Java
/** * <pre> * author : JinBiao * CSDN : http://my.csdn.net/DT235201314 * time : 2017/06/12 * desc : SD卡文件操作协助类 * version: 1.0 * </pre> */ public class SDFileHelper { private Context context; public SDFileHelper() { } public SDFileHelper(Context context) { super(); this.context = context; } /** * 往SD卡写入文件的方法 * @param filename * @param filecontent * @throws Exception */ public void savaFileToSD(String filename, String filecontent) throws Exception { //如果手机已插入sd卡,且app具有读写sd卡的权限 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename; //这里就不要用openFileOutput了,那个是往手机内存中写数据的 FileOutputStream output = new FileOutputStream(filename); output.write(filecontent.getBytes()); //将String字符串以字节流的形式写入到输出流中 output.close(); //关闭输出流 } else Toast.makeText(context, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show(); } /** * 读取SD卡中文件的方法 * @param filename * @return * @throws IOException */ public String readFromSD(String filename) throws IOException { StringBuilder sb = new StringBuilder(""); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename; //打开文件输入流 FileInputStream input = new FileInputStream(filename); byte[] temp = new byte[1024]; int len = 0; //读取文件内容: while ((len = input.read(temp)) > 0) { sb.append(new String(temp, 0, len)); } //关闭输入流 input.close(); } return sb.toString(); }
点击事件操作:
@Override public void onClick(View v) { switch (v.getId()) { case R.id.btnclean: editdetail.setText(""); editname.setText(""); break; case R.id.btnsave: String filename = editname.getText().toString(); String filedetail = editdetail.getText().toString(); SDFileHelper sdHelper = new SDFileHelper(mContext); try { sdHelper.savaFileToSD(filename, filedetail); Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show(); } break; case R.id.btnread: String detail = ""; SDFileHelper sdHelper2 = new SDFileHelper(mContext); try { String filename2 = editname.getText().toString(); detail = sdHelper2.readFromSD(filename2); } catch (IOException e) { e.printStackTrace(); } Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show(); break; } }
读写权限:
<!-- 在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Demo3
SharePreference
使用流程图:
SharedHelper.java
/** * <pre> * author : JinBiao * CSDN : http://my.csdn.net/DT235201314 * time : 2017/06/12 * desc : SharedPreferences数据存储协助类 * map键值对形式保存文件 * version: 1.0 * </pre> */ public class SharedHelper { private Context mContext; public SharedHelper() { } public SharedHelper(Context mContext) { this.mContext = mContext; } /** * 定义一个保存数据的方法 * @param username * @param passwd */ public void save(String username, String passwd) { SharedPreferences sp = mContext.getSharedPreferences("my_sp", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString("username", username); editor.putString("passwd", passwd); editor.commit(); Toast.makeText(mContext, "信息已写入SharedPreference中", Toast.LENGTH_SHORT).show(); } /** * 定义一个读取SP文件的方法 * @return */ public Map<String, String> read() { Map<String, String> data = new HashMap<String, String>(); SharedPreferences sp = mContext.getSharedPreferences("my_sp", Context.MODE_PRIVATE); data.put("username", sp.getString("username", "")); data.put("passwd", sp.getString("passwd", "")); return data; } }
SharedPreferenceActivity:
public class SharedPreferenceActivity extends Activity { private EditText editname; private EditText editpasswd; private Button btnlogin,btnshow,button_clear; private String strname; private String strpasswd; private SharedHelper sh; private Context mContext; private SharedPreferences sp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.shared_preference_activity); mContext = getApplicationContext(); sh = new SharedHelper(mContext); intViews(); } private void intViews() { editname = (EditText)findViewById(R.id.editname); editpasswd = (EditText)findViewById(R.id.editpasswd); button_clear = (Button)findViewById(R.id.button_clear); btnshow = (Button)findViewById(R.id.buttonshow); btnlogin = (Button)findViewById(R.id.btnlogin); btnlogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { strname = editname.getText().toString(); strpasswd = editpasswd.getText().toString(); sh.save(strname,strpasswd); } }); btnshow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //获得第一个应用的包名,从而获得对应的Context,需要对异常进行捕获 try { mContext = createPackageContext("com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.androiddemo" , Context.CONTEXT_IGNORE_SECURITY); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } //根据Context取得对应的SharedPreferences sp = mContext.getSharedPreferences("my_sp", Context.MODE_WORLD_READABLE); String name = sp.getString("username", ""); String passwd = sp.getString("passwd", ""); Toast.makeText(getApplicationContext(), "Demo1的SharedPreference存的\n用户名为:" + name + "\n密码为:" + passwd, Toast.LENGTH_SHORT).show(); } }); button_clear.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { SPUtils.clear(mContext); Toast.makeText(getApplicationContext(), "已删除保存信息" , Toast.LENGTH_SHORT).show(); } }); } @Override protected void onStart() { super.onStart(); Map<String,String> data = sh.read(); editname.setText(data.get("username")); editpasswd.setText(data.get("passwd")); } }
SharedPreference工具类
/** * <pre> * author : JinBiao * CSDN : http://my.csdn.net/DT235201314 * time : 2017/06/12 * desc : SharedPreference工具类 * version: 1.0 * </pre> */ public class SPUtils { /** * 保存在手机里的SP文件名 */ public static final String FILE_NAME = "my_sp"; /** * 保存数据 */ public static void put(Context context, String key, Object obj) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); if (obj instanceof Boolean) { editor.putBoolean(key, (Boolean) obj); } else if (obj instanceof Float) { editor.putFloat(key, (Float) obj); } else if (obj instanceof Integer) { editor.putInt(key, (Integer) obj); } else if (obj instanceof Long) { editor.putLong(key, (Long) obj); } else { editor.putString(key, (String) obj); } editor.commit(); } /** * 获取指定数据 */ public static Object get(Context context, String key, Object defaultObj) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE); if (defaultObj instanceof Boolean) { return sp.getBoolean(key, (Boolean) defaultObj); } else if (defaultObj instanceof Float) { return sp.getFloat(key, (Float) defaultObj); } else if (defaultObj instanceof Integer) { return sp.getInt(key, (Integer) defaultObj); } else if (defaultObj instanceof Long) { return sp.getLong(key, (Long) defaultObj); } else if (defaultObj instanceof String) { return sp.getString(key, (String) defaultObj); } return null; } /** * 删除指定数据 */ public static void remove(Context context, String key) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.remove(key); editor.commit(); } /** * 返回所有键值对 */ public static Map<String, ?> getAll(Context context) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE); Map<String, ?> map = sp.getAll(); return map; } /** * 删除所有数据 */ public static void clear(Context context) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.clear(); editor.commit(); } /** * 检查key对应的数据是否存在 */ public static boolean contains(Context context, String key) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE); return sp.contains(key); } }
demo4:
代码详解参考:
Android基础入门教程——6.3.1 数据存储与访问之——初见SQLite数据库
ContentProvider目前不做详解文章代码参考:
Android基础入门教程——4.4.1 ContentProvider初探
Android基础入门教程——4.4.2 ContentProvider再探——Ducument Provider
Android深入四大组件(五)Content Provider的启动过程
五丶文件存储运用场景:
1.文件操作不能用于其他应用,一般用于图片文件的保存;
2.SharedPreference一般用于用户信息储存,能与其他应用共享数据,一般结合加密使用,如实现免登陆等操作;
3.SQLite轻量级数据库,数据可共享,一般用于结构化数据存储,例如前面文章提到的日记本开发,结构化数据又提供增删改查功能;
4.ContentProvider以提供公用url使数据数据在不同app中共享,例如视频音频图片通讯录等