繁体   English   中英

通过Unity在android中使用填充的SQLite数据库

[英]Using populated SQLite database in android via Unity

我将在Android游戏中使用预先填充的SQLite数据库,我正在使用Unity创建。

由于简单的方法在Android上不起作用( 它在Windows上运行完美 ),我已经按照本教程在Android应用程序中使用我的数据库。

public void OpenDB(string p) //p is the database name

{
    // check if file exists in Application.persistentDataPath

    string filepath = Application.persistentDataPath + "/" + p;

    if(!File.Exists(filepath))

    {

        // if it doesn't ->

        // open StreamingAssets directory and load the db -> 

        WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + p);  // this is the path to your StreamingAssets in android

        while(!loadDB.isDone) {}  // CAREFUL here, for safety reasons you shouldn't let this while loop unattended, place a timer and error check

        // then save to Application.persistentDataPath

        File.WriteAllBytes(filepath, loadDB.bytes);

    }

    //open db connection

    connection = "URI=file:" + filepath;

    dbcon = new SqliteConnection(connection);

    dbcon.Open();

}

当我运行此代码时,我收到以下错误:

SqliteSyntaxException:文件已加密或不是数据库

这是完整的错误:

SqliteSyntaxException:文件已加密或不是数据库Mono.Data.SqliteClient.SqliteCommand.GetNextStatement(IntPtr pzStart,System.IntPtr&pzTail,System.IntPtr&pStmt)Mono.Data.SqliteClient.SqliteCommand.ExecuteReader(CommandBehavior behavior,Boolean want_results,System .Int32&rows_affected)Mono.Data.SqliteClient.SqliteCommand.ExecuteReader(CommandBehavior behavior)Mono.Data.SqliteClient.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)System.Data.Common.DbCommand.ExecuteReader()System.Data.Common.DbCommand.System .Data.IDbCommand.ExecuteReader()dbAccess.SingleSelectWhere(System.String tableName,System.String itemToSelect,System.String wCol,System.String wPar,System.String wValue)(在Assets / dbAccess.cs:152)

我已从该帖子下载了该示例,并得到了同样的错误。

我怀疑这一行:

File.WriteAllBytes(filepath, loadDB.bytes); 

而我的想法是出于某种原因,它无法将数据库数据写入文件。

有谁知道如何解决这个问题?

由于这个博客,我解决了这个问题。

由于if语句将根据应用程序运行的平台执行不同的行为,因此此代码在每个平台上都运行良好。

这是重要部分的DataService.cs或者我更好地说整个部分

using SQLite4Unity3d;
using UnityEngine;
#if !UNITY_EDITOR
using System.Collections;
using System.IO;
#endif
using System.Collections.Generic;

public class DataService  {

    private SQLiteConnection _connection;

    public DataService(string DatabaseName){

#if UNITY_EDITOR
            var dbPath = string.Format(@"Assets/StreamingAssets/{0}", DatabaseName);
#else
        // check if file exists in Application.persistentDataPath
        var filepath = string.Format("{0}/{1}", Application.persistentDataPath, DatabaseName);

        if (!File.Exists(filepath))
        {
            Debug.Log("Database not in Persistent path");
            // if it doesn't ->
            // open StreamingAssets directory and load the db ->

#if UNITY_ANDROID 
            var loadDb = new WWW("jar:file://" + Application.dataPath + "!/assets/" + DatabaseName);  // this is the path to your StreamingAssets in android
            while (!loadDb.isDone) { }  // CAREFUL here, for safety reasons you shouldn't let this while loop unattended, place a timer and error check
            // then save to Application.persistentDataPath
            File.WriteAllBytes(filepath, loadDb.bytes);
#elif UNITY_IOS
                 var loadDb = Application.dataPath + "/Raw/" + DatabaseName;  // this is the path to your StreamingAssets in iOS
                // then save to Application.persistentDataPath
                File.Copy(loadDb, filepath);
#elif UNITY_WP8
                var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName;  // this is the path to your StreamingAssets in iOS
                // then save to Application.persistentDataPath
                File.Copy(loadDb, filepath);

#elif UNITY_WINRT
        var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName;  // this is the path to your StreamingAssets in iOS
        // then save to Application.persistentDataPath
        File.Copy(loadDb, filepath);
#else
    var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName;  // this is the path to your StreamingAssets in iOS
    // then save to Application.persistentDataPath
    File.Copy(loadDb, filepath);

#endif

            Debug.Log("Database written");
        }

        var dbPath = filepath;
#endif
            _connection = new SQLiteConnection(dbPath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create);
        Debug.Log("Final PATH: " + dbPath);     

    }

