Search code examples
javaandroidsqliteandroid-sqlitesqliteopenhelper

Inserting or Reading values in an SQLite database doesn't yield any results


Started with SQLite in Android this evening. Practiced all the code from the Google documentation but it's still going wrong and I can't figure out where I'm going wrong. Take a look and see if you can find out any details.

DatabaseHelperContract.java

package com.practice.sqlitepractice;

import android.provider.BaseColumns;

//final class to prevent inheritance
public final class DatabaseHelperContract {

    //Create Entry String
    public static final String CREATE_ENTRY = "CREATE TABLE " + DatabaseSchema.TABLE_NAME + " (" +
            DatabaseSchema._ID + " INTEGER PRIMARY KEY, " + DatabaseSchema.COLUMN_NAME + " TEXT)";

    //private constructor to prevent accidental instantiation
    private DatabaseHelperContract(){
    }

    /*Inner class that defines individual table contents*/
    public static class DatabaseSchema implements BaseColumns{
        public static final String TABLE_NAME = "details";
        public static final String COLUMN_NAME = "name";
    }
}

DatabaseHelper.class

package com.practice.sqlitepractice;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

class DatabaseHelper extends SQLiteOpenHelper {

    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "table.db";

    public DatabaseHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(DatabaseHelperContract.CREATE_ENTRY);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

MainActivity.java

package com.practice.sqlitepractice;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText nameEditText;
    private Button insertButton;
    private Button readButton;
    private ListView detailsListView;

    private DatabaseHelper databaseHelper;

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

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

    private void insertionMethod(String name) {
        //gets the data repository in write mode
        SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();

        //create a new map of values, where the columns are the keys
        ContentValues contentValues = new ContentValues();
        contentValues.put(DatabaseHelperContract.DatabaseSchema.COLUMN_NAME, name);

        try {
            long newRowID = sqLiteDatabase.insert(DatabaseHelperContract.DatabaseSchema.TABLE_NAME, null, contentValues);
            Toast.makeText(this, "ID for newly created row: " + newRowID, Toast.LENGTH_SHORT).show();
        } catch (SQLException exception) {
            exception.printStackTrace();
        }
    }

    private void readMethod() {
        SQLiteDatabase sqLiteDatabase = databaseHelper.getReadableDatabase();
        String[] projection = {DatabaseHelperContract.DatabaseSchema.COLUMN_NAME};

        try {
            Cursor cursor = sqLiteDatabase.query(
                    DatabaseHelperContract.DatabaseSchema.TABLE_NAME,
                    projection,
                    null,
                    null,
                    null,
                    null,
                    null);

            List<String> itemIDs = new ArrayList<>();
            while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndex(DatabaseHelperContract.DatabaseSchema.COLUMN_NAME));
                itemIDs.add(name);
            }

            cursor.close();
            displayMethod(itemIDs);
        } catch (SQLiteException exception) {
            exception.printStackTrace();
        }
    }

    private void displayMethod(List<String> list) {
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, R.id.details_list_view, list);
        detailsListView.setAdapter(arrayAdapter);
    }

    @Override
    public void onClick(View view) {
        if (view == readButton) {
            readMethod();
        }

        if (view == insertButton) {
            String name = nameEditText.getText().toString();
            insertionMethod(name);
        }
    }

    private void initializeWidgetsMethod() {
        nameEditText = findViewById(R.id.name_edit_text);
        insertButton = findViewById(R.id.insert_button);
        readButton = findViewById(R.id.read_button);
        detailsListView = findViewById(R.id.details_list_view);
        databaseHelper = new DatabaseHelper(getApplicationContext());
    }
}

Note: I know that database transactions are expensive and should always be performed asynchronously. This code is just for practice and I will be performing all those at a later stage.


Solution

  • The problem with your code is the way that you initialize the ArrayAdapter in displayMethod().
    The 3d argument of this definition:

    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
       this, 
       android.R.layout.simple_list_item_1, 
       R.id.details_list_view, 
       list
    );
    

    is R.id.details_list_view which is the ListView resource id, while you should have used a TextView resource id but only if you have created one to use inside the ListView.
    Did you create such a TextView?
    If not then you can use the default TextView, by not passing this argument.
    So change the code to this:

    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
        this, 
        android.R.layout.simple_list_item_1, 
        list
    );