Unity sqlite android数据库查询问题(“找不到表”)

问题描述 投票:0回答:2

我试图在Android / PC游戏中实现本地数据库(sqlite)

我能够从编辑器和游戏的独立电脑版本加载数据库,但Android版本有一个错误,没有找到我试图查询的表格

这是将数据库从流资产文件夹加载到三个列表中的代码

using System;
using System.IO;
using System.Data;
using System.Collections;
using System.Collections.Generic;

using Mono.Data.Sqlite;

using UnityEngine;
using UnityEngine.SceneManagement;


public class DBAdministrator : MonoBehaviour {

    //
    //Android sdk > platform-tools > adb logcat MarsGames.ChippyRemix *:E

    public List<LevelDP> levelsList;

    public List<LevelDP> defaultLevels;
    public List<LevelDP> myLevels;
    public List<LevelDP> otherLevels;

    GameObject playMenu;
    public string myName;
    public string defaultName = "chippy";

    public string debugString;

    void Start () {
        //myName = PlayerPrefs.GetString("MyName");
        playMenu = GameObject.FindWithTag("UI");

        //levelsList = new List<LevelDP>();
        defaultLevels   = new List<LevelDP>();
        myLevels        = new List<LevelDP>();
        otherLevels     = new List<LevelDP>();        
        //Fill the list

        FillLists();
        //PrintAllLevels();
        if(playMenu !=  null){
            playMenu.SendMessage("CreateDisplayLists");
        }
    }


    void FillLists(){
        //Path to database

        string conn = "";

        //Debug.Log(Application.streamingAssetsPath);

        #if UNITY_EDITOR_WIN

            //Debug.Log("Using unity editor conn");
            conn = "URI=file:" + Application.dataPath + "/StreamingAssets/chickdb.db";
        #elif UNITY_ANDROID

            debugString = "Using andriod";
            conn = Application.persistentDataPath + "/chickdb.db";
            if(!File.Exists(conn)){
                debugString = "DB file does not exist";
                //Open Streaming assets and load the db
                WWW loadDb = new WWW("jar:file://" + Application.dataPath + "!/assets/chickdb.db");
                while (!loadDb.isDone) { }
                File.WriteAllBytes(conn,loadDb.bytes);
            }else{
                debugString = "File exists";
                //debugString = conn;
            }
            //Once file is loaded, use the appropiate filepath to access db
            conn = "URI=file:" + Application.persistentDataPath + "/chickdb.db";
        #elif UNITY_STANDALONE
            //debugString = "Using standalone PC";
            //string conn = "URI=file:" + System.IO.Path.Combine(Application.streamingAssetsPath, "Database/TMDB.s3db");
            //conn = "URI=File:" + System.IO.Path.Combine(Application.streamingAssetsPath,"/StreamingAssets/chickdb.db");
            conn = "URI=file:" + Application.streamingAssetsPath + "/chickdb.db";
            debugString = conn;
        /*
        #elif UNITY_IOS
            debugString = "Using ios";
            // this is the path to your StreamingAssets in iOS
            var loadDb = Application.dataPath + "/Raw/chickdb.do";
            // then save to Application.persistentDataPath
            File.Copy(loadDb, filepath);
            //conn = "URI=file " + Application.persistentDataPath + "/chickdb.db"; 
        */
        #endif

        //Debug.Log("ST Connection DB: " + conn);

        #if UNITY_ANDROID
            debugString = "Connection Attempted";
        #endif

        IDbConnection dbconn = (IDbConnection) new SqliteConnection(conn);

        //Open connection to the database.
        dbconn.Open(); 

        #if UNITY_ANDROID
            debugString = "Database Open";
        #endif

        IDbCommand dbcmd = dbconn.CreateCommand();

        string sqlQuery = "SELECT * FROM levels";

        dbcmd.CommandText = sqlQuery;

        IDataReader reader = dbcmd.ExecuteReader();

        #if UNITY_ANDROID
            debugString = "Query executed";
        #endif
        while (reader.Read()){

            LevelDP lp = new LevelDP();

            lp.SetLevelID(reader.GetInt32(0));
            lp.SetLevelName(reader.GetString(1));
            lp.SetCreationDate(reader.GetString(2));
            lp.SetUserID(reader.GetString(3));
            lp.SetBlocks(reader.GetString(4));
            lp.SetCompleted(reader.GetInt32(5));

            //levelsList.Add(lp);

            if(lp.GetUserID().Equals(defaultName)){
                defaultLevels.Add(lp);
            }else if(lp.GetUserID().Equals(myName)){
                myLevels.Add(lp);
            }else{
                otherLevels.Add(lp);
            }
        }

        //Close the db reader
        reader.Close();
        reader = null;
        //Close the comand executer
        dbcmd.Dispose();
        dbcmd = null;
        //Close the db connection
        dbconn.Close();
        dbconn = null;
    }

    void PrintAllLevels(){
        Debug.Log("Print all levels");
        for(int i = 0; i < defaultLevels.Count; i++){

            Debug.Log(defaultLevels[i].ToString());
        }
        for(int i = 0; i < myLevels.Count; i++){

            Debug.Log(myLevels[i].ToString());
        }
        for(int i = 0; i < otherLevels.Count; i++){

            Debug.Log(otherLevels[i].ToString());
        }
    }
 }

从这个代码我已经能够打印(“数据库打开”),但当数据库应该查询时,我得到一个错误(来自adb工具)状态(“表级别未找到”),我不知道在哪里错误是

我必须添加编辑器,并且pc构建工作正常,

我遵循的步骤是:

将.db文件放在Streaming Assets文件夹中解压缩.apk并通过sqlitebrowser检查.db文件中的值

我有一个理论,也许我没有在#if UNITY_ANDROID条件语句中正确地将数据库加载到内存中,但几乎所有其他的例子我见过这样工作

c# android database sqlite unity3d
2个回答
1
投票

我不能发表评论,这就是我写答案的原因。

在测试游戏/应用程序时,尝试使用Debug.Log来查看路径文件。然后检查您的sq3db文件是否在正确的文件夹中。

我有一个类似的流式传输sqlite数据库的代码,但如果我在PC上测试它,数据库应该在Assets文件夹中而不是在StreamingAssets文件夹中。

编辑1:

首先:我将向您展示我制作游戏时使用的代码片段:

if(Application.platform != RuntimePlatform.Android)
    _filepath =  Application.dataPath + "/" + _DBName;    
else
{
    _filepath = Application.persistentDataPath + "/" + _DBName;
    if (!File.Exists(_filepath))
    {
        //Debug.Log("Check in");
        WWW loadDB = new WWW("jar:file://" + Application.dataPath + 
            "!/assets/" + _DBName);

        while (!loadDB.isDone) { }
        File.WriteAllBytes(_filepath, loadDB.bytes);
    }
}
    _StringConnection = "URI=file:" + _filepath;

第二:当我在PC上测试游戏时(统一编辑器)我在这里有我的数据库(.s3db):ProjectName / Assets / Database.s3db

当我在Android上运行游戏时,我在这里有我的数据库:ProjectName / Assets / StreamingAssets / Database.s3db

你可能会注意到我的数据库文件扩展名是s3db,我使用的是SQlite3,但无论如何都应该可以工作。


0
投票

在Android中,sqlite db应该保存在持久数据路径中。我将我的sqlite数据库放在扩展名为.txt的资源中,并将其作为文本读取。然后在代码中查找扩展并将其保存在Application.persistentDataPath中。

© www.soinside.com 2019 - 2024. All rights reserved.