android.database.sqlite.SQLiteException(代码1)

时间:2021-01-04 23:02:21

I try to write an app with a sqlite database. The Problem is, that my app in the emulator always “Unfortunately stopped”.

我尝试用sqlite数据库编写应用程序。问题是,我在模拟器中的应用总是“不幸停止”。

The stack trace says that this was happening because of a RuntimeException. This RuntimeException is caused by a SQLiteException.

堆栈跟踪说由于RuntimeException而发生这种情况。此RuntimeException是由SQLiteException引起的。

The full stack trace is:

完整的堆栈跟踪是:

--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.passwordsavver.wahlfachprojekt, PID: 3336
   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.passwordsavver.wahlfachprojekt/com.passwordsavver.wahlfachprojekt.MainScreen}: android.database.sqlite.SQLiteException: no such column: favourites (code 1): , while compiling: SELECT DISTINCT _id, websitename, username, password, notes, favourites FROM mainTable
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
       at android.app.ActivityThread.access$800(ActivityThread.java:151)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5254)
       at java.lang.reflect.Method.invoke(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
    Caused by: android.database.sqlite.SQLiteException: no such column: favourites (code 1): , while compiling: SELECT DISTINCT _id, websitename, username, password, notes, favourites FROM mainTable
       at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 
       at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
       at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
       at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
       at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
       at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
       at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
       at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
       at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
       at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
       at com.passwordsavver.wahlfachprojekt.DBAdapter.getAllRows(DBAdapter.java:142)
       at com.passwordsavver.wahlfachprojekt.MainScreen.populateButtons(MainScreen.java:52)
       at com.passwordsavver.wahlfachprojekt.MainScreen.onCreate(MainScreen.java:33)
       at android.app.Activity.performCreate(Activity.java:5990)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
       at android.app.ActivityThread.access$800(ActivityThread.java:151) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:135) 
       at android.app.ActivityThread.main(ActivityThread.java:5254) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at java.lang.reflect.Method.invoke(Method.java:372) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
Application terminated.

My Problem is, after looking multiples times over my code, I don’t know where exactly the Exception in my class occurs.

我的问题是,在查看我的代码的倍数之后,我不知道我的类中出现了什么异常。

My DBHealper Class looks like this:

我的DBHealper类看起来像这样:

