在上一篇的基础上,我们已经将安卓应用的数据库文件拷贝到了公共文件夹下,接下来,我们需要把这个数据库文件拷贝到Pc端。手机上的数据怎么拷贝到PC上呢,笨办法,连数据线、蓝牙等,自己手动拷,但程序猿的工作不就是将无聊的重复性工作想办法交给电脑么,所以让我们放弃这个蠢笨的办法。

       相信大家在安卓的开发中,使用过adb将文件从你的模拟器或者手机上pull到电脑上进行查看,那么,点子来了,让我们也尝试这种方式。

       我们首先将adb的exe和相关组件dll统一放到我们的WPF工程目录下,这样就可以直接通过相对路径的方式启动adb,而不需要用户手动启动了,如下图所示:

AndroidSQlite数据库读取kotlin_List

      然后呢,在程序中通过通过命令来启动这个我们的Adb,如下图所示:

/// <summary>
        /// adb.exe文件的路径,默认相对于当前应用程序目录取。
        /// </summary>
        public static string AdbExePath
        {
            get
            {
                return Path.Combine(PathUtils.GetProjectRootPath(), "AdbBin\\adb.exe");
            }
        }


        /// <summary>
        /// 启动ADB服务
        /// </summary>
        /// <returns></returns>
        public static bool StartServer()
        {
            return ProcessHelper.Run(AdbExePath, "start-server").Success;
        }

       服务启动之后,我们就可以操作adb的进程,完成你在开发安卓时,对adb的一切操作。这里摘抄了部分代码,更多的功能你可以查看adb shell相关命令,然后解析结果即可。

/// <summary>
        /// 获取设备列表
        /// </summary>
        /// <returns></returns>
        public static string[] GetDevices()
        {
            var result = ProcessHelper.Run(AdbExePath, "devices");

            var itemsString = result.OutputString;
            var items = itemsString.Split(new[] { "$", "#", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);

            var itemsList = new List<String>();
            foreach (var item in items)
            {
                var tmp = item.Trim();

                //第一行不含\t所以排除
                if (tmp.IndexOf("\t") == -1)
                    continue;
                var tmps = item.Split('\t');
                itemsList.Add(tmps[0]);
            }

            itemsList.Sort();

            return itemsList.ToArray();
        }

        /// <summary>
        /// 列举ls /data/data目录下的文件和目录
        /// </summary>
        /// <returns></returns>
        public static List<string> ListDataFolder(string deviceNo)
        {
            var moreArgs = new[] { "su", "ls /data/data", "exit", "exit" };
            var result = ProcessHelper.RunAsContinueMode(AdbExePath, string.Format("-s {0} shell", deviceNo), moreArgs);

            var itemsString = result.MoreOutputString[1];
            var items = itemsString.Split(new[] { "$", "#", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);

            var itemsList = new List<String>();
            foreach (var item in items)
            {
                var tmp = item.Trim();
                //移除第一行,输入的命令
                if (tmp.Contains(moreArgs[1]))
                    continue;
                //移除空白行
                if (string.IsNullOrEmpty(tmp))
                    continue;
                //移除最后两行的root@android
                if (tmp.ToLower().Contains("root@"))
                    continue;
                itemsList.Add(tmp);
            }

            itemsList.Sort();

            return itemsList;
        }

       以上整体的思路就是我们首先启动adb的服务,然后通过向adb服务写命令行的方式,得到结果,解析这个结果,得到我们想要的相关数据,那怎么把安卓上的文件pull到电脑上呢,核心代码如下:

/// <summary>
        /// 拷贝文件到PC上
        /// </summary>
        /// <param name="deviceNo"></param>
        /// <param name="devPath"></param>
        /// <param name="pcPath"></param>
        /// <returns></returns>
        public static bool CopyFromDevice(string deviceNo, string devPath, string pcPath)
        {
            //使用Pull命令将数据库拷贝到Pc上
            //adb pull [-p] [-a] <remote> [<local>]
            var result = ProcessHelper.Run(AdbExePath, string.Format("-s {0} pull {1} {2}", deviceNo, devPath, pcPath));
            m_log.Info("推送PC时结果:" + result.ToString());
            if (!result.Success
                || result.ExitCode != 0
                || (result.OutputString != null && result.OutputString.Contains("failed")))
            {
                return false;
                throw new Exception("pull 执行返回的结果异常:" + result.OutputString);
            }
            return true;
        }

     到此,我们已经将安卓应用下的db数据库文件,拷贝到了电脑上,接下来,让我们解析它~解析的方式这里就不做啰嗦,可以查看我的这篇文章WPF中使用SqLite数据库,这里我直接往下做,使用SqlLite-net-pcl这个ORM框架进行数据读取操作。

    首先新建一个UserDbModel的类,对应着数据库中的usermodel表。

[Table("usermodel")]
    public class UserDbModel
    {
        [PrimaryKey, AutoIncrement]

        public int Id { get; set; }

        public string Email { get; set; }

        public string Password { get; set; }

        public string Username { get; set; }
    }

   再创建一个AndroidDb,继承自SQLiteConnection类,将初始化UserDbModel的方法写在里面。

public class AndroidDb : SQLiteConnection
    {
        //定义属性,便于外部访问数据表
        public TableQuery<UserDbModel> Users { get { return this.Table<UserDbModel>(); } }

        public AndroidDb(string dbPath) : base(dbPath)
        {
            //创建数据表
            CreateTable<UserDbModel>();
        }
    }

  接下来,直接读取数据库中的User表数据。

//本地数据库地址
            string path = strPCFilePath + "\\" + dbName;//数据库所在路径
            //使用SQLite.Net-PCL访问数据库
            using (var db = new AndroidDb(path))
            {
                List<UserDbModel> users = db.Users.Where(m => true).ToList();
                
            }

到此,我们已经完成了pc读取手机应用内部数据库的功能啦,来,欣赏一下吧~

AndroidSQlite数据库读取kotlin_数据库_02