Part 5 - 安卓数据存储

2021-09-29
6分钟阅读时长

【版本】

当前版本号v20220929

版本修改说明
v20220929初始化版本

【实验名称】 实验5.1 SmartHome 项目使用 Intent 传递用户名给 MainActivity

【实验目的】

  • 掌握 Android 的 Intent 传递数据

【实验环境】

  • 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
  • 计算机可以访问互联网。
  • 内存:至少6G
  • 硬盘:至少空余20G
  • JDK 8或以上
  • Android Studio

【实验要求】

  • 本实验承接实验4.5项目 SmartHome
  • 在 SmartHome 项目,LoginActivity 登录成功以后,使用 Intent 传递用户名给 MainActivity,并在 MainActivity 弹出提示框“欢迎你[用户名]”

【参考代码】

  1. Intent 放入数据
Intent intent=new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("userid","用户名");
  1. Intent 取出数据的方法
//Intent获取值方法
getStringExtra(String name) 
getDoubleExtra(String name, double defaultValue) 
getFloatExtra(String name, float defaultValue) 
getLongExtra(String name, long defaultValue)
getIntExtra(String name, int defaultValue)
getCharExtra(String name, char defaultValue)
getShortExtra(String name, short defaultValue)
getBooleanExtra(String name, boolean defaultValue)
  1. Activity 获取 Intent 的方法
getIntent()

【实验名称】 实验5.2 SmartHome 项目实现登录以后使用 SharedPreferences 保存用户信息

【实验目的】

  • 掌握使用 SharedPreferences 存储数据

【实验环境】

  • 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
  • 计算机可以访问互联网。
  • 内存:至少6G
  • 硬盘:至少空余20G
  • JDK 8或以上
  • MySQL 或 MariaDB

【实验要求】

  • (1)本实验承接实验5.1项目 SmartHome
  • (2)在 SmartHome 项目,LoginActivity 登录成功以后,使用 SharedPreferences 保存用户的用户名(userid) ,令牌(Token)和令牌过期时间(Token Expired Time)
  • (3)设置 MainActivity 为主Activity
  • (4)修改 MainActivity 的 onCreate 方法,MainActivity启动时,检查令牌(Token)是否过期,没有过期直接进入 MainActivity,如果令牌过期清除 SharedPreferences 里的值,并且跳转到 LoginActivity。

【实验步骤】

LoginActivity.java

  1. 修改 LoginActivity,登录成功获取到用户信息以后,使用 SharedPreferences 保存用户的用户名(userid) ,令牌(Token)和令牌过期时间(Token Expired Time)。参考代码如下。
SharedPreferences.Editor editor=getSharedPreferences(PrefConst.DEFAULT_FILE_NAME,MODE_PRIVATE).edit();
editor.putString(PrefConst.KEY_CUR_USERID,"用户名");
editor.putString(PrefConst.KEY_TOKEN,"令牌");
editor.putLong(PrefConst.KEY_TOKEN_EXPIRED_TS,令牌过期时间);
editor.apply();

PrefConst.java

public interface PrefConst {

    /**
     * 默认文件名
     */
    String DEFAULT_FILE_NAME="data";

    /**
     * 当前用户名
     */
    String KEY_CUR_USERID="KEY_CUR_USERID";

    /**
     * 当前令牌
     */
    String KEY_TOKEN="KEY_TOKEN";

    /**
     * 当前令牌过期时间戳
     */
    String KEY_TOKEN_EXPIRED_TS="KEY_TOKEN_EXPIRED_TS";
}

AndroidManifest.xml

  1. 修改AndroidManifest.xml,把 MainActivity 设置为主应用。
<activity
            android:name=".ui.MainActivity"
            android:exported="true"
            android:label="@string/app_name">
             <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
        </activity>

MainActivity.java

  1. MainActivity 启动时,检查令牌(Token)是否过期,没有过期直接进入 MainActivity,如果令牌过期清除 SharedPreferences 里的值,并且跳转到 LoginActivity。参考代码如下。
SharedPreferences pref=getSharedPreferences(PrefConst.DEFAULT_FILE_NAME,MODE_PRIVATE);
long tokenExpiredTs=pref.getLong(PrefConst.KEY_TOKEN_EXPIRED_TS,0L);
String token=pref.getString(PrefConst.KEY_TOKEN,"");
if(!"".equals(token) && new Date().getTime()<tokenExpiredTs){
	//如果令牌不为空,而且令牌没过期,正常启动 MainActivity
}else{
	//否则跳转到 LoginActivity 重新登录。
}

【实验名称】 实验5.3 SmartHome 项目使用 LitePal 保存当前用户信息到设备

【实验目的】

  • 掌握 LitePal 框架的应用

【实验环境】

  • 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
  • 计算机可以访问互联网。
  • 内存:至少6G
  • 硬盘:至少空余20G
  • JDK 8或以上
  • Android Studio
  • iot-cloud 物联网云平台

【实验要求】

  • (1)本实验承接实验5.2项目 SmartHome
  • (2)当用户点击“我”菜单时,APP 通过远程API 获取到用户信息(包括用户ID,姓名,头像),并使用 LitePal 框架保存当前用户信息到 SQLite。当下次再次点击“我”菜单时,直接从 SQLite 读取数据。只有当用户下拉刷新时,才重新从远程 API 请求数据。

