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

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 Android在未root手机获取应用内置的SQLite数据库到电脑上处理的方法(数据库备份与恢复-支持SDK30+),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/139895.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!