当前位置: 首页 > news >正文

Android 之 存储(Assets目录,SharedPreferences,数据库,内部存储等)

一.Assets目录操作

/*** 读取Assets目录下面的json文件* */
public class JAssetsUtils {/*** 读取Assets目录下面指定文件并返回String数据* @param context* @param fileName* @return*/public static String getJsonDataFromAssets(Context context, String fileName) {StringBuilder stringBuilder = new StringBuilder();InputStream inputStream = context.getClass().getClassLoader().getResourceAsStream("assets/" + fileName);try {byte[] buffer = new byte[inputStream.available()];inputStream.read(buffer);String json = new String(buffer, "utf-8");stringBuilder = stringBuilder.append(json);}catch (IOException e) {e.printStackTrace();}finally {try {inputStream.close();}catch (IOException e) {e.printStackTrace();}}return stringBuilder.toString();}
}

二.SharedPreferences

1.封装工具类

public class SpfUtils {/*** 保存在手机里面的文件名*/public static final String FILE_NAME = "share_data";/*** 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法** @param context* @param key* @param object*/public static void put(Context context, String key, Object object) {SharedPreferences sp = context.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE);SharedPreferences.Editor editor = sp.edit();if (object instanceof String) {editor.putString(key, (String) object);} else if (object instanceof Integer) {editor.putInt(key, (Integer) object);} else if (object instanceof Boolean) {editor.putBoolean(key, (Boolean) object);} else if (object instanceof Float) {editor.putFloat(key, (Float) object);} else if (object instanceof Long) {editor.putLong(key, (Long) object);} else {editor.putString(key, object.toString());}SharedPreferencesCompat.apply(editor);}/*** 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值** @param context* @param key* @param defaultObject* @return*/public static Object get(Context context, String key, Object defaultObject) {SharedPreferences sp = context.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE);if (defaultObject instanceof String) {return sp.getString(key, (String) defaultObject);} else if (defaultObject instanceof Integer) {return sp.getInt(key, (Integer) defaultObject);} else if (defaultObject instanceof Boolean) {return sp.getBoolean(key, (Boolean) defaultObject);} else if (defaultObject instanceof Float) {return sp.getFloat(key, (Float) defaultObject);} else if (defaultObject instanceof Long) {return sp.getLong(key, (Long) defaultObject);}return null;}/*** 移除某个key值已经对应的值** @param context* @param key*/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);SharedPreferencesCompat.apply(editor);}/*** 清除所有数据** @param context*/public static void clear(Context context) {SharedPreferences sp = context.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE);SharedPreferences.Editor editor = sp.edit();editor.clear();SharedPreferencesCompat.apply(editor);}/*** 查询某个key是否已经存在** @param context* @param key* @return*/public static boolean contains(Context context, String key) {SharedPreferences sp = context.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE);return sp.contains(key);}/*** 返回所有的键值对** @param context* @return*/public static Map<String, ?> getAll(Context context) {SharedPreferences sp = context.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE);return sp.getAll();}/*** 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类** @author zhy*/private static class SharedPreferencesCompat {private static final Method sApplyMethod = findApplyMethod();/*** 反射查找apply的方法** @return*/@SuppressWarnings({"unchecked", "rawtypes"})private static Method findApplyMethod() {try {Class<SharedPreferences.Editor> clz = SharedPreferences.Editor.class;return clz.getMethod("apply");} catch (NoSuchMethodException e) {}return null;}/*** 如果找到则使用apply执行,否则使用commit** @param editor*/public static void apply(SharedPreferences.Editor editor) {try {if (sApplyMethod != null) {sApplyMethod.invoke(editor);return;}} catch (IllegalArgumentException e) {} catch (IllegalAccessException e) {} catch (InvocationTargetException e) {}editor.commit();}}}  

2.存储数据

SpfUtils.put(OBU_Trade_Activity.this,"ber_xiaofei",text);

3.读取数据

boolean lanyas = (boolean) SpfUtils.get(this, "lanya", true);

三.sqllite数据库使用-第三方数据库ormlite

 ​​一、基础配置​

​1. 添加依赖​

在 build.gradle 中引入 OrmLite:

dependencies {implementation 'com.j256.ormlite:ormlite-android:5.0'implementation 'com.j256.ormlite:ormlite-core:5.0'
}

2. 权限声明(如需操作外部存储)​

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

​二、数据模型定义​

使用注解将 Java 类映射为数据库表:

@DatabaseTable(tableName = "users")
public class User {@DatabaseField(generatedId = true) // 自增主键private int id;@DatabaseField(columnName = "name", canBeNull = false)private String name;@DatabaseField(columnName = "age")private int age;// 必须包含无参构造方法public User() {} // Getter/Setter 省略
}注解说明​​:@DatabaseTable:指定表名。
@DatabaseField:定义字段属性,支持 generatedId(自增)、unique(唯一)、foreign(外键)等。
​​强制要求​​:类必须提供无参构造方法

三、数据库管理​

​1. 创建 DatabaseHelper​

