Android数据存储文件存储SQLite数据库简单使用 sharedPreferences存储
Posted www?
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android数据存储文件存储SQLite数据库简单使用 sharedPreferences存储相关的知识,希望对你有一定的参考价值。
文章目录
5 数据存储
5.1 数据的存储方式
补充
- 文件存储:读取方式和java中I/O程序是完全一样的
- SharedPreferences:这是android提供的用来存储一些简单的配置信息的一种机制,用于存储一些应用程序的各种配置信息,入用户名,密码等
- SQlite数据库:是Android自带的一个轻量级的数据库,,一般使用它作为复杂数据的存储引擎,可以存储用户信息等
- ContentProvider:Android四大组件之一
- 网络存储:需要Android网络数据包打交道,间数据存储到服务器上
5.2 文件存储
5.2.1 将数据存入文件中
1.内部存储
内部存储值得是将应用程序中的数据以文件的形式存储到应用中(该文件默认位于data/data/< packagename > ,此时存储的文件会被所在的应用程序私有化,如果其他程序想要操作本应用程序中的文件,需要权限设置,当创建的应用程序被卸载的时候,期内部存储文件也会随之被删除。
示例代码:
参数:“name”表示文件名:“mode”表示文件的操作模式,也就是读写文件的方式
2.外部存储
外部存储是将数据以文件的形式存储到一些外部设备上,例如SD卡或者设备内钱嵌的存储卡,属于永久性的存储方式(外部存储的文件通常位于mnt/sdcard目录下,不同的手机路径可能不同)外部的存储文件可以被其他应用程序所共享,当将外部存储文件设备连接计算机上时,这些文件可以被浏览,修改和删除,因此此方式不安全。
第一行:获取外部设备的状态
第二行:判断外部设备是否可用
加粗样式
5.2.2 从文件中读取数据
1.读取内部存储中的文件数据
byte[] bytes= new byte[fis.available()]创建缓冲区,并获取文件的长度
2.读取外部存储中的文件数据
首先需要读取外部设备(SD卡)的路径,并通过该路径读取相应的文件的数据
静态申请权限
动态申请权限
申请正常权限时使用静态申请权限的方式即可,但对于一些涉及用户隐私的危险权限需要用户的授权后才可以使用,因此危险权限不仅需要在清单文件(AndroidManifest.xml)的< manifest >节点添加权限,还需在代码中动态申请权限,以动态申请SD卡的写权限为例:
requestPermissions()方法中包含3个参数,第1个参数为Context上下文,第2个参数需要申请的权限,第3个参数为请求码
添加完动态申请权限后,运行程序,界面会弹出是否允许请求权限的对话框,有用户进行授权,如下图所示:
上述图片内容为“是否允许访问设备上照片、媒体和文件的申请权限”DENY按钮表示拒绝,ALLOW按钮表示允许,当用户点击对话框中的“ALLow"按钮时,程序会执行动态申请权限回调方法onRequestPermissionsResult(),该方法中可以获去用户授予申请权限的结果。
方法中包含三个参数:第一个参数requestCode表示请求码,permissions表示请求的权限,grantResults表示用户授予权限的结果。
5.2.3 实战演练-保存QQ账号和密码
使用文件存储的方式保存数据
FileSaveQQ.java
package com.example.administrator.saveqq;
import android.content.Context;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class FileSaveQQ {
//保存QQ账号和登录密码到data.txt 文件中
public static Boolean saveUserInfo(Context context, String account, String passwoed) {
FileOutputStream fos = null;
try {
//获取文件的输出流对象fos
fos = context.openFileOutput("data.txt", Context.MODE_PRIVATE);
//将数据以字节码的方式写入data.txt文件中
fos.write((account + ":" + passwoed).getBytes());
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//从data.txt文件中获取存储的QQ号账号密码
public static Map<String,String> getUsetInfo(Context context){
String content = "";
FileInputStream fis = null;
try {
//获取文件的输入流对象
fis = context.openFileInput("data.txt");
//将输入流对象中的数据转换为字节码的形式
byte[] bytes= new byte[fis.available()];
fis.read(bytes);//通过read()方法读取字节码文件中的数据
content = new String(bytes);//将获取的字节码转换为字符串
Map<String ,String> map = new HashMap<>();
//将字符串以":"进行分割,然后形成一个数组的形式
String[] infos= content.split(":");
//讲述租的第一个数据放入userMap集合中
map.put("account",infos[0]);
map.put("password",infos[1]);
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if(fis!=null){
fis.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
MainActivity.java
package com.example.administrator.saveqq;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText et_account;//账号输入框
private EditText et_password;//密码输入框
private Button but_login;//登录按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//通过工具类FileSaveQQ中的getUserInfo()方法获取QQ帐号和密码信息
Map<String ,String> userInfo = FileSaveQQ.getUsetInfo(this);
//Map<String ,String> userInfo = SPSaveQQ.getUserInfo(this);
if(userInfo!=null){
et_account.setText(userInfo.get("account"));
et_password.setText(userInfo.get("password"));
}
}
private void initView() {
et_account=findViewById(R.id.et_account);
et_password=findViewById(R.id.et_password);
but_login=findViewById(R.id.but_login);
but_login.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.but_login:
//当点击“登录”按钮的时候,获取界面输入的账号和密码
String account = et_account.getText().toString().trim();
String password = et_password.getText().toString();
//检验输入的账号和密码是否为空
if(TextUtils.isEmpty(account)){
Toast.makeText(this,"你输入的账号为空",Toast.LENGTH_SHORT).show();
return;
}
if(TextUtils.isEmpty(password)){
Toast.makeText(this,"你输入的密码为空",Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this,"登陆成功!",Toast.LENGTH_SHORT).show();
boolean isSave = FileSaveQQ.saveUserInfo(this,account,password);
// boolean isSave = SPSaveQQ.saveUserInfo(this,account,password);
if(isSave){
Toast.makeText(this,"保存成功",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"保存失败",Toast.LENGTH_SHORT).show();
}
break;
}
}
}
xml文件
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/a1"
android:layout_gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/et_account"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码:" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/et_password"
android:inputType="textPassword"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:id="@+id/but_login"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消" />
</LinearLayout>
</LinearLayout>
5.3 sharedPreferences存储
5.3.1 将数据存入SharedPreferences中
第一步:获取sp对象,参数data表示文件名,MODE_PRIVATE表示文件操作模式
由于该对象本身只能获取数据,不能对数据进行存储和修改,因此需要调用SharePreferences类的edit()的方法获取可编辑的Editor对象。
editor.commit(); //提交修改
5.3.2 读取和删除数据
-
获取数据的key值与存入数据的key值数据类型要一致,否则找不到指定数据
-
保存SharedPreferences的key值是,使用静态变量保存,以免操作是写错,如private final String key= “itcast”。
5.3.3 实战演练—保存QQ账号和密码
使用SharedPreferences存储的方式保存数据
SPSaveQQ.java
package com.example.administrator.saveqq;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.HashMap;
import java.util.Map;
public class SPSaveQQ {
public static boolean saveUserInfo(Context context,String account,String password){
SharedPreferences sp = context.getSharedPreferences("data",Context.MODE_PRIVATE);
SharedPreferences.Editor editor= sp.edit();
editor.putString("account",account);
editor.putString("password",password);
editor.commit();
return true;
}
public static Map<String,String> getUserInfo(Context context){
SharedPreferences sp = context.getSharedPreferences("data",Context.MODE_PRIVATE);
String account = sp.getString("account",null);
String password = sp.getString("password",null);
Map<String,String> map = new HashMap<>();
map.put("account",account);
map.put("password",password);
return map;
}
}
xml文件和5.2.3节相同,这里省略。
MainActivity.java
-
这里面修改两句代码即可(调用的代码)分别是5.2.3节中的第27行代替26行,和60行代替59行即可。
-
如果想要查看你存储的文件是否保存了数据,可以在以下位置找到。
-
运行你的项目
-
在右下角找到Device File Explorer文件(便于观察我将图片旋转了一下)
-
打开data文件中的data文件
-
在data文件中找到你的项目文件
-
上面两个分别就是上述两种存储方式生成的文件,可以右键,然后点击Save保存至桌面进行查看。
-
5.4 SQlite数据库存储
前面介绍了如何使用文件进行存储和SharedPreferences存储数据,这两种方式适合存储简单数据,当你需要存储大量的数据的时候,显然不适合,为此Android提供了一个SQLite数据库,它可以存储应用程序中的大量数据,并对数据进行管理和维护。
5.4.1 SQLite数据库的创建
- 只需要创建一个类继承SQLiteOpenHelper类,在该类中重写onCreate()方法和onUpgrade()方法即可
- super()调用父类SQLiteOpenHelper,并传入4个参数,分别表示上下文对象,数据库名称,游标工厂(通常是null),数据库版本
- onGrate()方法是在数据库第一次创建的时候调用的,此方法通常用于初始化结构
- onUpgrade()方法在数据库版本号增加时调用,如果版本号不增加,此方法不调用。
扩展 SQLite Expert Personal可视化工具
1.在Android系统中,数据库创建完成后是无法直接对数据进行查看的,想要查看需要使用SQLite Expert Personal可视化工具,可在官网(点击查看)中下载SQLite Expert Personal工具
2.接下来通过SQLite Expert Personal查看已将创建好的数据库文件,可在Device File Explorer视图中找到数据库文件所在的目录【data】–>【data】–>【项目包名全路径】–>【databases】
3.数据库文件是.db为扩展名,右键点击【Save As】将文件导入到指定目录下
4.在SQLite Expert Personal工具中点击【File】–>【Open Database】选项,选择你想要查看的数据库文件
5.4.2 SQLite数据库的基本操作
1.新增数据 (inset)
- 通过getWritableDatabase()方法得到SQLiteDatabase对象,然后获取ContentValues对象中,最后调用insert()方法将数据插入到information表中
- **inset()**方法接收3个参数,第一个参数是数据库表的名称,第二个参数是表示如果发现将要插入的行行为为空时,会将这个列名的值设为null,第三个参数为ContentValues对象
- ContentValues类似于Map类,通过键值对元素的形式将数据存入,这里的key值表示插入数据库的列名,value表示要插入的数据
- 最后一定要使用close()方法将它关闭,否则数据库连接会一直存在,不断消耗内存,当系统内存不足的时候获取不到SQLiteDatabase对象,并且会报出数据库未关闭异常。
2.删除数据(delete)
- 删除操作不需要使用ContentValue来添加数,而是使用一个字符串和一个字符数组来添加参数名和参数值
3.修改数据(update)
- update()方法中有四个参数,第一个参数表示数据库表名称,第二个参数是修改后的数据,第三个参数表示要修改的数据的查询条件,第四个参数是表示查询条件的参数。
4.查询数据(query)
- query方法中有7个参数,第一个参数表名称,第二个参数表示查询的列名,第三个参数表示接收查询条件的子句,第四个参数表示接收查询子句对应的条件值,第五个参数值表示分组方式,第六个阐释是接收having条件,即定义的过滤器,第七个参数表示排序的方式
- getCount()方法获取查询到的结果总数
- moveToNext()方法移动游标指向下一行数据
- getString()方法传入列名获取对应的数据
Android中数据存储——SQLite数据库存储数据