package com.passwordsavver.wahlfachprojekt;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public class DBAdapter {

    private static final String TAG = "DBAdapter";

    // DB Fields
    public static final String KEY_ROWID = "_id";
    public static final int COL_ROWID = 0;

    public static final String KEY_WEBSITENAME = "websitename";
    public static final String KEY_USERNAME = "username";
    public static final String KEY_PASSWORD = "password";
    public static final String KEY_NOTES = "notes";
    public static final String KEY_FAV = "favourites";

    public static final int COL_WEBSITENAME = 1;
    public static final int COL_USERNAME = 2;
    public static final int COL_PASSWORD = 3;
    public static final int COL_NOTES = 4;
    public static final int COL_FAV = 5;

    public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_WEBSITENAME, KEY_USERNAME, KEY_PASSWORD, KEY_NOTES, KEY_FAV};

    public static final String DATABASE_NAME = "MyDb";
    public static final String DATABASE_TABLE = "mainTable";

    public static final int DATABASE_VERSION = 5;

    private static final String DATABASE_CREATE_SQL = 
        "create table " + DATABASE_TABLE 
        + " (" + KEY_ROWID + " integer primary key autoincrement, "
        + KEY_WEBSITENAME + " string not null, "
        + KEY_USERNAME + " string not null, "
        + KEY_PASSWORD + " string not null, "
        + KEY_NOTES + " string, "
        + KEY_FAV + "string"
        + ");";

    // Context of application who uses us.
    private final Context context;

    private DatabaseHelper myDBHelper;
    private SQLiteDatabase db;

    public DBAdapter(Context ctx) {
        this.context = ctx;
        myDBHelper = new DatabaseHelper(context);
    }

    // Open the database connection.
    public DBAdapter open() {
        db = myDBHelper.getWritableDatabase();
        return this;
    }

    // Close the database connection.
    public void close() {
        myDBHelper.close();
    }

    // Add a new set of values to the database.
    public long insertRow(String websitename, String username, String password, String notes, String fav) {

        // Create row's data:
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_WEBSITENAME, websitename);
        initialValues.put(KEY_USERNAME, username);
        initialValues.put(KEY_PASSWORD, password);
        initialValues.put(KEY_NOTES, notes);
        initialValues.put(KEY_FAV, fav);

        // Insert it into the database.
        return db.insert(DATABASE_TABLE, null, initialValues);
    }

    // Delete a row from the database, by rowId (primary key)
    public boolean deleteRow(long rowId) {
        String where = KEY_ROWID + "=" + rowId;
        return db.delete(DATABASE_TABLE, where, null) != 0;
    }

    public void deleteAll() {
        Cursor c = getAllRows();
        long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
        if (c.moveToFirst()) {
            do {
                deleteRow(c.getLong((int) rowId));              
            } while (c.moveToNext());
        }
        c.close();
    }

    // Return all data in the database.
    public Cursor getAllRows() {
        String where = null;
        Cursor c =  db.query(true, DATABASE_TABLE, ALL_KEYS, 
                            where, null, null, null, null, null);
        if (c != null) {
            c.moveToFirst();
        }
        return c;
    }

    // Get a specific row (by rowId)
    public Cursor getRow(long rowId) {
        String where = KEY_ROWID + "=" + rowId;
        Cursor c =  db.query(true, DATABASE_TABLE, ALL_KEYS, 
                            where, null, null, null, null, null);
        if (c != null) {
            c.moveToFirst();
        }
        return c;
    }

    // Change an existing row to be equal to new data.
    public boolean updateRow(long rowId, String websitename, String username, String password, String notes, String fav) {
        String where = KEY_ROWID + "=" + rowId;

        // Create row's data:
        ContentValues newValues = new ContentValues();
        newValues.put(KEY_WEBSITENAME, websitename);
        newValues.put(KEY_USERNAME, username);
        newValues.put(KEY_PASSWORD, password);
        newValues.put(KEY_NOTES, notes);
        newValues.put(KEY_FAV, fav);

        // Insert it into the database.
        return db.update(DATABASE_TABLE, newValues, where, null) != 0;
    }

    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase _db) {
            _db.execSQL(DATABASE_CREATE_SQL);           
        }

        @Override
        public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading application's database from version " + oldVersion
                    + " to " + newVersion + ", which will destroy all old data!");

            // Destroy old database:
            _db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);

            // Recreate new database:
            onCreate(_db);
        }
    }
}

The Class in where the exception occurs looks like this:

发生异常的类如下所示:

package com.passwordsavver.wahlfachprojekt;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.database.Cursor;
import android.widget.TextView;
import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class MainScreen extends AppCompatActivity {
    DBAdapter myDb;
    String passwordAES;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_screen);

        Intent intent = getIntent();
        passwordAES = intent.getStringExtra("Password");

        openDB();
        populateButtons();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        closeDB();
    }

    private void openDB() {
        myDb = new DBAdapter(this);
        myDb.open();
    }

    private void closeDB() {
        myDb.close();
    }

    private void populateButtons() {
        Cursor cursor = myDb.getAllRows();
        int itemNumber = 0;
        int i = 0;

        if (cursor.moveToFirst()) {
            do {
                itemNumber++;
            } while (cursor.moveToNext());
        }

        int ids[] = new int[itemNumber];
        String aesWebsitenames[] = new String[itemNumber];
        String websitenames[] = new String[itemNumber];
        String aesFav[] = new String[itemNumber];
        String fav[] = new String[itemNumber];


        if (cursor.moveToFirst()) {
            do {
                ids[i] = cursor.getInt(DBAdapter.COL_ROWID);
                aesWebsitenames[i] =  cursor.getString(DBAdapter.COL_WEBSITENAME);
                aesFav[i] = cursor.getString(DBAdapter.COL_FAV);

                try
                {
                    websitenames[i] = decrypt(passwordAES, aesWebsitenames[i]);
                    fav[i] = decrypt(passwordAES, aesFav[i]);
                }
                catch(Exception e)
                {

                }

                i++;
            } while (cursor.moveToNext());
        }

        i = 0;

        int numCols = 1;

        int numRows = itemNumber;


        TableLayout table = (TableLayout)findViewById(R.id.tableForButtons);

        // Favourites
        int countFavourites = 0;
        for(int row = 0; row < numRows; row++)
        {
            TableRow tableRow = new TableRow(this);
            table.addView(tableRow);

            if(fav[i] == "1") {
                Button button = new Button(this);

                button.setText(websitenames[i]);


                // Make text not clip on small buttons
                button.setPadding(0, 0, 0, 0);
                tableRow.addView(button);

                final int FINAL_ID = ids[i];


                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(v.getContext(), ViewScreen.class);
                        intent.putExtra("id", FINAL_ID);
                        intent.putExtra("Password", passwordAES);
                        startActivity(intent);
                    }
                });
            }
            countFavourites++;
            i++;
        }

        if(countFavourites == 0)
        {
            TextView txtNoFavourites = (TextView) findViewById(R.id.txtMainScreenNoFavourites);
            txtNoFavourites.setVisibility(View.VISIBLE);
        }

        i = 0;

        // Not Favourites
        for(int row = 0; row < numRows; row++)
        {
            TableRow tableRow = new TableRow(this);
            table.addView(tableRow);
            for(int col = 0; col < numCols; col++)
            {
                if(fav[i] == "0") {
                    Button button = new Button(this);

                    button.setText(websitenames[i]);

                    // Make text not clip on small buttons
                    button.setPadding(0, 0, 0, 0);
                    tableRow.addView(button);

                    final int FINAL_ID = ids[i];

                    button.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent intent = new Intent(v.getContext(), ViewScreen.class);
                            intent.putExtra("id", FINAL_ID);
                            intent.putExtra("Password", passwordAES);
                            startActivity(intent);
                        }
                    });
                }
            }
            i++;
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        Intent intent;

        switch (id)
        {
            case R.id.action_offlinemode:
                intent = new Intent(this, OptionScreen.class);
                intent.putExtra("Password", passwordAES);
                startActivity(intent);
                break;

            case R.id.action_allPasswords:
                intent = new Intent(this, MainScreen.class);
                intent.putExtra("Password", passwordAES);
                startActivity(intent);
                break;

            case R.id.action_favorites:

                break;

            case R.id.action_addPassword:
                intent = new Intent(this, AddScreen2.class);
                intent.putExtra("Password", passwordAES);
                startActivity(intent);
                break;

            case R.id.action_deleteAllPasswords:
                myDb.deleteAll();
                break;

            case R.id.action_option:
                intent = new Intent(this, OptionScreen.class);
                intent.putExtra("Password", passwordAES);
                startActivity(intent);
                break;

            case R.id.action_logout:

                break;

            default:
                return super.onOptionsItemSelected(item);
        }

        return true;
    }

    private String decrypt (String password, String data) throws Exception
    {
        SecretKeySpec key = generateKey(password);
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decodedValue = Base64.decode(data, Base64.DEFAULT);
        byte[] decValue = c.doFinal(decodedValue);
        String decryptedValue = new String(decValue);
        return  decryptedValue;
    }

    private SecretKeySpec generateKey(String password) throws Exception
    {
        final MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] bytes = password.getBytes("UTF-8");
        digest.update(bytes, 0, bytes.length);
        byte[] key = digest.digest();
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        return secretKeySpec;
    }
}

Please can anybody show over my code and tell me where my error is?

请任何人都可以显示我的代码并告诉我我的错误在哪里?

4 个解决方案

#1


1  

Change a line of your DATABASE_CREATE_SQL string,

更改DATABASE_CREATE_SQL字符串的一行,

put a space + KEY_FAV + "string" before string make it,

在字符串之前放一个空格+ KEY_FAV +“string”,

+ KEY_FAV + " string"

change public static final int DATABASE_VERSION = 5; value and try again.

更改public static final int DATABASE_VERSION = 5;价值再试一次。

#2


1  