    public void CreateDB(){
        _connection.DropTable<Person> ();
        _connection.CreateTable<Person> ();

        _connection.InsertAll (new[]{
            new Person{
                Id = 1,
                Name = "Tom",
                Surname = "Perez",
                Age = 56
            },
            new Person{
                Id = 2,
                Name = "Fred",
                Surname = "Arthurson",
                Age = 16
            },
            new Person{
                Id = 3,
                Name = "John",
                Surname = "Doe",
                Age = 25
            },
            new Person{
                Id = 4,
                Name = "Roberto",
                Surname = "Huertas",
                Age = 37
            }
        });
    }

    public IEnumerable<Person> GetPersons(){
        return _connection.Table<Person>();
    }

    public IEnumerable<Person> GetPersonsNamedRoberto(){
        return _connection.Table<Person>().Where(x => x.Name == "Roberto");
    }

    public Person GetJohnny(){
        return _connection.Table<Person>().Where(x => x.Name == "Johnny").FirstOrDefault();
    }

    public Person CreatePerson(){
        var p = new Person{
                Name = "Johnny",
                Surname = "Mnemonic",
                Age = 21
        };
        _connection.Insert (p);
        return p;
    }
}

它遵循另外两个脚本来创建或使用现有数据库。

ExistingDBScript.cs

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;

public class ExistingDBScript : MonoBehaviour {

    public Text DebugText;

    // Use this for initialization
    void Start () {
        var ds = new DataService ("existing.db");
        //ds.CreateDB ();
        var people = ds.GetPersons ();
        ToConsole (people);

        people = ds.GetPersonsNamedRoberto ();
        ToConsole("Searching for Roberto ...");
        ToConsole (people);

        ds.CreatePerson ();
        ToConsole("New person has been created");
        var p = ds.GetJohnny ();
        ToConsole(p.ToString());

    }

    private void ToConsole(IEnumerable<Person> people){
        foreach (var person in people) {
            ToConsole(person.ToString());
        }
    }

    private void ToConsole(string msg){
        DebugText.text += System.Environment.NewLine + msg;
        Debug.Log (msg);
    }

}

CreateDBScript.cs

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;

public class CreateDBScript : MonoBehaviour {

    public Text DebugText;

    // Use this for initialization
    void Start () {
        StartSync();
    }

    private void StartSync()
    {
        var ds = new DataService("tempDatabase.db");
        ds.CreateDB();

        var people = ds.GetPersons ();
        ToConsole (people);
        people = ds.GetPersonsNamedRoberto ();
        ToConsole("Searching for Roberto ...");
        ToConsole (people); 
    }

    private void ToConsole(IEnumerable<Person> people){
        foreach (var person in people) {
            ToConsole(person.ToString());
        }
    }

    private void ToConsole(string msg){
        DebugText.text += System.Environment.NewLine + msg;
        Debug.Log (msg);
    }
}

person脚本,在数据库中演示人表

using SQLite4Unity3d;

public class Person  {

    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }

    public override string ToString ()
    {
        return string.Format ("[Person: Id={0}, Name={1},  Surname={2}, Age={3}]", Id, Name, Surname, Age);
    }
}

您还需要将插件和Sqlite.cs添加到您可以在git存储库中找到的项目中

它帮助我克服了这个问题,希望它能帮助其他人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM