简体   繁体   中英

No such table error when running on device but on emulator same code works fine

I have a very weird problem I am writing a code that gets data from database to show it in listView, so I've made a class for getting the database and other one for the adapter. But when I run it on device I got no such table error, although it's working fine on emulator. Also, I tried this code with another database in the same project and it's working. I added the android_metadata table to them, but still not working.

This is my db class

public class Directory_DB extends SQLiteOpenHelper{

private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = ""; 
private static String DB_NAME ;// Database name
private SQLiteDatabase mDataBase; 
private final Context mContext;
private String TABLE_NAME;

public Directory_DB(Context context , String DB_NAME ) 
{
    super(context , DB_NAME, null , 2);// 1? its Database Version
    DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    this.mContext = context;
    this.DB_NAME = DB_NAME;

}   

public void createDataBase() throws IOException
{
    //If database not exists copy it from the assets

    boolean mDataBaseExist = checkDataBase();
    if(!mDataBaseExist)
    {
        this.getReadableDatabase();
        this.close();
        try 
        {
            //Copy the database from assests
            copyDataBase();
            Log.e(TAG, "createDatabase database created");
        } 
        catch (IOException mIOException) 
        {
            throw new Error("ErrorCopyingDataBase");
        }
    }
}
    //Check that the database exists here: /data/data/your package/databases/Da Name
    private boolean checkDataBase()
    {
        File dbFile = new File(DB_PATH + DB_NAME);
        Log.v("dbFile", dbFile + "   "+ dbFile.exists());
        return dbFile.exists();
    }

    //Copy the database from assets
    private void copyDataBase() throws IOException
    {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream mOutput = new FileOutputStream(outFileName);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer))>0)
        {
            mOutput.write(mBuffer, 0, mLength);
        }
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    //Open the database, so we can query it
    public boolean openDataBase() throws SQLException
    {
        String mPath = DB_PATH + DB_NAME;
        //Log.v("mPath", mPath);
        mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
        //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() 
    {
        if(mDataBase != null)
            mDataBase.close();
        super.close();
    }




@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

}

}

and this is my adapter class

public class DirectoryAdapter {
public static final String TAG_ID = "_id";
public static String TAG_TABLE_NAME;

protected static final String TAG = "DataAdapter";

private final Context mContext;
private SQLiteDatabase mDb;
private Directory_DB mDbHelper;

public DirectoryAdapter(Context context, String DB_NAME, String TABLE_NAME) {
    this.mContext = context;
    mDbHelper = new Directory_DB(mContext, DB_NAME );
    this.TAG_TABLE_NAME = TABLE_NAME;
    Log.d("Database name in adapter", DB_NAME);
    Log.d("Table name in adapter", TAG_TABLE_NAME);
}

public DirectoryAdapter createDatabase() throws SQLException {
    try {
        mDbHelper.createDataBase();
    } catch (IOException mIOException) {
        Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
        throw new Error("UnableToCreateDatabase");
    }
    return this;
}

public DirectoryAdapter open() throws SQLException {
    try {
        mDbHelper.openDataBase();
        mDbHelper.close();
        mDb = mDbHelper.getReadableDatabase();
    } catch (SQLException mSQLException) {
        Log.e(TAG, "open >>" + mSQLException.toString());
        throw mSQLException;
    }
    return this;
}

public void close() {
    mDbHelper.close();
}

public Cursor getTestData() {
    try {

        String sql = "SELECT * FROM " + TAG_TABLE_NAME;
        Cursor mCur = mDb.rawQuery(sql, null);

        return mCur;
    } catch (SQLException mSQLException) {
        Log.e(TAG, "getTestData >>" + mSQLException.toString());
        throw mSQLException;
    }
}

}

您可以从设备中卸载应用程序并再次运行它。如果您稍后在数据库中添加了表,则不会反映它,因为您的数据库已经创建,并且仅在创建数据库时才创建表。

You have to call your createDataBase method inside the on create method

 @Override
 public void onCreate(SQLiteDatabase db) {
     // TODO Auto-generated method stub
 }

that's what's this method is for. Also if you're calling it form any where else (I didn't read your whole code) don't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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