Android在未root手机获取应用内置的SQLite数据库到电脑上处理的方法(数据库备份与恢复-支持SDK30+)

54 篇文章 2 订阅

在android中我们常用sqlite数据库来存放文件,在开发中我们可能需要查看数据库中的所有的数据,以保证数据的准确性。在已经root的手机下,我们可以进入

data/data/包名/databases/数据库名称

目录下获取数据库文件,可以在ddms界面导出,用Navicat等软件查看编辑修改。
但如果手机没有root,我们用ddms是打不开/data/data目录的。那如何获取相应的db文件呢?

解决方法:

我们可以利用文件拷贝的方法,在app内置一个数据库备份与恢复功能,即实现从内部到外部的文件复制进出功能即可实现内部数据库的交换。该方法支持所有安卓版本。包括最新的安卓13

代码如下:

    String dbFileName= Environment.getDataDirectory().getAbsolutePath() + "/data/" + getPackageName() + "/databases/mydatabase.db";
    //getExternalFilesDir(null);这个目录会在应用被卸载的时候删除,而且访问这个目录不需要动态申请STORAGE权限。如果这个目录不存在,系统会自动帮你创建
    String dbBakFile= getExternalFilesDir(null) + "/copy.db";
    

public void btnBackClick(View v) {

        //找到文件的路径
         ///data/data/包名/databases/数据库名称
        File dbFile = new File(dbFileName);
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //文件复制到sd卡中
            fis = new FileInputStream(dbFile);
            //fos = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/copy.db");
            fos=new FileOutputStream(dbBakFile);
            int len;
            byte[] buffer = new byte[2048];
            while (-1 != (len = fis.read(buffer))) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭数据流
            try {
                if (fos != null) fos.close();
                if (fis != null) fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Toast.makeText(MainActivity.this,"SQLite数据库备份成功,备份路径:\n"+dbBakFile, Toast.LENGTH_SHORT).show();
    }


    public void btnRestoreClick(View v) {
       /*
        找到备份文件的路径
        /storage/emulated/0/Android/data/yourPackageName/files
        */
        File dbFile = new File(dbBakFile);
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(dbFile);
            //将备份文件复制到 data/data/包名/databases/数据库名称
            fos=new FileOutputStream(dbFileName);
            int len;
            byte[] buffer = new byte[2048];
            while (-1 != (len = fis.read(buffer))) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭数据流
            try {
                if (fos != null) fos.close();
                if (fis != null) fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Toast.makeText(MainActivity.this,"SQLite数据库从备份恢复成功", Toast.LENGTH_SHORT).show();
    }

需要申请文件系统读写权限:

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

说明:如果想把备份文件写入公共目录,比如

/storage/emulated/0/Download 

对这种目录的读写需要特殊的动态权限申请操作(安卓6.0+)

否则会报下面这个错误:

/storage/emulated/0/Download/copy_download.db (Permission denied)

解决方法:

在运行虚拟机时,或者使用高版本的安卓手机时,即使是在清单文件中加了权限,向sd卡写入数据时还是会报错:

其实这个问题是由于Android6.0更新了权限机制,在6.0之前,写入sd卡权限只需在清单文件中添加 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>即可,而在6.0中,则需要在activity中用代码来请求一些敏感的权限,其中就包括对sd卡的操作权限。对这个问题有以下几种解决办法:

  1. 打开虚拟机的Setting–>Apps–>找到你的应用–>点击Permissions–>将需要的权限手动打开
  2. 将targetSdkVersion设置为小于23,然后重新编译
  3. 手动在activity添加请求权限的代码,具体代码可参考如下链接: 
    Android 6.0 运行时权限处理 http://www.jianshu.com/p/b4a8b3d4f587
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值