使用Phonegap从SQLLite db for Android填充数据

使用Phonegap从SQLLite db for Android填充数据,android,sqlite,cordova,Android,Sqlite,Cordova,我正在为基于phonegap的Android应用程序使用SQLLite。我面临的问题是,只要该应用程序处于打开状态,我就能够获取我存储在local.db文件中的任何数据。 例如,我有一个设置功能,用户可以保存他/她的设置并将其转到数据库。现在我面临的问题是,一旦应用程序关闭,我无法获取用户保存的数据,只要应用程序打开,我就可以获取数据。 所以问题是数据库不是持久的。即使应用程序关闭,有人能告诉我如何在内存中存储数据吗 这是我的主要活动文件 public class Demo extends Co

我正在为基于phonegap的Android应用程序使用SQLLite。我面临的问题是,只要该应用程序处于打开状态,我就能够获取我存储在local.db文件中的任何数据。 例如,我有一个设置功能,用户可以保存他/她的设置并将其转到数据库。现在我面临的问题是,一旦应用程序关闭,我无法获取用户保存的数据,只要应用程序打开,我就可以获取数据。 所以问题是数据库不是持久的。即使应用程序关闭,有人能告诉我如何在内存中存储数据吗

这是我的主要活动文件

public class Demo extends CordovaActivity 
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        super.init();
        super.loadUrl(Config.getStartUrl());            
        try {
            String pName = this.getClass().getPackage().getName();
            this.copy("Databases.db", "/data/data/" + pName + "/app_database/");
            this.copy("0000000000000001.db", "/data/data/" + pName
                    + "/app_database/file__0/");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    void copy(String file, String folder) throws IOException {

        File CheckDirectory;
        CheckDirectory = new File(folder);
        if (!CheckDirectory.exists()) {
            CheckDirectory.mkdir();
            InputStream in = getApplicationContext().getAssets().open(file);
        OutputStream out = new FileOutputStream(folder + file);

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0)
            out.write(buf, 0, len);
        in.close();
        out.close();
        }
    }
} 
以下是我授予的权限:-

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

你知道如何解决这个问题吗?

只需创建一个空白数据库,并用新的数据库替换它

Thread getData = new Thread() {
        public void run() {

            Data.qh = new QueryHandler(mContext); // for creating a blank DB
            DB_PATH = getDatabasePath("htest.sqlite").getAbsolutePath(); // get the path of blank DB
            copyDataBase(mContext);

        };
    };


void copyDataBase(Context mContext) {

        try {

            String outFileName = DB_PATH;

            OutputStream myOutput = new FileOutputStream(outFileName);

            byte[] buffer = new byte[1024];
            int length;

            InputStream myInput = mContext.getAssets().open("htest.sqlite");
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myInput.close();

            myOutput.flush();
            myOutput.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

下面是示例代码,这是在html页面中实现的Javascript调用

function onDeviceReady() 
{
  var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
  db.transaction(populateDB, errorCB, successCB);
}
然后我们需要在表中填充数据,调用方法

function populateDB(tx) 
{
  var id=$('#id').val();
  var firstname=$('#firstname').val();        
  tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, firstname)');
  tx.executeSql('INSERT INTO DEMO (id, firstname) VALUES (?, ?)', [id, firstname]);
}
要保存数据,请在任何事件中执行以下操作

<button class="button" id="clickMe" onclick="onDeviceReady();" >Save</button>
保存

您的数据库是持久性的,问题是每次应用程序启动时,onCreate()中对copy()方法的调用都会用资产中保存的副本再次覆盖数据库。我想你只想复印一次。一种方法是仅在目标目录不存在时进行复制:

if (!CheckDirectory.exists()) {
    CheckDirectory.mkdir();
    ...move the copy code inside this if block
}
或者,您可以在共享首选项中存储一个标志,并在制作副本时将其设置为true。在onCreate中,仅当该标志为false时才执行复制

编辑:

要使用共享首选项标志,请执行以下操作:

在onCreate中:

SharedPreferences sp = getSharedPreferences("MYPREFS", Activity.MODE_PRIVATE);

//If no shared prefs exist, e.g. first install, it doesn't matter - the following will return false as a default
Boolean database_copied = sp.getBoolean("database_copied", false);

if (!database_copied)
{
    try {
        String pName = this.getClass().getPackage().getName();
        this.copy("Databases.db", "/data/data/" + pName + "/app_database/");
        this.copy("0000000000000001.db", "/data/data/" + pName
                + "/app_database/file__0/");
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean("database_copied", true);
        editor.apply();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我已经做了你所说的,实际上问题是数据库在应用程序关闭时无法获取保存的记录,否则,当应用程序打开时,它就可以正常工作。是的,将复制代码移动到if条件就成功了。非常感谢:)NigelK:卸载以前的版本并创建新的版本现在向我显示了一个错误。这就是我得到的错误:-E/SQLiteLog(26682):(1)没有这样的表:CacheGroups。知道我做错了什么吗?我已经用错误日志更新了我的问题,请检查并让我知道我做错了什么。我希望卸载会删除/app_数据库/文件夹。但是它看起来不是,因此复制代码不会运行。我的另一个使用SharedReferences的建议可能更可靠。如果您愿意,请随时拒绝我的回答,因为更多的人会再次关注您的问题。是的,卸载时会清除共享首选项,这实际上是关键。读取首选项时,可以在不存在该首选项的情况下指定默认值。请看我的编辑。
SharedPreferences sp = getSharedPreferences("MYPREFS", Activity.MODE_PRIVATE);

//If no shared prefs exist, e.g. first install, it doesn't matter - the following will return false as a default
Boolean database_copied = sp.getBoolean("database_copied", false);

if (!database_copied)
{
    try {
        String pName = this.getClass().getPackage().getName();
        this.copy("Databases.db", "/data/data/" + pName + "/app_database/");
        this.copy("0000000000000001.db", "/data/data/" + pName
                + "/app_database/file__0/");
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean("database_copied", true);
        editor.apply();
    } catch (IOException e) {
        e.printStackTrace();
    }
}