android studio sqliteopenhelper,SQLiteOpenHelper使用指定位置数据库

这篇博客介绍了如何在Android 6.0及以上版本中,使用SQLiteOpenHelper将数据库文件保存到外部存储,并处理权限问题。通过创建自定义的DatabaseContext类重写getDatabasePath和openOrCreateDatabase方法,实现了数据库文件的指定位置创建。同时,文章提到了需要针对Android 6.0及以上版本动态申请READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,并提供了相应的代码示例和权限申请工具类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章转自本人优快云博客

目标和环境

最近项目中需要事实存储监测的数据,于是使用SQLiteOpenHelper来实现。事后又要导出到分析软件分析,所以必须将db文件放到指定的位置。SQLiteOpenHelper默认的位置只有app自己访问,想导出来很麻烦。一番搜索和试错后,终于实现功能。手机版本是android6.0,studio3.5.2。

虽然csdn上面能看到不少相关的文章,奈何google更猛。所以好多文章照着做也是失败。最后终于在stackoverflow这个问题下面k3b大佬的回复找到了解决方法。

代码

自己写的SQLiteOpenHelper类中间要有如下的改动:

public class DatabaseHelper extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 3;

.....

DatabaseHelper(final Context context, String databaseName) {

super(new DatabaseContext(context), databaseName, null, DATABASE_VERSION);

}

}

创件一个DatabaseContext类继承ContextWrapper并重写getDatabasePath和openOrCreateDatabase

class DatabaseContext extends ContextWrapper {

private static final String DEBUG_CONTEXT = "DatabaseContext";

public DatabaseContext(Context base) {

super(base);

}

@Override

public File getDatabasePath(String name) {

File sdcard = Environment.getExternalStorageDirectory();

String dbfile = sdcard.getAbsolutePath() + File.separator+ "databases" + File.separator + name;

if (!dbfile.endsWith(".db")) {

dbfile += ".db" ;

}

File result = new File(dbfile);

if (!result.getParentFile().exists()) {

result.getParentFile().mkdirs();

}

if (Log.isLoggable(DEBUG_CONTEXT, Log.WARN)) {

Log.w(DEBUG_CONTEXT, "getDatabasePath(" + name + ") = " + result.getAbsolutePath());

}

return result;

}

/* this version is called for android devices >= api-11. thank to @damccull for fixing this. */

@Override

public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {

return openOrCreateDatabase(name,mode, factory);

}

/* this version is called for android devices < api-11 */

@Override

public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {

SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);

// SQLiteDatabase result = super.openOrCreateDatabase(name, mode, factory);

if (Log.isLoggable(DEBUG_CONTEXT, Log.WARN)) {

Log.w(DEBUG_CONTEXT, "openOrCreateDatabase(" + name + ",,) = " + result.getPath());

}

return result;

}

}

理论上这样就能在指定的位置创建db文件了。

权限

光上面的代码还是不行的,还需要外部存储文件的读写权限,6.0以前只要在manifest里面添加下面这些代码

6.0及以上的就要动态申请。

首先写一个申请类

public class PermissionUtils {

private static String[] PERMISSIONS_CAMERA_AND_STORAGE = {

android.Manifest.permission.READ_EXTERNAL_STORAGE,

android.Manifest.permission.WRITE_EXTERNAL_STORAGE,

android.Manifest.permission.CAMERA};

public static boolean isGrantExternalRW(Activity activity, int requestCode) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

int storagePermission = activity.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

int cameraPermission = activity.checkSelfPermission(android.Manifest.permission.CAMERA);

if (storagePermission != PackageManager.PERMISSION_GRANTED ||

cameraPermission != PackageManager.PERMISSION_GRANTED) {

activity.requestPermissions(PERMISSIONS_CAMERA_AND_STORAGE, requestCode);

return false;

}

}

return true;

}

}

之后在MainActivty的onCreate下添加

PermissionUtils.isGrantExternalRW(this,1);

运行的时候授权就ok了。

关于路径

现在很多手机没有sd卡,但是依然有外部存储。只能APP访问的,就是内部存储,反之,应该是外部存储了。

不管是不是存在sd卡上,注意用正确的get方法拿到正确的路径。我这里是用Environment.getExternalStorageDirectory().getAbsolutePath()拿到根目录的。

否则很容易看到android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (Sqlite code 14)

————————————————

版权声明:本文为优快云博主「bat2fly」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.youkuaiyun.com/bat2fly/article/details/106122061

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值