简体   繁体   中英

Android Studio: app not saving to/reading from database

So my app is a QR Code scanner. Currently it will read a QR code and display it back to user. I want to get it to also save this result to a database and then proceed to read back from it. Currently it does neither of the last two and I'm struggling to figure out which is causing the issue - either saving to the database or reading back from the database.

My Database code is this:

public class Database {
    private static final String DATABASE_NAME = "QRCodeScanner";
    private static final int DATABASE_VERSION = 1;
    private static final String TABLE_NAME = "codes";

    private OpenHelper mDbHelper;
    private SQLiteDatabase mDb;
    private final Context dbContext;

    private static final String DATABASE_CREATE =
            "CREATE TABLE " + TABLE_NAME + " (" +
                    "codeid INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    "code TEXT NOT NULL);";

    public Database(Context ctx) {
        this.dbContext = ctx;
    }

    public Database open() throws SQLException {
        mDbHelper = new OpenHelper(dbContext);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

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

    public boolean createUser(String code) {
        ContentValues initialValues = new ContentValues();
        initialValues.put("codes", code);

        return mDb.insert(TABLE_NAME, null, initialValues) > 0;
    }


    public ArrayList<String[]> fetchUser(String code) throws SQLException {

        ArrayList<String[]> myArray = new ArrayList<String[]>();

        int pointer = 0;

        Cursor mCursor = mDb.query(TABLE_NAME, new String[] {"codeid", "code",
                        }, "code LIKE '%" + code + "%'", null,
                null, null, null);

        int codeNameColumn = mCursor.getColumnIndex("code");


        if (mCursor != null){
            if (mCursor.moveToFirst()){
                do {
                    myArray.add(new String[3]);
                    myArray.get(pointer)[0] = mCursor.getString(codeNameColumn);
                    pointer++;
                } while (mCursor.moveToNext());
            } else {
                myArray.add(new String[3]);
                myArray.get(pointer)[0] = "NO RESULTS";
                myArray.get(pointer)[1] = "";
            }
        }

        return myArray;

    }

    public ArrayList<String[]> selectAll() {

        ArrayList<String[]> results = new ArrayList<String[]>();


        int counter = 0;

        Cursor cursor = this.mDb.query(TABLE_NAME, new String[] { "codeid", "codes" }, null, null, null, null, "codeid");

        if (cursor.moveToFirst()) {
            do {
                results.add(new String[3]);
                results.get(counter)[0] = cursor.getString(0);
                counter++;
            } while (cursor.moveToNext());
        }
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }

        return results;
    }


    private static class OpenHelper extends SQLiteOpenHelper {

        OpenHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    }
}

And my main java code is this.

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button Scan;
private ArrayList<String[]> viewall;
private TextView QR_output;
private IntentIntegrator ScanCode;
private ListView lv;
private ArrayList Search = new ArrayList();
ArrayList<String[]> searchResult;

Database dbh;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // this caused an error on earlier APKs which made the app switch from 17 to 27
    setContentView(R.layout.activity_main);

    // Defines the Scan button
    Scan = findViewById(R.id.Scan);
    // defines the output for text
    QR_output = findViewById(R.id.QR_Output);

    // looks for the user clicking "Scan"
    Scan.setOnClickListener(this);

    ScanCode = new IntentIntegrator(this);
    // Means the scan button will actually do something
    Scan.setOnClickListener(this);

    lv = findViewById(R.id.list);

    dbh = new Database(this);
    dbh.open();

}

public void displayAll(View v){

    Search.clear();
    viewall = dbh.selectAll();
    String surname = "", forename = "";

    for (int count = 0 ; count < viewall.size() ; count++) {
        code = viewall.get(count)[1];
        Search.add(surname + ", " + forename);
    }
    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            Search);

    lv.setAdapter(arrayAdapter);
}




// will scan the qr code and reveal its secrets
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if (result != null) {
        // if an empty QR code gets scanned it returns a message to the user
        if (result.getContents() == null) {
            Toast.makeText(this, "This QR code is empty.", Toast.LENGTH_LONG).show();
        } else try {
            // converts the data so it can be displayed
            JSONObject obj = new JSONObject(result.getContents());
            // this line is busted and does nothing
            QR_output.setText(obj.getString("result"));
        } catch (JSONException e) {
            e.printStackTrace();
                String codes = result.getContents();
                boolean success = false;

                success = dbh.createUser(codes);
            // outputs the data to a toast
            Toast.makeText(this, result.getContents(), Toast.LENGTH_LONG).show();
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

@Override
public void onClick(View view) {
    // causes the magic to happen (It initiates the scan)
    ScanCode.initiateScan();
}

}

Your issue could well be with the line initialValues.put("codes", code); as according to your table definition there is no column called codes , rather the column name appears to be code

As such using initialValues.put("code", code); may well resolve the issue.

Addititional

It is strongly recommended that you define and subsequently use constants throughout your code for all named items (tables, columns, views trigger etc) and thus the value will always be identical.

eg

private static final String DATABASE_NAME = "QRCodeScanner";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "codes";
public static final String COLUMN_CODEID = "codeid"; //<<<<<<<<< example note making public allows the variable to be used elsewhere
public static final String COLUMN_CODE = "code";   //<<<<<<<<<< another example

private OpenHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context dbContext;

private static final String DATABASE_CREATE =
        "CREATE TABLE " + TABLE_NAME + " (" +
                COLUMN_CODEID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + //<<<<<<<<<<
                COLUMN_CODE + " TEXT NOT NULL);"; //<<<<<<<<<<

........ other code omitted for brevity

public boolean createUser(String code) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(COLUMN_CODE, code); //<<<<<<<<<< CONSTANT USED

    return mDb.insert(TABLE_NAME, null, initialValues) > 0;
}

You would also likely encounter fewer issues by not using hard coded column offsets when extracting data from Cursor by rather using the Cursor getColumnIndex method to provide the offset.

eg instead of :-

results.get(counter)[0] = cursor.getString(0);

it would be better to use :-

results.get(counter)[0] = cursor.getString(cursor.getColumnIndex(COLUMN_CODEID));

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