【实验步骤】

项目目录架构

src
  |-main
    build.gradle
    |- AndroidManifest.xml
	|- assets
	  |- litepal.xml
    |- java
        |-iot.app.smarthome
		  |- SmarthomeApplication        
      	  |- model
      	    |- user
      	      |- UserInfoVo.java

build.gradle(Module 模块级别)

  1. 请在dependencies中加入以下 implementation 开头的代码,引入依赖的包
dependencies {

    //请在dependencies中加入以下代码
    implementation 'org.litepal.guolindev:core:3.2.3'

}

AndroidManifest.xml

  1. 在 application 标签下加入android:name属性,指定 Application
 <application
        android:name="iot.app.smarthome.SmarthomeApplication"

SmarthomeApplication.java

  1. 在 Application 启动阶段初始化 LitePal。
package iot.app.smarthome;

import android.app.Application;

import org.litepal.LitePal;

public class SmarthomeApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        LitePal.initialize(this);
    }
}

litepal.xml

  1. 配置 LitePal 数据库名称,和相关映射类。
<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <!--
    	定义应用程序的数据库名称。默认情况下,每个数据库名称应以.db结束。如果你没有名字数据库以.db结束, LitePal将为您自动加上后缀。例如:
    	<dbname value="demo" />
    -->
    <dbname value="SmartHome" />

    <!--
        定义数据库的版本。每一次当你想要数据库升级时,版本标记会有帮助。
        修改模型中定义的映射标签“version”,就使版本值+ 1,数据库的升级将自动处理而不会出现问题。例如:
    	<version value="1" />
    -->
    <version value="1" />

    <list>
        <mapping class="iot.app.smarthome.model.user.UserInfoVo"  />
    </list>

    <!--
        定义.db文件的位置。
        “internal”表示.db文件将存储在内部存储的数据库文件夹中,无人可以访问。
        “external”表示.db文件将存储在主外部存储设备上目录的路径中,每个人都可以访问的永久文件。
        默认值为“内部 internal”。 例如:
        <storage value =“external”/>
    -->

</litepal>

UserInfoVo.java(请完善代码)

  1. 映射当前用户信息表的类
package iot.app.smarthome.model.user;


import org.litepal.crud.LitePalSupport;

public class UserInfoVo extends LitePalSupport {
    private long id;
    private String username;
    private String userid;
    private String avatar;

    //TODO:请补充完整 getter 和 setter
}

LitePal 保存数据、删除数据的参考代码

  1. 请修改 MineFragment ,请求用户数据成功以后,把用户数据(包括用户名,姓名,头像路径)通过 LitePal 框架保存到 Sqlite。 LitePal 插入、删除和查询数据的参考代码如下。
//保存当前用户信息
UserInfoVo userInfo=new UserInfoVo();
userInfo.setUsername("用户姓名");
userInfo.setUserid("用户名");
userInfo.setAvatar("头像路径");
userInfoVo.save();

//删除表所有数据
LitePal.deleteAll(UserInfoVo.class);

//查找第一行数据
LitePal.findFirst(UserInfoVo.class);

【实验名称】 实验5.4 SmartHome 项目保存当前登录用户的头像到设备

【实验目的】

  • 掌握保存文件到 Android 设备

【实验环境】

  • 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
  • 计算机可以访问互联网。
  • 内存:至少6G
  • 硬盘:至少空余20G
  • JDK 8或以上
  • Android Studio

【实验要求】

  • (1)本实验承接实验5.3项目 SmartHome
  • (2)当用户点击“我”菜单时,APP 通过远程API 获取到用户头像图片。请优化代码把用户头像图片保存在设备上,当下次再次点击“我”菜单时,直接设备文件系统读取图片。只有当用户下拉刷新时,才重新从远程 API 下载图片。

【实验步骤】

项目目录架构

src
  |-main
    |- java
        |-iot.app.smarthome
		  |- model
		    |- FileUtil.java

FileUtil.java

  1. 请修改MineFragment代码,调用FileUtil 保存和获取设备的文件。
package iot.app.smarthome.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileUtil {
    public static File saveAvatar(Bitmap bitmap,String fileName){
        File avaterFile = new File("/data/data/iot.app.smarthome/avatar", fileName);
        if(!avaterFile.getParentFile().exists()){
            avaterFile.getParentFile().mkdirs();
        }
        if(avaterFile.exists()){
            avaterFile.delete();
        }
        try {
            avaterFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(avaterFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
            Log.d("FileUtil","保存图片到"+avaterFile.getAbsoluteFile());
        } catch (IOException e) {
            Log.e("FileUtil",e.getMessage());
        }
        return avaterFile;
    }

    public static Bitmap getAvatar(String path){
        Bitmap bitmap = null;
        try{
            File avaterFile = new File(path);
            if(avaterFile.exists()) {
                bitmap = BitmapFactory.decodeFile(avaterFile.getAbsolutePath());
            }
        } catch (Exception e) {
            Log.e("FileUtil",e.getMessage());
        }
        return bitmap;
    }
}

扫码或长按识别访问