I have an Android project (running in emulator) in which clicking the 'Novels' button on the main menu should lead to the values of pieces where the typeField = 0 (ie false) in the 'pieceTable' in the SQL database being displayed in a ListActivity through an ArrayList.
However, when the Novels button is clicked, the application is stopped and a dialogue box shown, stating 'Unfortunately, EnglishLitRevision has stopped'. There is no LogCat output.
I wouldn't be surprised if this is a very basic error out of ignorance, but I would be grateful if anyone can identify the problem.
UPDATE - filter was not set to 'error' on LogCat!
LogCat output is shown below:
01-02 18:26:06.344: E/AndroidRuntime(548): FATAL EXCEPTION: main
01-02 18:26:06.344: E/AndroidRuntime(548): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lawson.englishlitrevision/com.lawson.englishlitrevision.Novel}: java.lang.NullPointerException
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ActivityThread.access$600(ActivityThread.java:123)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.os.Looper.loop(Looper.java:137)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-02 18:26:06.344: E/AndroidRuntime(548): at java.lang.reflect.Method.invokeNative(Native Method)
01-02 18:26:06.344: E/AndroidRuntime(548): at java.lang.reflect.Method.invoke(Method.java:511)
01-02 18:26:06.344: E/AndroidRuntime(548): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-02 18:26:06.344: E/AndroidRuntime(548): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-02 18:26:06.344: E/AndroidRuntime(548): at dalvik.system.NativeStart.main(Native Method)
01-02 18:26:06.344: E/AndroidRuntime(548): Caused by: java.lang.NullPointerException
01-02 18:26:06.344: E/AndroidRuntime(548): at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.widget.ListView.setAdapter(ListView.java:460)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ListActivity.setListAdapter(ListActivity.java:265)
01-02 18:26:06.344: E/AndroidRuntime(548): at com.lawson.englishlitrevision.Novel.onCreate(Novel.java:24)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.Activity.performCreate(Activity.java:4465)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
01-02 18:26:06.344: E/AndroidRuntime(548): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
01-02 18:26:06.344: E/AndroidRuntime(548): ... 11 more
I would be grateful if anyone can identify the cause of the error.
Code from three relevant classes is shown below.
Main Menu:
/**
* Main Menu (launcher item)
* #author Daniel Lawson
* #Version 29/12/13
*/
package com.lawson.englishlitrevision;
import android.os.Bundle;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class MainMenu extends Activity {
/** Button for accessing novels area */
private Button novelBut;
/** Button for accessing plays area */
private Button playBut;
/** Button for viewing progress/statistics */
private Button progressBut;
/** Button for viewing about screen */
private Button aboutBut;
/** Button for exiting the application */
private Button exitBut;
/**
* Method called when activity is started. Sets up required data.
*
* #param savedInstanceState
* : The saved state of the application
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Sets up layout
setContentView(R.layout.main_menu_layout);
createButton();
}
/** Sets up the buttons */
public void createButton() {
novelBut = (Button) findViewById(R.id.novelBut);
playBut = (Button) findViewById(R.id.playBut);
progressBut = (Button) findViewById(R.id.addNovBut);
aboutBut = (Button) findViewById(R.id.aboutBut);
exitBut = (Button) findViewById(R.id.exitBut);
}
/**
* Method called when novel button is clicked. Starts novel activity.
*
* #param novBut
* : The view of the novel button, which has been clicked.
*/
public void goNovel(View novBut) {
startActivity(new Intent(this, Novel.class));
}
/**
* Method called when play button is clicked. Starts play activity.
*
* #param playBut
* : The view of the play button, which has been clicked.
*/
public void goPlay(View playBut) {
startActivity(new Intent(this, Play.class));
}
/**
* Method called when progress button is clicked. Starts stats activity.
*
* #param progBut
* : The view of the progress button, which has been clicked.
*/
public void goStats(View progBut) {
startActivity(new Intent(this, Stats.class));
}
/**
* Method called when abpit button is clicked. Starts about activity.
*
* #param aboutBut
* : The view of the about button, which has been clicked.
*/
public void goAbout(View aboutBut) {
startActivity(new Intent(this, About.class));
}
/**
* Method called when exit button is clicked. Quits application.
*
* #param closeBut
* : The view of the exit button, which has been clicked.
*/
public void goClose(View closeBut) {
this.finish();
}
}
Novel:
package com.lawson.englishlitrevision;
import java.util.ArrayList;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.content.Context;
public class Novel extends ListActivity {
ArrayList<String> novels = new ArrayList<String>();
#Override
public void onCreate(Bundle icicle) {
ManipulateDatabase md = new ManipulateDatabase(this);
super.onCreate(icicle);
novels = md.getPieces("0");
setContentView(R.layout.novel_layout);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, novels));
}
public void addNovel() {
// show text input
// add the String put in to database as new novel
// update list
}
public void deleteNovel() {
// show checkboxes
// allow selection
// delete selected records from database
// update list
}
}
ManipulateDatabase:
/**
* Contains SQL statements and manages connections
*
* #author Daniel Lawson
* #version 29/12/13
*/
package com.lawson.englishlitrevision;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import java.util.ArrayList;
import java.util.Scanner;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class ManipulateDatabase {
/** String representing the name of the database */
private static final String databaseName = "EnglishDatabase.db";
/** Int representing the current version of the database */
private static final int databaseVersion = 1;
// ----------------------------------------------------------------------------------
/**
* String representing the table that stores the name of the piece and
* whether it is a play or not.
*/
private static final String pieceTable = "pieceTable";
/**
* String representing the table that stores the name of the point made,
* which piece it belongs to, and which element it pertains to.
*/
private static final String specificTable = "specificTable";
/**
* String representing the table that stores the element, the piece it
* belongs to, and whether or not it is a character.
*/
private static final String elementTable = "elementTable";
/**
* String representing the table that stores the quote and the point it
* links to.
*/
private static final String quoteTable = "quoteTable";
/**
* String representing the table that stores the piece and the
* correct/incorrect responses on various dates
*/
private static final String statsTable = "statsTable";
// ----------------------------------------------------------------------------------
/** String representing the piece field of the piece table */
private static final String pieceField = "piece";
/** String representing the type field of the piece table */
private static final String typeField = "isPlay";
/** String representing the point field of the specific table */
private static final String pointField = "point";
/** String representing the element field of the element table */
private static final String elementField = "element";
/** String representing the elType field of the element table */
private static final String elTypeField = "isCharacter";
/** String representing the quote field of the quote table */
private static final String quoteField = "quote";
/** String representing the ID field of the stats table */
private static final String idField = "statId";
/** String representing the correct field of the stats table */
private static final String correctField = "correct";
/** String representing the incorrect field of the stats table */
private static final String incorrectField = "incorrect";
/** String representing the date field of the stats table */
private static final String dateField = "date";
// ----------------------------------------------------------------------------------
/** String array representing all the fields of the piece table */
private static final String[] pieceTableFields = { pieceField, typeField };
/** String array representing all the fields of the specific table */
private static final String[] specificTableFields = { pointField,
pieceField, elementField };
/** String array representing all the fields of the quote table */
private static final String[] quoteTableFields = { quoteField, pointField };
/** String array representing all the fields of the element table */
private static final String[] elementTableFields = { elementField,
pieceField, elTypeField };
/** String array representing all the fields of the stats table */
private static final String[] statsTableFields = { idField, pieceField,
correctField, incorrectField, dateField };
// ----------------------------------------------------------------------------------
/** SQL statement to create the piece table. */
private static final String createPieceTable = "CREATE TABLE " + pieceTable
+ " (" + pieceField + " TEXT NOT NULL PRIMARY KEY, " + typeField
+ " INTEGER);";
/** SQL statement to create the specific table. */
private static final String createSpecificTable = "CREATE TABLE "
+ specificTable + "(" + pointField + " TEXT NOT NULL PRIMARY KEY,"
+ pieceField + " TEXT NOT NULL," + elementField + " TEXT NOT NULL)";
/** SQL statement to create the quotes table. */
private static final String createQuoteTable = "CREATE TABLE " + quoteTable
+ "(" + quoteField + " TEXT NOT NULL PRIMARY KEY," + pointField
+ " TEXT NOT NULL PRIMARY KEY)";
/** SQL statement to create the element table. */
private static final String createElementTable = "CREATE TABLE "
+ elementTable + "(" + elementField + " TEXT NOT NULL PRIMARY KEY,"
+ pieceField + " TEXT NOT NULL," + elTypeField + " INTEGER)";
/** SQL statement to create the stats table. */
private static final String createStatsTable = "CREATE TABLE " + statsTable
+ "(" + idField + " INTEGER PRIMARY KEY," + pieceField
+ " TEXT NOT NULL," + correctField + " INTEGER," + incorrectField
+ " INTEGER," + dateField + " DATE)";
// ----------------------------------------------------------------------------------
/**
* SQL statement to search the piece table - replace [columnName] and
* [value] with field to be searched and what value to look for.
*/
private static final String searchPieceTable = "SELECT * FROM "
+ pieceTable + " WHERE [columnName] = '[value]';";
/**
* SQL statement to search the specific table - replace [columnName] and
* [value] with field to be searched and what value to look for.
*/
private static final String searchSpecificTable = "SELECT * FROM "
+ specificTable + " WHERE [columnName] = '[value]'";
/**
* SQL statement to search the quote table - replace [columnName] and
* [value] with field to be searched and what value to look for.
*/
private static final String searchQuoteTable = "SELECT * FROM "
+ quoteTable + " WHERE [columnName] = '[value]'";
/**
* SQL statement to search the element table - replace [columnName] and
* [value] with field to be searched and what value to look for.
*/
private static final String searchElementTable = "SELECT * FROM "
+ elementTable + " WHERE [columnName] = '[value]'";
/**
* SQL statement to search the stats table - replace [columnName] and
* [value] with field to be searched and what value to look for.
*/
private static final String searchStatsTable = "SELECT * FROM "
+ statsTable + " WHERE [columnName] = '[value]'";
// ----------------------------------------------------------------------------------
/**
* SQL statement to update the piece table - replace [assignValues] and
* [condition] with items to be altered + their new values and the condition
* where if true, this change should be applied.
*/
private static final String updatePieceTable = "UPDATE " + pieceTable
+ " SET [assignValues] WHERE [condition]";
/**
* SQL statement to update the specific table - replace [assignValues] and
* [condition] with items to be altered + their new values and the condition
* where if true, this change should be applied.
*/
private static final String updateSpecificTable = "UPDATE " + specificTable
+ " SET [assignValues] WHERE [condition]";
/**
* SQL statement to update the quote table - replace [assignValues] and
* [condition] with items to be altered + their new values and the condition
* where if true, this change should be applied.
*/
private static final String updateQuoteTable = "UPDATE " + quoteTable
+ " SET [assignValues] WHERE [condition]";
/**
* SQL statement to update the element table - replace [assignValues] and
* [condition] with items to be altered + their new values and the condition
* where if true, this change should be applied.
*/
private static final String updateElementTable = "UPDATE " + elementTable
+ " SET [assignValues] WHERE [condition]";
/**
* SQL statement to update the stats table - replace [assignValues] and
* [condition] with items to be altered + their new values and the condition
* where if true, this change should be applied.
*/
private static final String updateStatsTable = "UPDATE " + statsTable
+ " SET [assignValues] WHERE [condition]";
// ----------------------------------------------------------------------------------
/**
* SQL statement to delete from the piece table - replace [condition] the
* condition where if true, this deletion should be applied.
*/
private static final String deleteFromPieceTable = "DELETE FROM "
+ pieceTable + " WHERE [condition]";
/**
* SQL statement to delete from the specific table - replace [condition] the
* condition where if true, this deletion should be applied.
*/
private static final String deleteFromSpecificTable = "DELETE FROM "
+ specificTable + " WHERE [condition]";
/**
* SQL statement to delete from the quote table - replace [condition] the
* condition where if true, this deletion should be applied.
*/
private static final String deleteFromQuoteTable = "DELETE FROM "
+ quoteTable + " WHERE [condition]";
/**
* SQL statement to delete from the element table - replace [condition] the
* condition where if true, this deletion should be applied.
*/
private static final String deleteFromElementTable = "DELETE FROM "
+ elementTable + " WHERE [condition]";
/**
* SQL statement to delete from the stats table - replace [condition] the
* condition where if true, this deletion should be applied.
*/
private static final String deleteFromStatsTable = "DELETE FROM "
+ statsTable + " WHERE [condition]";
// ----------------------------------------------------------------------------------
/**
* SQL statement to insert into the piece table - replace [values] with the
* values to be inserted.
*/
private static final String insertIntoPieceTable = "INSERT INTO "
+ pieceTable + " VALUES ([values])";
/**
* SQL statement to insert into the specific table - replace [values] with
* the values to be inserted.
*/
private static final String insertIntoSpecificTable = "INSERT INTO "
+ specificTable + " VALUES ([values])";
/**
* SQL statement to insert into the quote table - replace [values] with the
* values to be inserted.
*/
private static final String insertIntoQuoteTable = "INSERT INTO "
+ quoteTable + " VALUES ([values])";
/**
* SQL statement to insert into the element table - replace [values] with
* the values to be inserted.
*/
private static final String insertIntoElementTable = "INSERT INTO "
+ elementTable + " VALUES ([values])";
/**
* SQL statement to insert into the quote table - replace [values] with the
* values to be inserted.
*/
private static final String insertIntoStatsTable = "INSERT INTO "
+ statsTable + " VALUES ([values])";
// ----------------------------------------------------------------------------------
/**
* SQLiteDatabase representing the English database
*/
private SQLiteDatabase dataBase;
/**
* Instance of DatabaseHelper class utilised to 'access' database
*/
private DatabaseHelper baseHelper;
/**
* Content of the Database Manipulator (ManipulateDatabase class)
*/
private Activity context;
/**
* Boolean to store whether or not this is the first time this base/version
* has been launched
*/
private boolean initialLaunch = false;
/**
* Scanners to read the .txt lists to to input to database
*/
private Scanner pieceScan = new Scanner("pieceList.txt");
private Scanner specificScan = new Scanner("specificList.txt");
private Scanner elementScan = new Scanner("elementList.txt");
private Scanner quoteScan = new Scanner("quoteList.txt");
/**
* Method to open the database
*/
private void openSesame() {
try {
dataBase = baseHelper.getWritableDatabase();
} catch (SQLiteException e) {
System.out.println("Database couldn't be opened");
e.printStackTrace();
}
}
/**
* Method to close the database
*/
private void closeSesame() {
baseHelper.close();
}
public ArrayList<String> getPieces(String typePiece) {
try {
openSesame();
ArrayList<String> pieces = new ArrayList<String>();
String command = searchPieceTable
.replace("[columnName]", typeField);
command = command.replace("[value]", typePiece);
Cursor cursor = dataBase.rawQuery(command, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
pieces.add(cursor.getString(cursor.getColumnIndex(pieceField)));
cursor.moveToNext();
}
closeSesame();
return pieces;
} catch (SQLiteException e) {
e.printStackTrace();
System.out.println("SQL Problem");
return null;
}
}
/**
* Constructor
*
* #param contextIn
* Context of the MainpulateDatabase class
*/
public ManipulateDatabase(Activity contextIn) {
baseHelper = new DatabaseHelper(contextIn);
context = contextIn;
openSesame();
String line;
String pieceName;
String isDrama;
String point;
String element;
String quote;
String isCharacter;
int commaPoint;
int commaPoint2;
if (initialLaunch) {
while (pieceScan.hasNext()) {
line = pieceScan.nextLine();
commaPoint = line.indexOf(",");
pieceName = line.substring(0, commaPoint);
isDrama = line.substring(commaPoint + 1, line.length() - 1);
ContentValues pv = new ContentValues();
pv.put(pieceField, pieceName);
pv.put(typeField, isDrama);
dataBase.insert(pieceTable, null, pv);
System.out.println("DAMN YOU MORONIC CRETIN!!");
}
while (specificScan.hasNext()) {
line = specificScan.nextLine();
commaPoint = line.indexOf(",");
point = line.substring(0, commaPoint);
commaPoint2 = (line
.substring(commaPoint + 1, line.length() - 1)
.indexOf(","));
pieceName = line.substring(commaPoint + 1, commaPoint2);
element = line.substring(commaPoint2 + 1, line.length() - 1);
ContentValues sv = new ContentValues();
sv.put(pointField, point);
sv.put(pieceField, pieceName);
sv.put(elementField, element);
dataBase.insert(specificTable, null, sv);
}
while (elementScan.hasNext()) {
line = elementScan.nextLine();
commaPoint = line.indexOf(",");
element = line.substring(0, commaPoint);
commaPoint2 = (line
.substring(commaPoint + 1, line.length() - 1)
.indexOf(","));
pieceName = line.substring(commaPoint + 1, commaPoint2);
isCharacter = line
.substring(commaPoint2 + 1, line.length() - 1);
ContentValues ev = new ContentValues();
ev.put(elementField, element);
ev.put(pieceField, pieceName);
ev.put(elTypeField, isCharacter);
dataBase.insert(elementTable, null, ev);
}
while (quoteScan.hasNext()) {
line = quoteScan.nextLine();
commaPoint = line.indexOf(",");
quote = line.substring(0, commaPoint);
point = line.substring(commaPoint + 1, line.length() - 1);
ContentValues qv = new ContentValues();
qv.put(quoteField, quote);
qv.put(pointField, point);
dataBase.insert(quoteTable, null, qv);
}
}
}
// ----------------------------------------------------------------------------------
/**
* Database helper - Three basic methods - required database tasks
*
* #author Daniel Lawson
* #version 30/12/13
*/
private class DatabaseHelper extends SQLiteOpenHelper {
private DatabaseHelper(Context theContext) {
super(theContext, databaseName, null, databaseVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(createPieceTable);
/*
* db.execSQL(createSpecificTable);
* db.execSQL(createQuoteTable); db.execSQL(createElementTable);
* db.execSQL(createStatsTable);
*/
// initialLaunch = true;
} catch (SQLiteException e) {
System.out.println("Failed to create table(s)");
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + pieceTable);
db.execSQL("DROP TABLE IF EXISTS " + specificTable);
db.execSQL("DROP TABLE IF EXISTS " + quoteTable);
db.execSQL("DROP TABLE IF EXISTS " + elementTable);
db.execSQL("DROP TABLE IF EXISTS " + statsTable);
onCreate(db);
}
}
}
This is the place on which you should look in logcat:
01-02 18:26:06.344: E/AndroidRuntime(548): Caused by: java.lang.NullPointerException
01-02 18:26:06.344: E/AndroidRuntime(548): at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
probably this call:
novels = md.getPieces("0");
returns null value, but from what I see this should happen only when there is an exception inside:
public ArrayList<String> getPieces(String typePiece) {
so look for problem in this function.
novels ArrayList is null
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/widget/ArrayAdapter.java/
Caused by: java.lang.NullPointerException
01-02 18:26:06.344: E/AndroidRuntime(548): at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
ArrayAdapter.java:330
328
329 public int getCount() {
330 return mObjects.size();
331 }
ArrayAdapter uses getCount which returns the size of the list indicating novels is null which means you should look at
novels = md.getPieces("0");
Related
I have created one listview where I want to retrieve the items from sqlite database. So I have created one method as a List named as getrequestitems where I will map the details and add to a arraylist.
public List<Map<String, String>> getrequestitems() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request WHERE time > date('now','-1 day')";
Cursor rs = db.rawQuery(sql,null);
if(rs.moveToFirst()) {
do {
Map<String, String> dtname = new HashMap<String, String>();
dtname.put("bloodgrp", rs.getString(rs.getColumnIndex("bloodgrp")));
dtname.put("date", "Date:- " + rs.getString(rs.getColumnIndex("Datetime1")));
dtname.put("time", "Time:- " + rs.getString(rs.getColumnIndex("time")));
dtname.put("name", "Name:- " + rs.getString(rs.getColumnIndex("Name")));
dtname.put("Username", rs.getString(rs.getColumnIndex("Username")));
data.add(dtname);
}
while (rs.moveToNext());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return data;
}
But When I open that activity It doesn't displayed any records. I have debug the code but can't any exception. I have written wrong query? as "SELECT * from request WHERE time > date('now','-1 day')";
Here is my complete code.
public class request extends AppCompatActivity {
SimpleAdapter ad;
TextView list3;
private SlidrInterface slidr;
private DBHandler dbHandler;
private static ArrayList<String> arrayList = new ArrayList<>();
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request);
slidr = Slidr.attach(this);
slidr.unlock();
dbHandler = new DBHandler(this);
list3 = findViewById(R.id.list3);
TextView txt = findViewById(R.id.list4);
ListView lst1 = (ListView) findViewById(R.id.list2);
List<Map<String, String>> MyDataList = null;
MyDataList = getrequestitems();
String[] from = {"bloodgrp", "date", "time", "name", "Username"};
int[] to = {R.id.listt, R.id.date, R.id.time1, R.id.name3, R.id.user};
ad = new SimpleAdapter(request.this, MyDataList, R.layout.listrequest, from, to);
lst1.setAdapter(ad);
lst1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
List<Map<String, String>> MyDataList1 = null;
MyDataList1 = getrequestitems();
String[] from = {"Username"};
int[] to = {R.id.user};
Toast.makeText(getApplicationContext(), MyDataList1.toString(), Toast.LENGTH_SHORT).show();
ad = new SimpleAdapter(request.this, MyDataList1, R.layout.listrequest, from, to);
if(ad.getCount()==0){
Toast.makeText(getApplicationContext(), "No requests are currently visible", Toast.LENGTH_SHORT).show();
}
HashMap<String, String> obj = (HashMap<String, String>) ad.getItem(i);
String name = (String) obj.get("Username");
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "select * from request where Username = '" + name + "'";
Cursor rs = db.rawQuery(sql,null);
if (rs.moveToFirst()) {
do {
runOnUiThread(new Runnable() {
#SuppressLint("Range")
#Override
public void run() {
try {
final AlertDialog.Builder alert = new AlertDialog.Builder(request.this);
View mView = getLayoutInflater().inflate(R.layout.custom_dialog3, null);
final TextView txt_inputText = (TextView) mView.findViewById(R.id.name1);
txt_inputText.setText(rs.getString(rs.getColumnIndex("Name")));
final TextView txt_inputText2 = (TextView) mView.findViewById(R.id.contactno1);
txt_inputText2.setText(rs.getString(rs.getColumnIndex("contactNo")));
final TextView txt_inputText3 = (TextView) mView.findViewById(R.id.message1);
txt_inputText3.setText(rs.getString(rs.getColumnIndex("message")));
Button btn_cancel = (Button) mView.findViewById(R.id.btn_cancel);
Button btn_okay = (Button) mView.findViewById(R.id.btn_okay);
alert.setView(mView);
final AlertDialog alertDialog = alert.create();
alertDialog.setCanceledOnTouchOutside(false);
btn_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
btn_okay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = txt_inputText2.getText().toString();
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));// Initiates the Intent
startActivity(intent);
alertDialog.dismiss();
}
});
alertDialog.show();
alertDialog.getWindow().setLayout(730, 850); //Controlling width and height.
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
});
}while (rs.moveToNext());
}
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
});
}
#SuppressLint("Range")
public List<Map<String, String>> getrequestitems() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request WHERE time > date('now','-1 day')";
Cursor rs = db.rawQuery(sql,null);
if(rs.moveToFirst()) {
do {
Map<String, String> dtname = new HashMap<String, String>();
dtname.put("bloodgrp", rs.getString(rs.getColumnIndex("bloodgrp")));
dtname.put("date", "Date:- " + rs.getString(rs.getColumnIndex("Datetime1")));
dtname.put("time", "Time:- " + rs.getString(rs.getColumnIndex("time")));
dtname.put("name", "Name:- " + rs.getString(rs.getColumnIndex("Name")));
dtname.put("Username", rs.getString(rs.getColumnIndex("Username")));
data.add(dtname);
}
while (rs.moveToNext());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return data;
}
}
But When I open that activity It doesn't displayed any records. I have debug the code but can't any exception. I have written wrong query?
probably as it appears that you are very likely comparing the anecdotal oranges and apples (see explanation/example) that is, at a guess you are comparing the time and a date (see Possible fix below BUT this very much depends upon what you are actually storing in the time column, see Possible debug action below that would allow you to see a) if you are extracting any data and if applying the get all (no WHERE clause) to see the actual underlying data)
format is yyyy-MM-dd –
That seems unlikely or if not a waste seeing that you have a column for the date and a column for the time.
If the time contains just the time hh:mm or even hh:mm:ss, as an example then extracting the date is going to result in unintended results.
Consider the following that highlights the issues that you may encounter:-
DROP TABLE IF EXISTS request;
CREATE TABLE IF NOT EXISTS request (booldgrp TEXT, Datetime1 TEXT, time TEXT, Name TEXT, Username TEXT);
INSERT INTO request VALUES
('O','2023-01-01 10:10','2023-01-01 10:10','FRED','USER001')
,('O','2023-01-01 10:10','10:10','FRED','USER002')
,('O','2023-01-01 10:10','2023-01-01 23:11','FRED','USER003')
,('O','2023-01-01 10:10','23:59','FRED','USER004')
,('O','2023-01-01 10:10','21:59','FRED','USER005')
,('O','2023-01-01 10:10','22:00','FRED','USER006')
,('O','2023-01-01 10:10','20:00','FRED','USER007')
,('O','2023-01-01 10:10','20:01','FRED','USER008')
,('O','2023-01-01 10:10','19:59:59','FRED','USER009')
;
SELECT *, date('now','-1 day') AS comparedate, time > date('now','-1 day') AS comparison FROM request;
SELECT *, date('now','-1 day') AS comparedate, datetime1 > date('now','-1 day') AS comparison FROM request;
DROP table IF EXISTS request;
that you can run in your favourite SQLite tool (Navicat was used)
The resultant output (what would be in the Cursor) is :-
As can be seen if the time is actually stored as hh:mm or hh:mm:ss (or similar where you just have the time and not the date) then the first 2 characters are significant, so if the year of the current date - 1 day is in the 21st century that only times that are 8 pm (20:00) or greater would be selected.
Possible fix (if date column has the date only or the date and time and the time column has the time)
Perhaps you want "SELECT * from request WHERE datetime1 > date('now','-1 day')"
Possible debug action
If the above is not the fix for your situation then consider changing your code to :-
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request /* WHERE time > date('now','-1 day') */"; // <<<<<<<<<< WHERE clause commented out to get ALL data, try also with WHERE clause */
Cursor rs = db.rawQuery(sql,null);
DatabaseUtils.dumpCursor(rs); /* ADDED FOR DEBUG, run and check the LOG */
if(rs.moveToFirst()) {
see comments
The log would include either something like (where data is extracted ):-
2022-07-19 13:21:50.995 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#31816bf
2022-07-19 13:21:50.996 I/System.out: 0 {
2022-07-19 13:21:50.996 I/System.out: bloodgrp=O
2022-07-19 13:21:50.996 I/System.out: Datetime1=2023-01-01
2022-07-19 13:21:50.996 I/System.out: time=10:30
2022-07-19 13:21:50.996 I/System.out: Name=FRED
2022-07-19 13:21:50.996 I/System.out: Username=USER001
2022-07-19 13:21:50.996 I/System.out: }
2022-07-19 13:21:50.996 I/System.out: <<<<<
or (where no data has been extracted) :-
2022-07-19 13:24:12.216 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#30380ea
2022-07-19 13:24:12.217 I/System.out: <<<<<
Note
The getColumnIndex index method is case sensitive (or at least was) and as such if any of the column names mismatch, even if only due to the case, then the trapped exception row 0 column -1 will also result in no result (only a short while to notice this with a Toast). I would suggest:-
using Constants for column names and ALWAYS using those Constants to refer to column names i.e. only ever hard code each column name once. Incorrect variables names will not compile. Coded incorrect column names will happily compile and may not be noticed.
consider using e.printStackTrace() as well as or even instead of the Toast
trapping and catching SQLite errors can so easily mask issues
Example
based upon your code, but with :-
DBhandler and layouts composed from what can be gleaned from your code AND
with it inserting a row when the database is created as per :-
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
REQUEST_COLUMN_BLOODGROUP + " TEXT" +
"," + REQUEST_COLUMN_DATE + " TEXT" +
"," + REQUEST_COLUMN_TIME + " TEXT" +
"," + REQUEST_COLUMN_NAME + " TEXT " +
"," + REQUEST_COLUMN_USERNAME + " TEXT" +
"," + REQUEST_COLUMN_CONTACTNo + " TEXT" +
"," + REQUEST_COLUMN_MESSAGE + " TEXT" +
")");
ContentValues cv = new ContentValues();
cv.put(REQUEST_COLUMN_BLOODGROUP,"O");
cv.put(REQUEST_COLUMN_DATE,"2023-01-01");
cv.put(REQUEST_COLUMN_TIME,"10:30");
cv.put(REQUEST_COLUMN_NAME,"FRED");
cv.put(REQUEST_COLUMN_USERNAME,"USER001");
cv.put(REQUEST_COLUMN_CONTACTNo,"0000000000");
cv.put(REQUEST_COLUMN_MESSAGE,"MESSAGE X");
db.insert(TABLE_NAME,null,cv);
}
with the Request (changed to capitalise) Activity started directly from the MainActivity
and with the possible fix applied to the WHERE clause (i.e. Datetime column used for the comparison rather than the time column)
The ListView with a Teal background (to distinguish it)
Then when run :-
and then when the item is clicked:-
and if OK is clicked :-
When I call function 'test' my app crashes. Any ideas why does that happen?
DB class
package com.example.paulcosma.app2;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DB extends SQLiteOpenHelper{
public static final String
dbName = "foods.db",
tableName = "foods",
colId = "id",colName = "name",colCarbs = "carbs";
public DB(Context context) {
super(context, dbName, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + dbName + "( " + colId + " INTEGER PRIMARY KEY AUTOINCREMENT," + colName + " TEXT," + colCarbs + " REAL)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + dbName);
onCreate(db);
}
public boolean addFood(String Name, float Carbs){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(colName,Name);
contentValues.put(colCarbs,Carbs);
long result = db.insert(tableName,null,contentValues);
return result != -1; // -1 == not inserted
}
}
MainActivity
package com.example.paulcosma.app2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
DB db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DB(this);
}
public void test(View v){
boolean insertedSuccessfully = db.addFood("Milk",4); // crashes when called
if(insertedSuccessfully)
Toast.makeText(this,"inserted",Toast.LENGTH_LONG).show();
else Toast.makeText(this,"not inserted",Toast.LENGTH_LONG).show();
}
}
logcat
01-20 19:59:47.888 9565-9565/com.example.paulcosma.app2 E/InstantRun:
Could not find slices in APK; aborting. 01-20 19:59:47.988
9565-9565/com.example.paulcosma.app2 E/dalvikvm: Could not find class
'android.graphics.drawable.RippleDrawable', referenced from method
android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
01-20 19:59:48.005 9565-9565/com.example.paulcosma.app2 E/TextView:
zhangcl: get font resource from application failed. 01-20
19:59:48.013 9565-9565/com.example.paulcosma.app2 E/TextView: zhangcl:
get font resource from application failed -- 2. 01-20 19:59:48.045
9565-9565/com.example.paulcosma.app2 E/TextView: zhangcl: get font
resource from application failed. 01-20 20:00:02.211
9565-9565/com.example.paulcosma.app2 E/SQLiteLog: (10) Failed to do
file read, got: 0, amt: 100, last Errno: 2 01-20 20:00:02.244
9565-9565/com.example.paulcosma.app2 E/SQLiteLog: (1) unknown database
foods 01-20 20:00:02.263 9565-9565/com.example.paulcosma.app2
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.paulcosma.app2, PID: 9565
java.lang.IllegalStateException: Could not execute method for
android:onClick
You've got a typo in onCreate(). You're using dbName instead of tableName to create your table, therefore when you're running your query which is looking up the correct name, you're looking up a table that doesn't exist. So:
db.execSQL("create table " + dbName + "( " + colId + " INTEGER PRIMARY KEY AUTOINCREMENT," + colName + " TEXT," + colCarbs + " REAL)");
needs to become:
db.execSQL("create table " + tableName + "( " + colId + " INTEGER PRIMARY KEY AUTOINCREMENT," + colName + " TEXT," + colCarbs + " REAL)");
Hi I am struggling with these two:
i) I created sqlite database for my android app. And added rows through Main Activity. Now, whenever I am running my program, everytime the same rows getting added in database. How to ensure only one time database gets created with all these rows.
ii) I made id (int type) as primary key and made it auto-increment.I don't want primary ID to be auto-incremental and can be set manually for each row. How I can do it?
1. All database related functions have been in this code:
public class DataBaseHandlerActivity extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "shopsManager";
// Shop table name
private static final String TABLE_SHOPS = "shops";
// Shop Table Columns names
private static final String KEY_ID = "shopid";
private static final String KEY_NAME = "shopname";
private static final String KEY_ADDRESS = "shopaddress";
private static final String KEY_CAT1="category1";
private static final String KEY_CAT2="category2";
private static final String KEY_CAT3="category3";
private static final String KEY_CAT4="category4";
private static final String KEY_IMAGE="shopimage";
public DataBaseHandlerActivity(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_SHOPS_TABLE="CREATE TABLE "+TABLE_SHOPS+"("+KEY_ID+" INTEGER PRIMARY KEY,"+KEY_NAME+" TEXT,"+
KEY_IMAGE+" TEXT,"+
KEY_ADDRESS+" TEXT,"+KEY_CAT1+" TEXT,"+KEY_CAT2+" TEXT,"+KEY_CAT3+" TEXT,"+KEY_CAT4+" TEXT"+
")";
db.execSQL(CREATE_SHOPS_TABLE);
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS"+TABLE_SHOPS);
//CREATE TABLE AGAIN
onCreate(db);
}
/**
* All CRUD(Create, Read, Update, Delete) Operations
*/
//Add a new shop row
void addShop(Shop shop){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME,shop.getShopName());
values.put(KEY_IMAGE,shop.getShopImage());
values.put(KEY_ADDRESS,shop.getShopAddress());
values.put(KEY_CAT1,shop.getShopCat1());
values.put(KEY_CAT2,shop.getShopCat2());
values.put(KEY_CAT3,shop.getShopCat3());
values.put(KEY_CAT4,shop.getShopCat4());
//Inserting row
db.insert(TABLE_SHOPS,null,values);
db.close(); //Close db connection
}
//Get a shop items corresponding to a primary key
Shop getShop(int id){
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.query(TABLE_SHOPS,new String[]{KEY_ID,KEY_NAME,KEY_IMAGE,KEY_ADDRESS,KEY_CAT1,KEY_CAT2,KEY_CAT3,KEY_CAT4},
KEY_ID +"=?",new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Shop shop = new Shop(Integer.parseInt(cursor.getString(0)),
cursor.getString(1), cursor.getString(2),cursor.getString(3),cursor.getString(4),cursor.getString(5),
cursor.getString(6),cursor.getString(7));
// return shop
return shop;
}
// Getting All Shops
public List<Shop> getAllShops() {
List<Shop> shopList = new ArrayList<Shop>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SHOPS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Shop shop = new Shop();
shop.setShopId(Integer.parseInt(cursor.getString(0)));
shop.setShopName(cursor.getString(1));
shop.setShopImage(cursor.getString(2));
shop.setShopAddress(cursor.getString(3));
shop.setShopCat1(cursor.getString(4));
shop.setShopCat2(cursor.getString(5));
shop.setShopCat3(cursor.getString(6));
shop.setShopCat4(cursor.getString(7));
// Adding contact to list
shopList.add(shop);
} while (cursor.moveToNext());
}
// return shop list
return shopList;
}
// Updating single shop
public int updateShop(Shop shop) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME,shop.getShopName());
values.put(KEY_IMAGE,shop.getShopImage());
values.put(KEY_ADDRESS,shop.getShopAddress());
values.put(KEY_CAT1,shop.getShopCat1());
values.put(KEY_CAT2,shop.getShopCat2());
values.put(KEY_CAT3,shop.getShopCat3());
values.put(KEY_CAT4,shop.getShopCat4());
// updating row
return db.update(TABLE_SHOPS, values, KEY_ID + " = ?",
new String[] { String.valueOf(shop.getShopId()) });
}
// Deleting single shop
public void deleteShop(Shop shop) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_SHOPS, KEY_ID + " = ?",
new String[] { String.valueOf(shop.getShopId()) });
db.close();
}
// Getting shops Count
public int getShopsCount() {
String countQuery = "SELECT * FROM " + TABLE_SHOPS;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count=cursor.getCount();
cursor.close();
db.close() ;
// return count
return count;
}
}
2. Main Activity where I pass data to create table:
package com.trillbit.databaseactivity;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DataBaseHandlerActivity db=new DataBaseHandlerActivity(this);
/**
* CRUD Operations
* */
// Inserting Shops
Log.d("Insert: ", "Inserting ..");
db.addShop(new Shop("Shoppers Stop","shopperstop","1st Floor,Forum Mall","Fashion","Clothes","Home","Shoes"));
db.addShop(new Shop("LifeStyle", "lifestyle", "2nd Floor, Forum Mall", "Fashion", "Clothes","Home", "Mobile"));
db.addShop(new Shop("Ezone", "ezone","3rd Floor, Forum Mall","Mobile","Electronics","Apppliances","Home"));
db.addShop(new Shop("Dominos", "dominos","1st Floor,Forum Mall","Food","Pizza","Cake","Pastery"));
// Reading all shops
Log.d("Reading: ", "Reading all shops..");
List<Shop> shops = db.getAllShops();
for (Shop shop : shops) {
String log = "Id: " + shop.getShopId() + " ,Name: " + shop.getShopName() + " ,Image: " + shop.getShopImage()
+ ",Address: " + shop.getShopAddress() + ",Categort1: " + shop.getShopCat1() + ", Category2: " + shop.getShopCat2()
+ ",Category3: " + shop.getShopCat3() + ",Catgeory4: " + shop.getShopCat4();
// Writing Shops to log
Log.d("Name: ", log);
}
}
}
3.Output in logcat:
D/Name:: Id: 5 ,Name: Shoppers Stop ,Image: shopperstop,Address: 1st Floor,Forunm Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Shoes
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 6 ,Name: LifeStyle ,Image: lifestyle,Address: 2nd Floor, Forum Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Mobile
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 7 ,Name: Ezone ,Image: ezone,Address: 3rd Floor, Forum Mall,Categort1: Mobile, Category2: Electronics,Category3: Apppliances,Catgeory4: Home
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 8 ,Name: Dominos ,Image: dominos,Address: 1st Floor,Forum Mall,Categort1: Food, Category2: Pizza,Category3: Cake,Catgeory4: Pastery
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 9 ,Name: Shoppers Stop ,Image: shopperstop,Address: 1st Floor,Forum Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Shoes
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 10 ,Name: LifeStyle ,Image: lifestyle,Address: 2nd Floor, Forum Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Mobile
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 11 ,Name: Ezone ,Image: ezone,Address: 3rd Floor, Forum Mall,Categort1: Mobile, Category2: Electronics,Category3: Apppliances,Catgeory4: Home
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 12 ,Name: Dominos ,Image: dominos,Address: 1st Floor,Forum Mall,Categort1: Food, Category2: Pizza,Category3: Cake,Catgeory4: Pastery
You add the those rows every single time your Activity is created.
Use SharedPreferences to mark a boolean that says your app started once
Create a UNIQUE CONSTRAINT in the database table definition.
It will automatically prevent duplicate entries.
OR
Instead of
INSERT ...
do
INSERT OR IGNORE ...
This means that instead of returning an error code if you violate a constraint, SQLite just returns SQLITE_OK as if the command succeeded.
For others benefit, I am writing how I solved using shared preferences as suggested by cricket-007. At start of main activity, created database when application gets installed and run first time.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false)) {
// run your one time code
// Inserting Shops
Log.d("Insert: ", "Inserting ..");
db.addShop(new Shop("01","Shoppers Stop","shopperstop","1st Floor,Forum Mall","Fashion","Clothes","Home","Shoes"));
db.addShop(new Shop("02","LifeStyle", "lifestyle", "2nd Floor, Forum Mall", "Fashion", "Clothes","Home", "Mobile"));
db.addShop(new Shop("03","Ezone", "ezone","3rd Floor, Forum Mall","Mobile","Electronics","Apppliances","Home"));
db.addShop(new Shop("04","Dominos", "dominos","1st Floor,Forum Mall","Food","Pizza","Cake","Pastery"));
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.commit();
}
so in my app i am using get and set methods. when it executes the set method, the app doesnt crash but when it gets to the get method, it crashes. i worked out that it crashes when it gets to the db.query() line in the get method but i think the problem could also be in the set method since they both give error messages.
here is my code:
public class MyDBHandler extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String COLUMN_ID = "_id";
public static final String TABLE_VALUES = "values";
public static final String COLUMN_TARGET = "target";
public static final String COLUMN_CURRENT = "current";
public MyDBHandler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query1 = "CREATE TABLE " + TABLE_VALUES + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_TARGET + " INT, " +
COLUMN_CURRENT + " INT);";
db.execSQL(query1);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_VALUES);
onCreate(db);
}
public void setTarget(int tar){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_TARGET, tar);
values.put(COLUMN_CURRENT, 0);
db.insert(TABLE_VALUES, null, values);
db.close();
}
public int getTarget() {
SQLiteDatabase db = this.getReadableDatabase();
int targetVal=0;
String[] columns = {COLUMN_TARGET};
Cursor c = db.query(TABLE_VALUES, columns, null, null, null, null, String.valueOf(1));
if(c.getCount()>0)
{
c.moveToFirst();
targetVal=c.getInt(0);
}
db.close();
c.close();
return targetVal;
}
}
the set function is used here:
public class home extends AppCompatActivity {
MyDBHandler db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
db = new MyDBHandler(this);
}
public void enter(View view)
{
EditText target = (EditText) findViewById(R.id.target);
TextView warning = (TextView) findViewById(R.id.warning);
String check = target.getText().toString();
if(check.equals("")) {
// Intent a = new Intent(this, MainActivity.class);
//startActivity(a);
warning.setText("Please enter a value");
return;
}
else {
int input = Integer.parseInt(check);
Log.d("tag", "111\n");
db.setTarget(input);
Log.d("tag", "222\n");
//int i = db.getTarget();
//Log.d("tag","input is " + i );
Intent a = new Intent(this, MainActivity.class);
startActivity(a);
}
}
}
the get function is used here:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onTrack(View view){
Log.d("tag", "traaaack\n");
Intent i = new Intent(this, Track.class);
startActivity(i);
}
}
and here are the error messages parts from the log.
this is when the set method is called:
E/SQLiteLog: (1) near "values": syntax error
E/SQLiteDatabase: Error inserting current=0 target=2000
android.database.sqlite.SQLiteException: near "values": syntax error (code 1): , while compiling: INSERT INTO values(current,target) VALUES (?,?)
this is when the get method is called:
E/SQLiteLog: (1) near "values": syntax error
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.user.calorietracker/com.example.user.calorietracker.Track}: android.database.sqlite.SQLiteException: near "values": syntax error (code 1): , while compiling: SELECT target FROM values LIMIT 1
I have tried so many things to fix it but cant work out what i am doing wrong. literally any suggestion would be helpful! thanks
According to the list of SQLite Keywords - the word values is one of the words that you can't use for the name of your table (or column or many other things).
There are several ways to fix this:
Don't use this word. You can always use tbl_values for example.
You can quote that word:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A keyword enclosed in square brackets is an identifier. This is not standard SQL. This quoting mechanism is used by MS Access and SQL Server and is included in SQLite for compatibility.
`keyword` A keyword enclosed in grave accents (ASCII code 96) is an identifier. This is not standard SQL. This quoting mechanism is used by MySQL and is included in SQLite for compatibility.
I am having a problem getting my SQLite working properly in this Android application that I'm developing. It appears as though the table isn't properly being created based on the LogCat messages. I feel like I've been staring at the screen too long. Can anyone here spot the problem in my code?
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 DBHelper extends SQLiteOpenHelper {
// table name
public static final String TABLE_JOKES = "jokes";
// database field names
public static final String COLUMN_ID = "_id";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_SUBCATEGORY = "subcategory";
public static final String COLUMN_JOKE_TYPE = "jokeType";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_QUESTION_TEXT = "questionText";
public static final String COLUMN_ANSWER_TEXT = "answerText";
public static final String COLUMN_MONOLOGUE_TEXT = "monologueText";
public static final String COLUMN_RATING_SCALE = "ratingScale";
public static final String COLUMN_COMMENTS = "comments";
public static final String COLUMN_JOKE_SOURCE = "jokeSource";
public static final String COLUMN_RELEASE_STATUS = "releaseStatus";
public static final String COLUMN_CREATED = "created";
public static final String COLUMN_MODIFIED = "modified";
private static final String DATABASE_NAME = "jokes.db"; // file name
private static final int DATABASE_VERSION = 1;
// Database creation raw SQL statement
private static final String DATABASE_CREATE = "create table " + TABLE_JOKES
+ "( " + COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_CATEGORY + " text not null, " + COLUMN_SUBCATEGORY
+ " text not null, " + COLUMN_JOKE_TYPE + " integer not null, "
+ COLUMN_DESCRIPTION + " text," + COLUMN_QUESTION_TEXT + "text,"
+ COLUMN_ANSWER_TEXT + "text," + COLUMN_MONOLOGUE_TEXT + "text,"
+ COLUMN_RATING_SCALE + "integer," + COLUMN_COMMENTS + "text,"
+ COLUMN_JOKE_SOURCE + "text," + COLUMN_RELEASE_STATUS + "integer,"
+ COLUMN_CREATED + "text," + COLUMN_MODIFIED + "text" + ");";
// static instance to share DBHelper
private static DBHelper dbHelper = null;
private SQLiteDatabase db ;
/**
* Constructor
*
* #param context
* #param name
* #param factory
* #param version
*/
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = getWritableDatabase();
}
/**
* This is a static method that makes sure that only one database helper
* exists across the app's lifecycle
*
* #param context
* #return
*/
public static DBHelper getDBHelper(Context context) {
if (dbHelper == null) {
dbHelper = new DBHelper(context.getApplicationContext());
}
return dbHelper;
}
/*
* (non-Javadoc)
*
* #see
* android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite
* .SQLiteDatabase)
*/
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
/*
* (non-Javadoc)
*
* #see
* android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite
* .SQLiteDatabase, int, int)
*/
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
Log.w(DBHelper.class.getName(), "Upgrading database from version "
+ oldVersion + " to " + newVersion);
}
/**
* CRUD - Update
*
* #param category
* #param subcategory
* #param jokeType
* #param description
* #param questionText
* #param answerText
* #param monologueText
* #param comments
* #param jokeSource
* #param ratingScale
* #param releaseStatus
* #return
*/
public long insertNewJoke(String category, String subcategory,
int jokeType, String description, String questionText,
String answerText, String monologueText, String comments,
String jokeSource, int ratingScale, int releaseStatus) {
ContentValues cv = new ContentValues();
cv.put(COLUMN_CATEGORY, category);
cv.put(COLUMN_SUBCATEGORY, subcategory);
cv.put(COLUMN_JOKE_TYPE, jokeType);
cv.put(COLUMN_DESCRIPTION, description);
cv.put(COLUMN_QUESTION_TEXT, questionText);
cv.put(COLUMN_ANSWER_TEXT, answerText);
cv.put(COLUMN_MONOLOGUE_TEXT, monologueText);
cv.put(COLUMN_COMMENTS, comments);
cv.put(COLUMN_JOKE_SOURCE, jokeSource);
cv.put(COLUMN_RATING_SCALE, ratingScale);
cv.put(COLUMN_RELEASE_STATUS, releaseStatus);
cv.put(COLUMN_CREATED, ""); // how to put date??
cv.put(COLUMN_CREATED, "");
long code = getWritableDatabase().insert(TABLE_JOKES, null, cv);
return code;
}
/**
* CRUD - Retrieve
*
* #return
*/
public Cursor getJokes() {
String[] columns = { COLUMN_CATEGORY, COLUMN_SUBCATEGORY,
COLUMN_JOKE_TYPE, COLUMN_DESCRIPTION, COLUMN_ANSWER_TEXT,
COLUMN_MONOLOGUE_TEXT, COLUMN_RATING_SCALE, COLUMN_COMMENTS,
COLUMN_JOKE_SOURCE, COLUMN_RELEASE_STATUS, COLUMN_CREATED,
COLUMN_MODIFIED }; // might need the _id column
return getWritableDatabase().query(TABLE_JOKES, columns, null, null,
null, null, null);
}
/**
* CRUD - Delete
*
* #param id
*/
public void deleteJoke(int id) {
getWritableDatabase().delete(TABLE_JOKES, COLUMN_ID + "=?",
new String[] { String.valueOf(id) });
}
}
So in onCreate() (in my MainActivity) I try to insert a new record into the database and then try to retrieve it into a cursor. However, it seems to be getting caught at the insert statement.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// the projection (fields from the database that we want to use)
String from[] = { DBHelper.COLUMN_DESCRIPTION };
// matching fields on the layout to be used with the adapter
int to[] = { R.id.tv1 };
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lvMainJokes);
dbHelper = DBHelper.getDBHelper(this);
long code = dbHelper.insertNewJoke("Holiday", "", 2, "Joke 1 Description", "", "",
"joke", "", "", 5, 1);
if (code != -1)
cursor = dbHelper.getJokes();
...
Here is the LogCat output:
11-15 15:19:08.040: I/Choreographer(1016): Skipped 45 frames! The application may be doing too much work on its main thread.
11-15 15:19:35.358: D/dalvikvm(1064): GC_FOR_ALLOC freed 58K, 4% free 2726K/2836K, paused 42ms, total 45ms
11-15 15:19:35.368: I/dalvikvm-heap(1064): Grow heap (frag case) to 3.315MB for 635812-byte allocation
11-15 15:19:35.438: D/dalvikvm(1064): GC_FOR_ALLOC freed 2K, 4% free 3344K/3460K, paused 63ms, total 63ms
11-15 15:19:35.548: E/SQLiteLog(1064): (1) table jokes has no column named releaseStatus
11-15 15:19:35.568: E/SQLiteDatabase(1064): Error inserting category=Holiday releaseStatus=1 jokeType=2 created= monologueText=joke description=Joke 1 Description subcategory= answerText= questionText= jokeSource= ratingScale=5 comments=
11-15 15:19:35.568: E/SQLiteDatabase(1064): android.database.sqlite.SQLiteException: table jokes has no column named releaseStatus (code 1): , while compiling: INSERT INTO jokes(category,releaseStatus,jokeType,created,monologueText,description,subcategory,answerText,questionText,jokeSource,ratingScale,comments) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1467)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at com.teamdotgetname.android.phase1.jokeapplication.persistence.DBHelper.insertNewJoke(DBHelper.java:143)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at com.teamdotgetname.android.phase1.jokeapplication.presentation.MainActivity.onCreate(MainActivity.java:53)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.Activity.performCreate(Activity.java:5133)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.os.Handler.dispatchMessage(Handler.java:99)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.os.Looper.loop(Looper.java:137)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at android.app.ActivityThread.main(ActivityThread.java:5103)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at java.lang.reflect.Method.invokeNative(Native Method)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at java.lang.reflect.Method.invoke(Method.java:525)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-15 15:19:35.568: E/SQLiteDatabase(1064): at dalvik.system.NativeStart.main(Native Method)
11-15 15:19:35.798: I/Choreographer(1064): Skipped 42 frames! The application may be doing too much work on its main thread.
11-15 15:19:35.868: D/gralloc_goldfish(1064): Emulator without GPU emulation detected.
Thanks for taking a look.
At a quick glance, your code looks good. The exception:
android.database.sqlite.SQLiteException: table jokes has no column named releaseStatus (code 1)
seems erroneous because clearly you are creating the releaseStatus column in your create table DATABASE_CREATE String. I ran into a problem where I was modifying the schema of my database and the changes were not taking effect in my application because I was not incrementing the DATABASE_VERSION.
Your options to try which will all cause the database to get recreated are:
Clear the applications data via the Settings apk
Manually uninstall then reinstall your application. (Just running gradle installDebug or having Eclipse install your app isn't good enough)
Increment your DATABASE_VERSION value
I would say that you need some space in Create statement.
Starting: COLUMN_QUESTION_TEXT + "text," into COLUMN_QUESTION_TEXT + " text,".
It looks just like you don't have spaces between the column names and the column types. Try this.
private static final String DATABASE_CREATE = "create table " + TABLE_JOKES
+ "( " + COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_CATEGORY + " text not null, " + COLUMN_SUBCATEGORY
+ " text not null, " + COLUMN_JOKE_TYPE + " integer not null, "
+ COLUMN_DESCRIPTION + " text," + COLUMN_QUESTION_TEXT + " text,"
+ COLUMN_ANSWER_TEXT + " text," + COLUMN_MONOLOGUE_TEXT + " text,"
+ COLUMN_RATING_SCALE + " integer," + COLUMN_COMMENTS + " text,"
+ COLUMN_JOKE_SOURCE + " text," + COLUMN_RELEASE_STATUS + " integer,"
+ COLUMN_CREATED + " text," + COLUMN_MODIFIED + " text" + ");";
In DATABASE_CREATE mistake "integer," + COLUMN_COMMENTS + "text,". No sepparate space.