mercredi 27 avril 2016

Connecting to a Database in Android Studio

I am attempting to build a Grocery List in Android Studio that allows you to type in your item and select a category from a Spinner and add a SQL Data row in a listview. Then you can mark if it's complete and can remove it from the list view. I'm having trouble getting the GUI to connect and run with the DB. I have three Java class that I'm using. The Main one which ties the project together, A DB one which details everything database related, and a Cursor one for marking an object complete in the list view.

This is the Main Jave Class:

import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
// setup variables
EditText etItem;
ListView myList;
ImageButton btnAdd, btnSave;
Button btnClearAll, btnClearComplete;
LinearLayout addLayout;
myDBAdapter myDb;
Spinner spinner;


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

    // get references to controls and setup listeners
    etItem = (EditText) findViewById(R.id.etItem);
    spinner = (Spinner) findViewById(R.id.spinner);
    btnAdd = (ImageButton) findViewById(R.id.btnAdd);
    btnAdd.setOnClickListener(this);
    btnSave = (ImageButton) findViewById(R.id.btnSave);
    btnSave.setOnClickListener(this);
    btnClearAll = (Button) findViewById(R.id.btnClearAll);
    btnClearAll.setOnClickListener(this);
    btnClearComplete = (Button) findViewById(R.id.btnClearComplete);
    btnClearComplete.setOnClickListener(this);
    addLayout = (LinearLayout) findViewById(R.id.add_layout);


    myList = (ListView) findViewById(R.id.listView);
    myList.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id)
        {
            Cursor cursor = (Cursor) parent.getItemAtPosition(position);
            long _id =
                    cursor.getLong(cursor.getColumnIndex(myDBAdapter.KEY_ROWID));
            int complete =
                    cursor.getInt(cursor.getColumnIndex(myDBAdapter.KEY_COMPLETE));
            // toggle the setting for complete
            myDb.setComplete(_id, (complete == myDBAdapter.COMPLETE_NO));
            populateListViewFromDB();
            cursor.close();
        }


    });

    // open the database
    openDB();
    // load the listview
    int count = populateListViewFromDB();
    // if the list is empty or the orientation is landscape show the add layout
    Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    int orientation = display.getRotation();
    if (orientation == Surface.ROTATION_90 || orientation == Surface.ROTATION_270)
        addLayout.setVisibility(View.VISIBLE);
    else
        addLayout.setVisibility((count == 0) ? View.VISIBLE : View.GONE);

    //Create a Spinner Object
     spinner = (Spinner) findViewById(R.id.spinner);

    // Creating adapter for spinner
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.Categories,
            android.R.layout.simple_spinner_dropdown_item);
    // Drop down layout style - list view with radio button
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    // attaching data adapter to spinner
    spinner.setAdapter(adapter);
}

 // end of onCreate


@Override
public void onClick(View v)
{
    switch (v.getId())
    {
        case R.id.btnSave:
            if (!TextUtils.isEmpty(etItem.getText())) {
                myDb.insertRow(etItem.getText().toString(), spinner.getSelectedItem().toString(), false);
                populateListViewFromDB();
                // clear the text
                etItem.setText(null);
            }

            break;
        case R.id.btnAdd:
            // show or hide the add layout
            addLayout.setVisibility((addLayout.getVisibility() == View.GONE) ? View.VISIBLE : View.GONE);
            break;
        case R.id.btnClearAll:
            clearAll();
            break;
        case R.id.btnClearComplete:
            clearComplete();
            break;
    }
}


private void clearAll()
{
    myDb.deleteAll();
    populateListViewFromDB();
}

private void clearComplete()
{
    myDb.deleteCompleted();
    populateListViewFromDB();
}

@Override
protected void onDestroy()
{
    super.onDestroy();
    closeDB();
}
private void openDB()
{
    myDb = new myDBAdapter(this);
    myDb.open();
}
private void closeDB()
{
    myDb.close();
}
// retrieves the data from the database and populates the listview
// uses myDBAdapter class and CursorAdapter
// returns the number of records in the dataset
private int populateListViewFromDB() {
    Cursor cursor = myDb.getAllRows();
// Setup mapping from cursor to view fields:
    String[] fromFieldNames = new String[]{myDBAdapter.KEY_ITEM,};
    int[] toViewIDs = new int[]{R.id.tvItemTask,};
// Create the cursor adapter
// connects the data to the layout for the row
    CursorAdapter myCursorAdapter = new CursorAdapter(getBaseContext(),
            R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 1);
    myList.setAdapter(myCursorAdapter);
// return the number of items in the list
    return cursor.getCount();
}

}