继承 OrmLiteSqliteOpenHelper 管理数据库:

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {private static final String DB_NAME = "app.db";private static final int DB_VERSION = 1;public DatabaseHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db, ConnectionSource cs) {try {TableUtils.createTable(cs, User.class); // 创建表} catch (SQLException e) {e.printStackTrace();}}@Overridepublic void onUpgrade(SQLiteDatabase db, ConnectionSource cs, int oldVer, int newVer) {try {TableUtils.dropTable(cs, User.class, true); // 删除旧表onCreate(db, cs); // 重建新表} catch (SQLException e) {e.printStackTrace();}}// 单例模式获取 Helperpublic static synchronized DatabaseHelper getInstance(Context context) {if (instance == null) {instance = new DatabaseHelper(context);}return instance;}
}

四、CRUD 操作​

1. 获取 Dao 对象​​
DatabaseHelper helper = DatabaseHelper.getInstance(context);
Dao<User, Integer> userDao = helper.getDao(User.class); // 泛型:模型类 + 主键类型​​2. 插入数据​​
User user = new User("Alice", 30);
userDao.create(user); // 插入单条
// 或防重复插入:userDao.createIfNotExists(user);​​3. 查询数据​​
// 查询所有用户
List<User> users = userDao.queryForAll();// 按条件查询(年龄大于25)
List<User> users = userDao.queryBuilder().where().gt("age", 25).query();​​4. 更新数据​​
user.setName("Bob");
userDao.update(user); // 更新整个对象
// 或部分更新:UpdateBuilder​​5. 删除数据​​
userDao.deleteById(1); // 按ID删除
// 或条件删除:userDao.deleteBuilder().where().eq("name", "Alice").delete();6.高级,条件查询
QueryBuilder<VideoTagInfo, Integer> queryBuilder = videoTagInfoIntegerDao.queryBuilder();
try {queryBuilder.where().eq("value",roomId).and().eq("myFocus",true);VideoTagInfo videoTagInfo = queryBuilder.queryForFirst();long count = queryBuilder.countOf();Log.i("ss","___count:"+count+"_____videoTagInfo:"+videoTagInfo);if(videoTagInfo != null){return true;}} catch (SQLException e) {Log.i("ss","__e:"+e);e.printStackTrace();}7.高级, 更新UpdateBuilder<Life_Devices, Integer> life_devicesIntegerUpdateBuilder = userDao.updateBuilder();
life_devicesIntegerUpdateBuilder.updateColumnValue("storid", storid).where().eq("deviceid", deviceid);
life_devicesIntegerUpdateBuilder.update();

四.内部存储

以下是一个功能全面的Android文件操作工具类FileUtils,集成了内部存储、外部存储、文件加密等常用操作,并适配了Android 10+的分区存储限制。代码包含详细注释和异常处理,可直接集成到项目中:

import android.content.Context;
import android.os.Environment;
import android.util.Log;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;/*** 文件操作工具类(兼容Android 10+)* 功能:文件读写、加密存储、目录管理、缓存清理等*/
public final class FileUtils {private static final String TAG = "FileUtils";private static final String AES_KEY = "YourAESKey123456"; //  AES密钥(需自定义)// 禁用构造方法private FileUtils() {throw new UnsupportedOperationException("工具类无需实例化");}/*------------------------ 内部存储操作 ------------------------*//*** 保存文本到内部私有目录* @param context 上下文* @param fileName 文件名(不含路径)* @param content 文本内容* @param mode 写入模式(Context.MODE_PRIVATE 或 MODE_APPEND)*/public static void writeInternal(Context context, String fileName, String content, int mode) {try (FileOutputStream fos = context.openFileOutput(fileName, mode)) {fos.write(content.getBytes(StandardCharsets.UTF_8));} catch (IOException e) {Log.e(TAG, "内部存储写入失败: " + e.getMessage());}}/*** 读取内部存储文件* @return 文件内容,失败返回空字符串*/public static String readInternal(Context context, String fileName) {try (FileInputStream fis = context.openFileInput(fileName);BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {StringBuilder sb = new StringBuilder();String line;while ((line = reader.readLine()) != null) {sb.append(line);}return sb.toString();} catch (IOException e) {Log.e(TAG, "内部存储读取失败: " + e.getMessage());return "";}}/*------------------------ 外部存储操作(适配分区存储) ------------------------*//*** 获取应用专属外部存储目录* @param context 上下文* @param type 目录类型(如 Environment.DIRECTORY_DOCUMENTS)* @return 路径,无权限或不可用时返回null*/public static File getExternalAppDir(Context context, String type) {if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {return null;}// Android 10+ 使用专属目录,无需权限return type != null ? context.getExternalFilesDir(type) : context.getExternalFilesDir(null);}/*** 保存文本到外部存储专属目录* @param content 文本内容* @param dirType 目录类型(如 Environment.DIRECTORY_DOCUMENTS)*/public static boolean writeExternal(Context context, String fileName, String content, String dirType) {File dir = getExternalAppDir(context, dirType);if (dir == null || !dir.exists()) return false;File file = new File(dir, fileName);try (FileWriter writer = new FileWriter(file)) {writer.write(content);return true;} catch (IOException e) {Log.e(TAG, "外部存储写入失败: " + e.getMessage());return false;}}/*------------------------ 文件管理 ------------------------*//*** 删除文件(支持内部/外部路径)* @param filePath 完整文件路径*/public static boolean deleteFile(String filePath) {File file = new File(filePath);return file.exists() && file.delete();}/*** 复制文件* @param srcPath 源文件路径* @param destPath 目标文件路径* @return 是否成功*/public static boolean copyFile(String srcPath, String destPath) {try (InputStream is = new FileInputStream(srcPath);OutputStream os = new FileOutputStream(destPath)) {byte[] buffer = new byte[1024];int length;while ((length = is.read(buffer)) > 0) {os.write(buffer, 0, length);}return true;} catch (IOException e) {Log.e(TAG, "文件复制失败: " + e.getMessage());return false;}}/*------------------------ 加密操作 ------------------------*//*** AES加密后保存文件* @param content 明文内容*/public static void saveEncrypted(Context context, String fileName, String content) {try {byte[] encrypted = encryptAES(content.getBytes(StandardCharsets.UTF_8));try (FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE)) {fos.write(encrypted);}} catch (Exception e) {Log.e(TAG, "加密存储失败: " + e.getMessage());}}private static byte[] encryptAES(byte[] data) throws Exception {SecretKeySpec keySpec = new SecretKeySpec(AES_KEY.getBytes(), "AES");Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, keySpec);return cipher.doFinal(data);}/*------------------------ 缓存管理 ------------------------*//*** 清理应用缓存目录* @return 是否成功*/public static boolean clearAppCache(Context context) {File cacheDir = context.getCacheDir();return deleteDir(cacheDir);}private static boolean deleteDir(File dir) {if (dir == null || !dir.isDirectory()) return false;for (File file : dir.listFiles()) {if (file.isDirectory()) deleteDir(file);else file.delete();}return dir.delete();}
}

 使用示例

// 1. 写入内部存储(覆盖模式)
FileUtils.writeInternal(context, "config.txt", "用户设置数据", Context.MODE_PRIVATE);// 2. 追加内容到内部存储
FileUtils.writeInternal(context, "log.txt", "新日志条目", Context.MODE_APPEND);// 3. 读取内部存储文件
String config = FileUtils.readInternal(context, "config.txt");// 4. 写入加密文件
FileUtils.saveEncrypted(context, "secret.dat", "敏感数据");// 5. 操作外部存储(Android 10+无需权限)
File docDir = FileUtils.getExternalAppDir(context, Environment.DIRECTORY_DOCUMENTS);
if (docDir != null) {FileUtils.writeExternal(context, "report.pdf", "PDF内容", Environment.DIRECTORY_DOCUMENTS);
}// 6. 清理缓存
FileUtils.clearAppCache(context);

http://www.dtcms.com/a/312980.html

相关文章:

  • 音视频学习(五十):音频无损压缩
  • 使用 Docker 部署 Golang 程序
  • 计数组合学7.12( RSK算法的一些推论)
  • 考研复习-计算机组成原理-第二章-数据的表示和运算
  • PHP面向对象编程与数据库操作完全指南-下
  • 深入解析C++函数重载:从原理到实践
  • 2025年测绘程序设计比赛--基于统计滤波的点云去噪(已获国特)
  • MySQL梳理三:查询与优化
  • python新功能match case|:=|typing
  • Hertzbeat如何配置redis?保存在redis的数据是可读数据
  • 【MySQL安全】什么是SQL注入,怎么避免这种攻击:前端防护、后端orm框架、数据库白名单
  • Android设备认证体系深度解析:GMS/CTS/GTS/VTS/STS核心差异与认证逻辑
  • ELECTRICAL靶机复现练习笔记
  • Leetcode:1.两数之和
  • Java 大视界 -- Java 大数据机器学习模型在金融市场情绪分析与投资决策辅助中的应用(379)
  • ubuntu24.04安装selenium、edge、msedgedriver
  • 05.Redis 图形工具RDM
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第四天(DOM编程和AJAX异步交互)
  • k8s+isulad 国产化技术栈云原生技术栈搭建1-VPC
  • 使用ACK Serverless容器化部署大语言模型FastChat
  • 如何在不停机的情况下,将MySQL单库的数据迁移到分库分表的架构上?
  • 【前端安全】聊聊 HTML 闭合优先级和浏览器解析顺序
  • [AI8051U入门第十五步]W5500实现DHCP自动获取IP
  • SpringBoot+Vue高校实验室预约管理系统 附带详细运行指导视频
  • Matlab算法编程示例4:数值解法求解常微分方程的代码实例
  • Python类与对象指南
  • java贪吃蛇小程序
  • 个人项目介绍:STM32F407核心多层电路板
  • Java试题-选择题(8)
  • 25 渗透测试培训课程第一部分 - 信息收集 内容概要