我正在尝试构建一个默认数据库,我的应用程序每次打开时都会使用该数据库。 为此,我做了一个简短的程序来转换我拥有的某个JSON文件中的数据,并将其传递给我创建的空db文件。 解析JSON工作正常,我能够获得它的所有内容。 但是当我尝试将该内容保存到db文件中时,我得到:
E/Database(361): Error inserting password=1234
E/Database(361): android.database.sqlite.SQLiteException: no such table: passwords: , while compiling: INSERT INTO passwords(password) VALUES(?);
文件本身存在并有一个表。它位于assets文件夹中。 我做完之后: 源码>创建表密码(密码varchar(4)); 并插入了一条记录,我能够在终端上看到它。
在我的应用中,我进行了启动画面活动调用:
jsonToDb.transfer(new WeakReference<Context>(getApplicationContext()));
jsonToDb:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.simple.parser.JSONParser;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
public class jsonToDb
{
static void transfer( WeakReference<Context> context )
{
DatabaseLoader.init( context );
String COLUMN_PASSWORD = "password";
ContentValues cv = new ContentValues();
JSONParser parser = new JSONParser();
AssetManager assetManager = context.get().getAssets();
InputStream inputStream = null;
String password = "null";
int successCount ;
try {
inputStream = assetManager.open("convertcsv.json");
BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder strBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
strBuilder.append(inputStr);
JSONArray jsonArray = new JSONArray( strBuilder.toString() );
//The loop should be up until i=10000 but I've made it 2 just for the sake of the example.
for (int i=0 ; i<2 ; i++)
{
password = (String) jsonArray.getJSONObject(0).get( "Code" );
cv.put( COLUMN_PASSWORD, password );
DatabaseLoader.getInstance().transferJson( cv );
}
}
catch (IOException e)
{
//
}
catch(JSONException e)
{
//
}
}
}
DatabaseLoader:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Map;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
class DatabaseLoader
{
private static DatabaseLoader instance;
private DatabaseLoaderHelper dbHelper;
private static final String ERROR_OPEN_FILE_TAG = "Error Opening File";
static void init( WeakReference<Context> contextWrapper )
{
if( instance == null )
{
instance = new DatabaseLoader( contextWrapper );
}
}
protected DatabaseLoader( WeakReference<Context> contextWrapper )
{
dbHelper = new DatabaseLoaderHelper( contextWrapper.get() );
}
static DatabaseLoader getInstance()
{
return instance;
}
SQLiteDatabase getDb()
{
return dbHelper.getWritableDatabase();
}
private static class DatabaseLoaderHelper extends SQLiteOpenHelper
{
private static final String DB_NAME = "passwordsdb.sql";
private static final String DB_PATH = "/data/data/mypackage/databases/";
private static final int DB_VERSION = 1;
private DatabaseLoaderHelper( Context context )
{
super( context, DB_NAME, null, DB_VERSION );
try
{
createDatabase( context );
}
catch ( IOException e )
{
Log.d( "CAN'T create DB", "cannot create db" );
e.printStackTrace();
}
}
private void copyDatabase( Context context ) throws IOException{
//Open your local db as the input stream
InputStream myInput = context.getAssets().open( DB_NAME );
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream( outFileName );
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
private boolean checkDatabase()
{
File dbFile = new File( DB_PATH + DB_NAME );
return dbFile.exists();
}
public void createDatabase( Context context ) throws IOException
{
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDatabase();
if(!mDataBaseExist)
{
try
{
//Copy the database from assests
copyDatabase( context );
Log.e("created DBase", "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}
@Override
public void onCreate( SQLiteDatabase db )
{
// TODO Auto-generated method stub
}
@Override
public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion )
{
// TODO Auto-generated method stub
}
}
public Map<String,Password> loadDatabase()
{
final String TABLE_NAME = "passwords";
Map<String,Password> passwords = null;
try
{
SQLiteDatabase db = getDb();
Cursor result = db.rawQuery( "select * from " + TABLE_NAME, null );
result.moveToFirst();
while( !result.isAfterLast() )
{
String password = result.getString( 1 );
int date = result.getInt( 2 );
int tried = result.getInt( 3 );
int successCount = result.getInt( 4 );
int dbIndex = result.getInt( 5 );
passwords.put( password , new Password( password, date, tried, successCount, dbIndex ) );
result.moveToNext();
}
result.close();
}
catch( SQLiteException errorOpeningDB )
{
Log.e( ERROR_OPEN_FILE_TAG, "problem" ,errorOpeningDB );
}
return passwords;
}
public void transferJson( ContentValues cv )
{
String TABLE_PASSWORDS = "passwords";
try
{
SQLiteDatabase db = getDb();
db.insert( TABLE_PASSWORDS, null, cv );
db.close();
}
catch( SQLiteException errorOpeningDB )
{
Log.e( ERROR_OPEN_FILE_TAG, "problem" ,errorOpeningDB );
}
}
}
我已经坐了几天,但现在无济于事。
答案 0 :(得分:1)
如果我没有错,你没有从资产文件夹中复制sqlite数据库。请尝试以下方法。您需要从资产文件夹中复制数据库,如下所示。
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
然后你需要这样做才能检查数据库是否存在
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
最后修改你的创建方法
public void createDataBase() throws IOException
{
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}
答案 1 :(得分:0)
在查询之前,必须创建一个表,我无法在SQLiteOpenHelper扩展类中看到表创建查询。
您可以在onCreate()方法中执行创建查询的表:
String CREATE_PASSWORD_TABLE = "CREATE TABLE passwords ( " + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "password TEXT)";
db.execSQL(CREATE_BOOK_TABLE);