private static final String DATABASE_CREATE_SQL = 
    "create table " + DATABASE_TABLE 
    + " (" + KEY_ROWID + " integer primary key autoincrement, "
    + KEY_WEBSITENAME + " string not null, "
    + KEY_USERNAME + " string not null, "
    + KEY_PASSWORD + " string not null, "
    + KEY_NOTES + " string, "
    + KEY_FAV + "string"
    + ");";

rewrite as

private static final String DATABASE_CREATE_SQL = 
        "create table " + DATABASE_TABLE 
        + " (" + KEY_ROWID + " integer primary key autoincrement, "
        + KEY_WEBSITENAME + " string not null, "
        + KEY_USERNAME + " string not null, "
        + KEY_PASSWORD + " string not null, "
        + KEY_NOTES + " string, "
        + KEY_FAV + " string "
        + ");";

as it seems only the space issue with KEY_FAV and String.

因为它似乎只是KEY_FAV和String的空间问题。

The only change required

唯一需要的改变

+ KEY_FAV + "string" 

as

 + KEY_FAV + " string " 

#3


1  

+ KEY_FAV + "string"

This line treating string all together. Add a space before.

这条线一起处理字符串。之前添加一个空格。

It would be " string"

这将是“字符串”

#4


0  

The exception is clearly saying that

例外显然是这样说的

Caused by: android.database.sqlite.SQLiteException: no such column: favourites (code 1): , while compiling: SELECT DISTINCT _id, websitename, username, password, notes, favourites FROM mainTable

引起:android.database.sqlite.SQLiteException:没有这样的列:收藏夹(代码1):,同时编译:SELECT DISTINCT _id,websitename,用户名,密码,备注,收藏夹FROM mainTable

So there is missing a space in front of + KEY_FAV + " string". That is why it is throwing an exception.

所以在+ KEY_FAV +“string”前面缺少一个空格。这就是它抛出异常的原因。

#1


1  

Change a line of your DATABASE_CREATE_SQL string,

更改DATABASE_CREATE_SQL字符串的一行,

put a space + KEY_FAV + "string" before string make it,

在字符串之前放一个空格+ KEY_FAV +“string”,

+ KEY_FAV + " string"

change public static final int DATABASE_VERSION = 5; value and try again.

更改public static final int DATABASE_VERSION = 5;价值再试一次。

#2


1  

private static final String DATABASE_CREATE_SQL = 
    "create table " + DATABASE_TABLE 
    + " (" + KEY_ROWID + " integer primary key autoincrement, "
    + KEY_WEBSITENAME + " string not null, "
    + KEY_USERNAME + " string not null, "
    + KEY_PASSWORD + " string not null, "
    + KEY_NOTES + " string, "
    + KEY_FAV + "string"
    + ");";

rewrite as

private static final String DATABASE_CREATE_SQL = 
        "create table " + DATABASE_TABLE 
        + " (" + KEY_ROWID + " integer primary key autoincrement, "
        + KEY_WEBSITENAME + " string not null, "
        + KEY_USERNAME + " string not null, "
        + KEY_PASSWORD + " string not null, "
        + KEY_NOTES + " string, "
        + KEY_FAV + " string "
        + ");";

as it seems only the space issue with KEY_FAV and String.

因为它似乎只是KEY_FAV和String的空间问题。

The only change required

唯一需要的改变

+ KEY_FAV + "string" 

as

 + KEY_FAV + " string " 

#3


1  

+ KEY_FAV + "string"

This line treating string all together. Add a space before.

这条线一起处理字符串。之前添加一个空格。

It would be " string"

这将是“字符串”

#4


0  

The exception is clearly saying that

例外显然是这样说的

Caused by: android.database.sqlite.SQLiteException: no such column: favourites (code 1): , while compiling: SELECT DISTINCT _id, websitename, username, password, notes, favourites FROM mainTable

引起:android.database.sqlite.SQLiteException:没有这样的列:收藏夹(代码1):,同时编译:SELECT DISTINCT _id,websitename,用户名,密码,备注,收藏夹FROM mainTable

So there is missing a space in front of + KEY_FAV + " string". That is why it is throwing an exception.

所以在+ KEY_FAV +“string”前面缺少一个空格。这就是它抛出异常的原因。