This is my DB Java Class:

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 myDBAdapter
{
// used for logging database version changes
private static final String TAG = "myDBAdapter";
// database info:
public static final String DATABASE_NAME = "dbToDo";
public static final String DATABASE_TABLE = "TasksToDo";
// the version number gets changed each time the db structure changes
public static final int DATABASE_VERSION = 1;
// Field Names:
public static final String KEY_ROWID = "_id";
public static final String KEY_ITEM = "item";
public static final String KEY_DESCRIPTION = "description";
public static final String KEY_COMPLETE = "complete";
public static final int COMPLETE_YES = 1;
public static final int COMPLETE_NO = 0;
public static final String[] ALL_KEYS = new String[]
        {KEY_ROWID, KEY_ITEM, KEY_COMPLETE};
// column numbers for each Field Name:
public static final int COL_ROWID = 0;
public static final int COL_TASK = 1;
public static final int COL_DESCRIPTION = 2;
public static final int COL_COMPLETE = 3;
// SQL statement to create database
private static final String DATABASE_CREATE_SQL =
        "CREATE TABLE " + DATABASE_TABLE
                + " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + KEY_ITEM + " TEXT NOT NULL, "
                + KEY_DESCRIPTION + " TEXT, "
                + KEY_COMPLETE + " INTEGER"
                + ");";
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
// constructor - stores the context, instantiates the DatabaseHelper class
public myDBAdapter(Context context)
{
    this.context = context;
    myDBHelper = new DatabaseHelper(context);
}
// inner class to create or upgrade the database
private static class DatabaseHelper extends SQLiteOpenHelper
{
    public 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 destroys all old data!");
        // Destroy old database:
        db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
        // Recreate new database:
        onCreate(db);
    }
}
// Open the database connection
public myDBAdapter open()
{
    db = myDBHelper.getWritableDatabase();
    return this;
}
// close the connection
public void close()
{
    myDBHelper.close();
}
// add a new set of values to be inserted into the database
public long insertRow(String item, String description,  boolean complete)
{
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_ITEM, item);
    initialValues.put(KEY_DESCRIPTION, description);
    initialValues.put(KEY_COMPLETE, complete);
    // insert the data 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();
}
public void deleteCompleted()
{
    String where = KEY_COMPLETE + "=1";
    Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null,
            null, null, null, null);
    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 item, String description
        , boolean complete)
{
    String where = KEY_ROWID + "=" + rowId;
    ContentValues newValues = new ContentValues();
    newValues.put(KEY_ITEM, item);
        newValues.put(KEY_DESCRIPTION, description);
    newValues.put(KEY_COMPLETE, complete);
    // insert it into the database
    return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
// change the status of a task to complete or not complete
public boolean setComplete(long rowId, boolean complete)
{
    String where = KEY_ROWID + "=" + rowId;
    ContentValues newValues = new ContentValues();
    newValues.put(KEY_COMPLETE, complete);
// insert it into the database
    return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
}

And Lastly, here is my Cursor Class, this isn't Important to the problem but in case it is, here it is:

 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Color;
 import android.graphics.Typeface;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;


  public class CursorAdapter extends SimpleCursorAdapter
  {
      public CursorAdapter(Context context, int layout, Cursor c,
                     String[] from, int[] to, int flags)
  {
      super(context, layout, c, from, to, flags);
  }
  @Override
  public void bindView(View view, Context context, Cursor cursor)
  {
      super.bindView(view, context, cursor);
      // set image for done items
      int complete = cursor.getInt(myDBAdapter.COL_COMPLETE);
      ImageView ivComplete = (ImageView) view.findViewById(R.id.ivComplete);
      if (complete == myDBAdapter.COMPLETE_YES)
      {
          ivComplete.setImageResource(R.drawable.complete);
      } else
      {
          ivComplete.setImageResource(0);
    }
}
}

Also here is my XML, Thanks for any help in advance. :)

 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Color;
 import android.graphics.Typeface;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;


  public class CursorAdapter extends SimpleCursorAdapter
  {
      public CursorAdapter(Context context, int layout, Cursor c,
                     String[] from, int[] to, int flags)
  {
      super(context, layout, c, from, to, flags);
  }
  @Override
  public void bindView(View view, Context context, Cursor cursor)
  {
      super.bindView(view, context, cursor);
      // set image for done items
      int complete = cursor.getInt(myDBAdapter.COL_COMPLETE);
      ImageView ivComplete = (ImageView) view.findViewById(R.id.ivComplete);
      if (complete == myDBAdapter.COMPLETE_YES)
      {
          ivComplete.setImageResource(R.drawable.complete);
      } else
      {
          ivComplete.setImageResource(0);
    }
}
}

Aucun commentaire:

Enregistrer un commentaire