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);
    }

    @Override
    public void onCreate(SQLiteDatabase db, ConnectionSource cs) {
        try {
            TableUtils.createTable(cs, User.class); // 创建表
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public 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();
        }
    }

    // 单例模式获取 Helper
    public 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);

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值