I am getting the following error: no such table: categories (code 1): , while compiling: SELECT * FROM categories.
I have an activity, SplashActivity which loads a second activity Category. On the Category Activity, I am loading a spinner with data from a table [categories] in the database. When the user selects an item on the spinner and it should load a QuestionsActivity which shows questions from the database based on the selection on the spinner.
The database is being copied from the Assets folder. It was working and then suddenly the error started popping up when I put the code to load the Question activity on the 'play' button. I have uninstalled the application from my phone to wipe of the data and reloading still gives the same error.
I have looked here and here, still no luck getting it to work.
This is my logcat
06-17 21:15:16.610 16854-16854/zw.co.pindula.funsa E/SQLiteLog﹕ (1) no such table: categories
06-17 21:15:16.624 16854-16854/zw.co.pindula.funsa E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: zw.co.pindula.funsa, PID: 16854
java.lang.RuntimeException: Unable to start activity ComponentInfo{zw.co.pindula.funsa/zw.co.pindula.funsa.util.Category}: android.database.sqlite.SQLiteException: no such table: categories (code 1): , while compiling: SELECT * FROM categories
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: android.database.sqlite.SQLiteException: no such table: categories (code 1): , while compiling: SELECT * FROM categories
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1255)
at zw.co.pindula.funsa.db.DBHelper.getAllCategories(DBHelper.java:168)
at zw.co.pindula.funsa.util.Category.loadCategoryData(Category.java:70)
at zw.co.pindula.funsa.util.Category.onCreate(Category.java:37)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
This is my DBHelper Class
package zw.co.pindula.funsa.db;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import zw.co.pindula.funsa.quiz.Question;
/**
* Created by NKT on 03/06/2015.
*/
public class DBHelper extends SQLiteOpenHelper{
private static String DB_PATH;// = "/data/data/zw.co.pindula.funsa/databases/";
// Database Version
private static final int DATABASE_VERSION = 1;
private static String DB_NAME = "questionsDb";
//Category Table name
private static final String TABLE_CATEGORY = "categories";
private final Context myContext;
//private static String DB_PATH= Context.getDatabasePath(DB_NAME).getPath();
private SQLiteDatabase myDataBase;
public DBHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
this.myContext = context;
DB_PATH = myContext.getDatabasePath(DB_NAME).getPath();
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if(!dbExist)
{
//By calling this method an empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
private boolean checkDataBase(){
/*
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH;// + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database doesn't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
*/
//New checkDataBase method
boolean checkdb = false;
try{
String myPath = myContext.getFilesDir().getAbsolutePath().replace("files", "databases")+ File.separator + DB_NAME;
File dbfile = new File(myPath);
checkdb = dbfile.exists();
}
catch(SQLiteException e){
System.out.println("Database doesn't exist");
}
return checkdb;
}
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH;// + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
//Open the database
String myPath = DB_PATH;// + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed, all data will be gone
//db.execSQL("DROP D IF EXISTS " + TABLE);
// Create tables again
//onCreate(db);
}
public List<Question> getQuestionSet(int difficulty, int numQ){
List<Question> questionSet = new ArrayList<Question>();
Cursor c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE DIFFICULTY=" + difficulty +
" ORDER BY RANDOM() LIMIT " + numQ, null);
while (c.moveToNext()){
//Log.d("QUESTION", "Question Found in DB: " + c.getString(1));
Question q = new Question();
q.setQuestion(c.getString(1));
q.setAnswer(c.getString(2));
q.setOption1(c.getString(3));
q.setOption2(c.getString(4));
q.setOption3(c.getString(5));
q.setRating(difficulty);
questionSet.add(q);
}
return questionSet;
}
/**
* Getting and return all the Categories
* */
public List<String> getAllCategories(){
List<String> myCategories = new ArrayList<String>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_CATEGORY;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
myCategories.add(cursor.getString(1));
} while (cursor.moveToNext());
}
// closing connection
cursor.close();
db.close();
// returning categories
return myCategories;
}
/*
* This method sets the questions using the categories
*/
public List<Question> getQuestionSetCategories(String cat, int difficulty, int numQ){
List<Question> questionSet = new ArrayList<Question>();
Cursor c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE CATEGORY=" + cat +
" ORDER BY RANDOM() LIMIT " + numQ, null);
while (c.moveToNext()){
//Log.d("QUESTION", "Question Found in DB: " + c.getString(1));
Question q = new Question();
q.setQuestion(c.getString(1));
q.setAnswer(c.getString(2));
q.setOption1(c.getString(3));
q.setOption2(c.getString(4));
q.setOption3(c.getString(5));
q.setRating(difficulty);
questionSet.add(q);
}
return questionSet;
}
}
This is the Category Activity
package zw.co.pindula.funsa.util;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.SQLException;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import zw.co.pindula.funsa.R;
import zw.co.pindula.funsa.db.DBHelper;
import zw.co.pindula.funsa.quiz.Constants;
import zw.co.pindula.funsa.quiz.GamePlay;
import zw.co.pindula.funsa.quiz.Question;
public class Category extends Activity implements AdapterView.OnItemSelectedListener {
Spinner spinner;
String theCategory; //This is the String to hold the selected category
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
spinner = (Spinner)findViewById(R.id.mySpinner);
loadCategoryData();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_category, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Function to load the spinner data from SQLite database
* */
private void loadCategoryData() {
// database handler
DBHelper db = new DBHelper(getApplicationContext());
// Spinner Drop down elements
List<String> lables = db.getAllCategories();
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
//dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
dataAdapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
}
public void startGame(View view){
Spinner spinner = (Spinner)findViewById(R.id.mySpinner);
theCategory = spinner.getSelectedItem().toString();
if(theCategory==null){
Toast.makeText(this, "You didn't select anything: ",
Toast.LENGTH_SHORT).show();
}
else
{
Intent i;
List<Question> questions = getQuestionSetFromDb();
//Initialise Game with retrieved question set ///
GamePlay c = new GamePlay();
c.setQuestions(questions);
c.setNumRounds(getNumQuestions());
((FunsaApplication)getApplication()).setCurrentGame(c);
//Start Game Now.. //
i = new Intent(this, QuestionActivity.class);
startActivityForResult(i, Constants.PLAYBUTTON);
//break;
}
}
private List<Question> getQuestionSetFromDb() throws Error {
int diff = getDifficultySettings();
int numQuestions = getNumQuestions();
DBHelper myDbHelper = new DBHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
List<Question> questions = myDbHelper.getQuestionSetCategories(theCategory, diff, numQuestions);
myDbHelper.close();
return questions;
}
/**
* Method to return the difficulty settings
* #return
*/
private int getDifficultySettings() {
SharedPreferences settings = getSharedPreferences(Constants.SETTINGS, 0);
int diff = settings.getInt(Constants.DIFFICULTY, Constants.MEDIUM);
return diff;
}
/**
* Method to return the number of questions for the game
* #return
*/
private int getNumQuestions() {
SharedPreferences settings = getSharedPreferences(Constants.SETTINGS, 0);
int numRounds = settings.getInt(Constants.NUM_ROUNDS, 2); //This sets the number of rounds
return numRounds;
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String selection =adapterView.getItemAtPosition(i).toString();//.getItemAtPosition(i).toString();
theCategory = selection;
// Showing selected spinner item
Toast.makeText(adapterView.getContext(), "You selected: " + selection,
Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
Related
all day long I've been searching the root cause of the following error. I there anyone who can help me with this issue?
Using:
Android Studio 4.1.1 / Java
My goal:
I have a sqlite database created with DB Browser (recipe.db3) in my assets folder: Assets > recipe.db3. This database shall be copied to app database folder in the SplashActivity.java if the database does not exist yet (basically once in app lifetime).
Once created, I want to access this database and show its content (only title) in the RecycleViewer in RecipesFragment.java.
My issue:
I receive a NullPointerException when I try to show my RecyclerView - basically when I run this.getReadableDatabase() in my DataBaseHelper.java. It seems like I cannot even access my database. Even if I do not copy my baking.db3 file to /data/data/com.android.baking/databases/ but create the database programmatically I receive the same error.
Does anyone have a clue where the error lies?
Thanks!
Kornelius
Logcat output
I/database: TABLE_RECIPES created
TABLE_US created
...............
D/EGL_emulation: eglMakeCurrent: 0xb31050c0: ver 2 0 (tinfo 0xb3103660)
I/art: Do partial code cache collection, code=55KB, data=59KB
After code cache collection, code=54KB, data=58KB
Increasing code cache capacity to 256KB
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.baking, PID: 9878
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.android.baking.ui.recipes.RecipesFragment: calling Fragment constructor caused an exception
at androidx.fragment.app.Fragment.instantiate(Fragment.java:566)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.android.baking.DataBaseHelper.<init>(DataBaseHelper.java:64)
at com.android.baking.ui.recipes.RecipesFragment.<init>(RecipesFragment.java:37)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
DataBaseHelper.java:
package com.android.baking;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.ContactsContract;
import android.util.Log;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.models.RecipeModel;
import com.android.baking.ui.models.UserSpecificModel;
import java.util.ArrayList;
import androidx.annotation.Nullable;
public class DataBaseHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
public static String DB_NAME = "recipe.db3";
//ITEMS IN TABLE: RECIPES
public static final String TABLE_RECIPES = "RECIPES";
public static final String RECIPE_RECIPE = "RECIPE";
public static final String RECIPE_ID = "ID";
public static final String RECIPE_SOURCE = "SOURCE";
public static final String RECIPE_TITLE = "TITLE";
...............
public static final String RECIPE_ZERO_DOUGH = "ZERO_DOUGH";
public static final String RECIPE_IMAGE_1 = "IMAGE_1";
public static final String RECIPE_IMAGE_2 = "IMAGE_2";
//ITEMS IN TABLE: USER_SPECIFIC
public static final String TABLE_USER_SPECIFIC = "USER_SPECIFIC";
public static final String US_ID = "ID";
public static final String US_URL = "URL";
public static final String US_NOTES = "NOTES";
public static final String US_IS_FAVORITE = "IS_FAVORITE";
public Context context;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
this.getReadableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
//CREATE RECIPES TABLE
String createTableStatement = "CREATE TABLE " + TABLE_RECIPES + " (" + RECIPE_ID + " INTEGER PRIMARY KEY " +
"AUTOINCREMENT, " + RECIPE_SOURCE + " TEXT, " + RECIPE_TITLE + " TEXT, " + RECIPE_URL + " TEXT, " + RECIPE_DATE + " TEXT, " + RECIPE_IMGLINKS + " TEXT, " + RECIPE_DESCRIPTION + " TEXT, " + RECIPE_INGREDIENTS + " TEXT, " + RECIPE_RECIPE + " TEXT, " + RECIPE_PREPTIME_TOTAL + " TEXT, " + RECIPE_PREPTIME_BAKETIME + " TEXT, " + RECIPE_MATCOST + " TEXT, " + RECIPE_OVERNIGHT + " INTEGER, " + RECIPE_FULL_GRAIN + " INTEGER, " + RECIPE_NO_KNEAD + " INTEGER, " + RECIPE_PASTRY_TYPE + " TEXT, " + RECIPE_DOUGHS + " TEXT, " + RECIPE_TASTE + " TEXT, " + RECIPE_PORES + " TEXT, " + RECIPE_FORM + " TEXT, " + RECIPE_ZERO_DOUGH + " TEXT, " + RECIPE_IMAGE_1 + " BLOB, " + RECIPE_IMAGE_2 + " BLOB)";
db.execSQL(createTableStatement);
Log.i("database", "TABLE_RECIPES created");
//CREATE USER_SPECIFIC TABLE
createTableStatement =
"CREATE TABLE " + TABLE_USER_SPECIFIC + " (" + US_ID + " INTEGER PRIMARY KEY, " + US_URL + " TEXT, " +
US_NOTES + " TEXT, " + US_IS_FAVORITE + " INTEGER)";
db.execSQL(createTableStatement);
Log.i("database", "TABLE_US created");
}
public boolean addOneUS(UserSpecificModel userSpecificModel){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(US_URL, userSpecificModel.getUrl());
cv.put(US_NOTES, userSpecificModel.getNote());
cv.put(US_IS_FAVORITE, userSpecificModel.getIs_favorite());
long insert = db.insert(TABLE_USER_SPECIFIC,null, cv);
if (insert == -1) {
return false;
} else {
return true;
}
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
/*SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECIPES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER_SPECIFIC);
onCreate(db);*/
}
public ArrayList<RecipeModel> getAllRecipes() {
ArrayList<RecipeModel> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
//String where = " where " + ContentDBManager.KEY_id + " = ? ";
Cursor cursor =
db.rawQuery("SELECT * FROM " + TABLE_RECIPES + " ORDER BY " + RECIPE_TITLE + " DESC", null);
if (cursor != null && cursor.getCount() > 0) {
try {
if (cursor.moveToFirst()) {
do {
RecipeModel recipeModel = new RecipeModel();
recipeModel.setId(cursor.getInt(0));
recipeModel.setSource(cursor.getString(1));
recipeModel.setUrl(cursor.getString(2));
recipeModel.setDate(cursor.getString(3));
recipeModel.setImglinks(cursor.getString(4));
recipeModel.setDescription(cursor.getString(5));
recipeModel.setIngredients(cursor.getString(6));
recipeModel.setRecipe(cursor.getString(7));
recipeModel.setPreptime_total(cursor.getString(8));
recipeModel.setPreptime_baketime(cursor.getString(9));
recipeModel.setMatcost(cursor.getString(10));
recipeModel.setOvernight(cursor.getInt(11));
recipeModel.setFull_grain(cursor.getInt(12));
recipeModel.setNo_knead(cursor.getInt(13));
recipeModel.setPastry_type(cursor.getString(14));
recipeModel.setDoughs(cursor.getString(15));
recipeModel.setTaste(cursor.getString(16));
recipeModel.setPores(cursor.getString(17));
recipeModel.setForm(cursor.getString(18));
recipeModel.setZero_dough(cursor.getString(19));
results.add(recipeModel);
} while (cursor.moveToNext());
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (!cursor.isClosed()){
cursor.close();
}
}
} else {
if (cursor != null) {
Log.i("Database",
"Cursor is Null!");
cursor.close();
}
} // to free up memory of cursor
return results;
}
}
SplashActivity.java:
package com.android.baking.ui;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.SQLException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;
import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class SplashActivity extends MainActivity {
private static boolean splashLoaded = false;
private static String DB_PATH;
private static String DB_NAME;
private static final int SPLASH_TIME = 1000;
public final int WRITE_PERMISSION_REQUEST_CODE = 1110;
private final String[] NEEDED_PERMISSIONS = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!checkPermissions(NEEDED_PERMISSIONS)){
ActivityCompat.requestPermissions(SplashActivity.this, NEEDED_PERMISSIONS, WRITE_PERMISSION_REQUEST_CODE);
}else {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
if (!splashLoaded) {
setContentView(R.layout.splash_screen);
int secondsDelayed = 3;
new Handler().postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
}, secondsDelayed * SPLASH_TIME);
splashLoaded = true;
} else {
Intent goToMainActivity = new Intent(SplashActivity.this, MainActivity.class);
goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(goToMainActivity);
finish();
}
//copy database from assets to database folder if it does not exist
//see also: https://stackoverflow.com/questions/18805874/copy-database-from-assets-to-databases-folder/18806587
if (!doesDatabaseExist(this, DataBaseHelper.DB_NAME)){
DB_PATH = getApplicationInfo().dataDir + "/databases/";
DB_NAME = DataBaseHelper.DB_NAME;
copyDataBase(DB_NAME, DB_PATH);
}
}
private static boolean doesDatabaseExist(Context context, String dbName) {
File dbFile = context.getDatabasePath(dbName);
return dbFile.exists();
}
private void copyDataBase(String dbName, String dbPath)
{
Log.i("Database",
"New database is being copied to device!");
byte[] buffer = new byte[1024];
OutputStream myOutput = null;
int length;
// Open your local db as the input stream
InputStream myInput = null;
try
{
myInput = getApplicationContext().getAssets().open(dbName);
// transfer bytes from the inputfile to the
// outputfile
myOutput = new FileOutputStream(dbPath + dbName);
while((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
myOutput.close();
myOutput.flush();
myInput.close();
Log.i("Database",
"New database has been copied to device!");
}
catch(IOException e)
{
e.printStackTrace();
}
}
// to get FaceFeature and FaceIdFeature.
private boolean checkPermissions(String[] neededPermissions) {
if (neededPermissions == null || neededPermissions.length == 0) {
return true;
}
boolean allGranted = true;
for (String neededPermission : neededPermissions) {
allGranted &= ContextCompat.checkSelfPermission(getApplicationContext(), neededPermission) == PackageManager.PERMISSION_GRANTED;
}
return allGranted;
}
private class BackgroundTask extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Object doInBackground(Object[] objects) {
try {
Thread.sleep(SPLASH_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Object[] values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case WRITE_PERMISSION_REQUEST_CODE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
break;
default:
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == WRITE_PERMISSION_REQUEST_CODE && resultCode == RESULT_OK) {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
}
}
RecipeAdapter.java:
package com.android.baking.ui.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.android.baking.R;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
// Create the basic adapter extending from RecyclerView.Adapter
// Note that we specify the custom ViewHolder which gives us access to our views
// see: https://stackoverflow.com/questions/40584424/simple-android-recyclerview-example
public class RecipeAdapter extends
RecyclerView.Adapter<RecipeAdapter.ViewHolder> {
private Context recipeContext;
private ArrayList<RecipeModel> recipeList = new ArrayList<>();
private ArrayList<RecipeModel> recipeSearchList = new ArrayList<>();
private RecipeItemClickListener recipeListener;
public RecipeAdapter(Context context, ArrayList<RecipeModel> recipeContentList, RecipeItemClickListener listener) {
this.recipeContext = context;
this.recipeListener = listener;
this.recipeList.addAll(recipeContentList);
recipeSearchList.addAll(recipeList);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(recipeContext).inflate(R.layout.item_recycler_view_recipes, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final RecipeModel recipeModel = recipeList.get(position);
holder.tv_title.setText(recipeModel.getTitle());
}
#Override
public int getItemCount() {
return recipeList.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_title;
public ViewHolder(View itemView) {
//ToDo: hier weitermachen
super(itemView);
tv_title = itemView.findViewById(R.id.item_title);
}
}
}
RecipeFragment.java:
package com.android.baking.ui.recipes;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;
import java.util.ArrayList;
public class RecipesFragment extends Fragment {
private RecipesViewModel recipesViewModel;
private ArrayList<RecipeModel> recipeList = new ArrayList<>();
private static RecipesFragment mInstance;
DataBaseHelper dataBaseHelper = new DataBaseHelper(getContext());
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
recipesViewModel = new ViewModelProvider(this).get(RecipesViewModel.class);
View root = inflater.inflate(R.layout.fragment_recipes, container, false);
RecyclerView rec_recipes = root.findViewById(R.id.recipes_recycler_view);
rec_recipes.setLayoutManager(new LinearLayoutManager(getContext()));
recipeList = dataBaseHelper.getAllRecipes();
RecipeAdapter recipeAdapter = new RecipeAdapter(getContext(), recipeList, new RecipeItemClickListener() {
#Override
public void OnItemClicked(RecipeModel recipeModel) {
Toast.makeText(getContext(), "You clicked " + recipeModel.getTitle(), Toast.LENGTH_SHORT).show();
}
});
rec_recipes.setAdapter(recipeAdapter);
return root;
}
}
In RecipieFragment.DataBaseHelper, calling getContext() here it may be returning you a null, hence the NPE. Try creating the DataBaseHelper in onCreateView() instead.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am trying to create a graph from my sqlite values for example here Date vs Weight. Later on I will add Date vs Fat etc. But the apps forced close by the phone with these Logcat:
08-19 21:58:50.313 25858-25858/example.christopher.bd E/AndroidRuntime: FATAL EXCEPTION: main Process: example.christopher.bd, PID: 25858 java.lang.RuntimeException: Unable to start activity ComponentInfo{example.christopher.bd/example.christopher.bd.VIewGraph}: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference at com.jjoe64.graphview.series.DataPoint.(DataPoint.java:45) at example.christopher.bd.VIewGraph.onCreate(VIewGraph.java:48) at android.app.Activity.performCreate(Activity.java:7136) at android.app.Activity.performCreate(Activity.java:7127) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
activity to show the graph:
package example.christopher.bd;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.helper.DateAsXAxisLabelFormatter;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class VIewGraph extends AppCompatActivity {
LineGraphSeries<DataPoint> series;
DatabaseHelper mDatabaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_graph);
mDatabaseHelper = new DatabaseHelper(this);
String y;
Float z;
Date d1;
Cursor data = mDatabaseHelper.readEntry();
int rows = data.getCount();
data.moveToFirst();
GraphView graph = (GraphView) findViewById(R.id.graph11);
series = new LineGraphSeries<DataPoint>();
for(int i = 0; i <rows; i++){
data.moveToNext();
String x = data.getString(2);
y = data.getString(3);
z = Float.parseFloat(y);
Date date1 = null;
try {
date1 = new SimpleDateFormat("dd/MM/yyyy").parse(x);
} catch (Exception e) {
e.printStackTrace();
}
series.appendData(new DataPoint(date1, z), true, 25);
}
graph.addSeries(series);
graph.getGridLabelRenderer().setNumHorizontalLabels(3);
graph.getGridLabelRenderer().setHumanRounding(false);
}
}
Here is the code for databasehelper
package example.christopher.bd;
import android.app.DatePickerDialog;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.icu.util.Calendar;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class DatabaseHelper extends SQLiteOpenHelper{
private static final String TAG = "DatabaseHelper";
private static final String TABLE_NAME = "BodyData";
private static final String COL1 = "ID";
private static final String COL2 = "tdate";
private static final String COL2a = "ttime";
private static final String COL3 = "weight";
private static final String COL4 = "fat";
private static final String COL5 = "hydration";
private static final String COL6 = "muscle";
private static final String COL7 = "bone";
//private static final String COL8 = "time";
private TextView mDisplayDate;
private DatePickerDialog.OnDateSetListener mDateSetListener;
public DatabaseHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = " CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, tdate string, ttime string, weight float, fat float, hydration float, muscle float, bone float)";
//String createTable = " CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, tday integer, tmonth integer, tyear integer, weight float, fat float, hydration float, muscle float, bone float)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL(" DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String tdate, String ttime, String weight, String fat, String hydration, String muscle, String bone) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, tdate);
contentValues.put(COL2a, ttime);
contentValues.put(COL3, weight);
contentValues.put(COL4, fat);
contentValues.put(COL5, hydration);
contentValues.put(COL6, muscle);
contentValues.put(COL7, bone);
//contentValues.put(COL8, time);
long result = db.insert(TABLE_NAME,null ,contentValues);
if(result == -1)
return false;
else
return true;
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
Cursor data = db.rawQuery(query, null);
return data;
}
public void deleteAll()
{
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME,null,null);
db.execSQL("delete from "+ TABLE_NAME);
db.close();
}
public Cursor readEntry(){
SQLiteDatabase db = this.getWritableDatabase();
String[] allColumns = new String[]{
DatabaseHelper.COL1,
DatabaseHelper.COL2,
DatabaseHelper.COL2a,
DatabaseHelper.COL3,
DatabaseHelper.COL4,
DatabaseHelper.COL5,
DatabaseHelper.COL6,
DatabaseHelper.COL7,
};
Cursor c = db.query(DatabaseHelper.TABLE_NAME, allColumns, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
}
activity to log the data (date, weight etc)
package example.christopher.bd;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.icu.util.Calendar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
public class Logging extends AppCompatActivity {
private static final String TAG = "Logging";
DatabaseHelper mDatabaseHelper;
EditText editWeight, editFat, editHydration, editMuscle, editBone, editTime, editASD;
private Button button2;
private TextView mDisplayDate, mDisplayTime;
private DatePickerDialog.OnDateSetListener mDateSetListener;
private TimePickerDialog.OnTimeSetListener mTimeSetListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logging);
button2 = (Button) findViewById(R.id.button2);
mDisplayDate = (TextView) findViewById(R.id.tvDate);
mDatabaseHelper = new DatabaseHelper(this);
mDisplayTime = (TextView) findViewById(R.id.tvTime);
editWeight = (EditText) findViewById(R.id.editWeight);
editFat = (EditText) findViewById(R.id.editFat);
editHydration = (EditText) findViewById(R.id.editHydration);
editMuscle = (EditText) findViewById(R.id.editMuscle);
editBone = (EditText) findViewById(R.id.editBone);
mDisplayDate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(
Logging.this,
android.R.style.Theme_Holo_Light_Dialog_MinWidth,
mDateSetListener,
year,month,day);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
}
});
mDateSetListener = new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker datePicker, int year, int month, int day) {
month = month + 1;
Log.d(TAG, "onDateSet: mm/dd/yyyy: " + day + "/" + month + "/" + year);
String date = day + "/" + month + "/" + year;
mDisplayDate.setText(date);
}
};
mDisplayTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Calendar mTime = Calendar.getInstance();
int mHour = mTime.get(Calendar.HOUR_OF_DAY);
int mMinute = mTime.get(Calendar.MINUTE);
TimePickerDialog timePickerDialog = new TimePickerDialog(Logging.this,
new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
mDisplayTime.setText(hourOfDay + ":" + minute);
}
}, mHour, mMinute, true);
timePickerDialog.show();
}
});
LogData();
}
public void LogData(){
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean isInserted = mDatabaseHelper.addData(
mDisplayDate.getText().toString(),
mDisplayTime.getText().toString(),
editWeight.getText().toString(),
editFat.getText().toString(),
editHydration.getText().toString(),
editMuscle.getText().toString(),
editBone.getText().toString()
);
if (isInserted == true)
Toast.makeText(Logging.this, "Data Inserted", Toast.LENGTH_LONG).show();
else
Toast.makeText(Logging.this, "Data not Inserted", Toast.LENGTH_LONG).show();
}
});
}
}
Can anyone help me?
java.lang.NullPointerException: Attempt to invoke virtual method 'long
java.util.Date.getTime()' on a null object reference
means that you are calling/the code you are using is calling getTime() on a Date object that is null.
In more detail
Attempt to invoke virtual method 'long java.util.Date.getTime()' on a
null object reference at
com.jjoe64.graphview.series.DataPoint.(DataPoint.java:45) at
example.christopher.bd.VIewGraph.onCreate(VIewGraph.java:48)
means that this was initiated in VIewGraph.java on line 48.
Just above that there is a try-catch block to catch problems in parsing a date, but you don't check was the Date object non-null in the end. Any error is just ignored. You then feed this null Date object to series in series.appendData(new DataPoint(date1, z), true, 25);
A quick fix would be to change
try {
date1 = new SimpleDateFormat("dd/MM/yyyy").parse(x);
} catch (Exception e) {
e.printStackTrace();
}
series.appendData(new DataPoint(date1, z), true, 25);
..to...
try {
date1 = new SimpleDateFormat("dd/MM/yyyy").parse(x);
series.appendData(new DataPoint(date1, z), true, 25);
} catch (Exception e) {
e.printStackTrace();
}
It looks like you have made changes to the columns of the table (COL2a instead of COL8) If this is the case, did you uninstall the app from the device/emulator where you test it? If not you must.
The table schema dos not change every time you make changes in onCreate() of DatabaseHelper class. onCreate() is executed when the db does not exist.
Now a logical problem:
In your activity's onCreate() you execute:
data.moveToFirst();
So the cursor data is pointing at its 1st row.
Then in the 1st line of the for loop you execute:
data.moveToNext();
So the cursor data is pointing at its 2nd row (if there is a 2nd row).
So you miss the 1st row's data for sure.
But since the number of iterations is equal as the number of rows the last iteration will fetch null data!
Suggestion move data.moveToNext(); as the last statement of the for loop.
My app is supposed to save data in a database then display it in a listView.
Problem is that the listView doesn't display anything.
Looking through the error log it seems to say that it has problem saving the data.
Thanks in advance
DBAdapter
package se.welovecode.wdmmg;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
private static final String TAG = "DBAdapter"; //used for logging database version changes
// Field Names:
public static final String KEY_ROWID = "_id";
public static final String KEY_TRANSACTIONS = "transactions";
public static final String KEY_ITEM = "item";
public static final String KEY_SUM = "sum";
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_TRANSACTIONS, KEY_ITEM, KEY_SUM,};
// Column Numbers for each Field Name:
public static final int COL_ROWID = 0;
public static final int COL_TRANSACTIONS = 1;
public static final int COL_ITEM = 2;
public static final int COL_SUM = 3;
// DataBase info:
public static final String DATABASE_NAME = "db";
public static final String DATABASE_TABLE = "mainTransactions";
public static final int DATABASE_VERSION = 1; // The version number must be incremented each time a change to DB structure occurs.
//SQL statement to create database
private static final String DATABASE_CREATE_SQL =
"CREATE TABLE " + DATABASE_TABLE
+ " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_TRANSACTIONS + " TEXT NOT NULL, "
+ KEY_ITEM + " TEXT NOT NULL, "
+ KEY_SUM + " INTEGER"
+ ");";
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx) {
Context context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to be inserted into the database.
public long insertRow(String transactions) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TRANSACTIONS, transactions);
// Insert the data into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
public long insertRow2(String item) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ITEM, item);
// Insert the data into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
public long insertRow3(int sum) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_SUM, sum);
// 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();
}
// 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 transaction, String item, String sum) {
String where = KEY_ROWID + "=" + rowId;
ContentValues newValues = new ContentValues();
newValues.put(KEY_TRANSACTIONS, transaction);
newValues.put(KEY_ITEM, item);
newValues.put(KEY_SUM, sum);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase _db) {
_db.execSQL(DATABASE_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
MainActivity
package se.welovecode.wdmmg;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
DBAdapter myDB;
TextView Balance;
Double value;
ListView lwTransactions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Balance = (TextView) findViewById(R.id.tvBalance);
refreshSum();
openDB();
populateListView();
}
#Override
protected void onResume() {
super.onResume();
refreshSum();
populateListView();
}
protected void onDestroy(){
super.onDestroy();
closeDb();
}
private void openDB(){
myDB = new DBAdapter(this);
myDB.open();
}
private void closeDb(){
myDB.close();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_add:
Intent intent = new Intent(MainActivity.this, AddTransaction.class);
startActivity(intent);
default:
return super.onOptionsItemSelected(item);
}
}
private void refreshSum(){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
value = (double) prefs.getFloat("KEY", 0f);
Balance.setText(value.toString());
}
private void populateListView(){
Cursor cursor = myDB.getAllRows();
String[] fromFieldNames = new String[]{DBAdapter.KEY_ROWID, DBAdapter.KEY_TRANSACTIONS, DBAdapter.KEY_ITEM, DBAdapter.KEY_SUM,};
int[] toViewIDs = new int[] {R.id.textViewRowID, R.id.textViewStore, R.id.textViewService, R.id.textViewCost};
SimpleCursorAdapter myCursorAdapter;
myCursorAdapter = new SimpleCursorAdapter(getBaseContext(),R.layout.item_layout, cursor, fromFieldNames,toViewIDs,0);
lwTransactions = (ListView) findViewById(R.id.lwTransactions);
lwTransactions.setAdapter(myCursorAdapter);
}
}
Errorlog
06-12 17:33:38.383 29168-29168/se.welovecode.wdmmg E/SQLiteLog﹕ (1299) abort at 7 in [INSERT INTO mainTransactions(transactions) VALUES (?)]: NOT NULL constraint failed: mainTransactions.item
06-12 17:33:38.383 29168-29168/se.welovecode.wdmmg E/SQLiteDatabase﹕ Error inserting transactions=hsns
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: mainTransactions.item (code 1299)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:952)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1595)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1465)
at se.welovecode.wdmmg.DBAdapter.insertRow(DBAdapter.java:68)
at se.welovecode.wdmmg.AddTransaction.onClick_AddTransaction(AddTransaction.java:55)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4268)
at android.view.View.performClick(View.java:5217)
at android.view.View$PerformClick.run(View.java:20983)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
06-12 17:33:38.393 29168-29168/se.welovecode.wdmmg E/SQLiteLog﹕ (1299) abort at 6 in [INSERT INTO mainTransactions(item) VALUES (?)]: NOT NULL constraint failed: mainTransactions.transactions
06-12 17:33:38.393 29168-29168/se.welovecode.wdmmg E/SQLiteDatabase﹕ Error inserting item=bsb
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: mainTransactions.transactions (code 1299)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:952)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1595)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1465)
at se.welovecode.wdmmg.DBAdapter.insertRow2(DBAdapter.java:76)
at se.welovecode.wdmmg.AddTransaction.onClick_AddTransaction(AddTransaction.java:58)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4268)
at android.view.View.performClick(View.java:5217)
at android.view.View$PerformClick.run(View.java:20983)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
06-12 17:33:38.393 29168-29168/se.welovecode.wdmmg E/SQLiteLog﹕ (1299) abort at 6 in [INSERT INTO mainTransactions(sum) VALUES (?)]: NOT NULL constraint failed: mainTransactions.transactions
06-12 17:33:38.393 29168-29168/se.welovecode.wdmmg E/SQLiteDatabase﹕ Error inserting sum=120
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: mainTransactions.transactions (code 1299)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:952)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1595)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1465)
at se.welovecode.wdmmg.DBAdapter.insertRow3(DBAdapter.java:83)
at se.welovecode.wdmmg.AddTransaction.onClick_AddTransaction(AddTransaction.java:61)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4268)
at android.view.View.performClick(View.java:5217)
at android.view.View$PerformClick.run(View.java:20983)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
U got KEY_TRANSACTIONS TEXT NOT NULL and KEY_ITEM TEXT NOT NULL
but u pass in insertRow only KEY_TRANSACTION but u need to put KEY_ITEM also
public long insertRow(String transactions) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TRANSACTIONS, transactions);
initialValues.put(KEY_ITEM, "some key item");
// Insert the data into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
or remove NOT NULL from your KEY_ITEM column constraints
I'm trying to code a simple randomizer app. I had the randomizer button working, but then I changed some code (which I thought was irrelevant to the randomizer button) and it started crashing and getting the "CursorIndexOutOfBoundsException Index 0 requested, with a size of 0" error. I couldn't find any fixes to this that apply to my code. Can anyone help me fix this?
Here is my main class with the button:
package com.example.randomgamechooser;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainScreen extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
}
public void chooseGame (View view) {
GameList dbUtil = new GameList(this);
dbUtil.open();
String string = dbUtil.getRandomEntry();
//TextView textView = new TextView(this);
TextView textView = (TextView) findViewById(R.id.chosenbox);
textView.setTextSize(40);
textView.setText(string);
//setContentView (textView);
dbUtil.close();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_screen, menu);
return true;
}
//starts the Game Selection activity
public void openGames (View view) {
Intent intent = new Intent(this, GameSelction.class);
startActivity(intent);
}
}
Here is the GameList class:
package com.example.randomgamechooser;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.Random;
public class GameList {
private static final String TAG = "GameList";
//database name
private static final String DATABASE_NAME = "game_list";
//database version
private static final int DATABASE_VERSION = 1;
//table name
private static final String DATABASE_TABLE = "game_list";
//table columns
public static final String KEY_NAME = "name";
public static final String KEY_GENRE = "genre";
public static final String KEY_ROWID = "_id";
//database creation sql statement
private static final String CREATE_GAME_TABLE =
"create table " + DATABASE_TABLE + " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_NAME +" text not null, " + KEY_GENRE + " text not null);";
//Context
private final Context mCtx;
private DatabaseHelper mDbHelper;
private static SQLiteDatabase mDb;
//Inner private class. Database Helper class for creating and updating database.
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// onCreate method is called for the 1st time when database doesn't exists.
#Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "Creating DataBase: " + CREATE_GAME_TABLE);
db.execSQL(CREATE_GAME_TABLE);
}
//onUpgrade method is called when database version changes.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion);
}
}
//Constructor - takes the context to allow the database to be opened/created
//#param ctx the Context within which to work
public GameList(Context ctx) {
this.mCtx = ctx;
}
//This method is used for creating/opening connection
//#return instance of GameList
//#throws SQLException
public GameList open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
//This method is used for closing the connection.
public void close() {
mDbHelper.close();
}
//This method is used to create/insert new game.
//#param name
// #param genre
// #return long
public long createGame(String name, String genre) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_GENRE, genre);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}
// This method will delete game.
// #param rowId
// #return boolean
public static boolean deleteGame(long rowId) {
return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
// This method will return Cursor holding all the games.
// #return Cursor
public Cursor fetchAllGames() {
return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_GENRE}, null, null, null, null, null);
}
// This method will return Cursor holding the specific game.
// #param id
// #return Cursor
// #throws SQLException
public Cursor fetchGame(long id) throws SQLException {
Cursor mCursor =
mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_GENRE}, KEY_ROWID + "=" + id, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public int getAllEntries()
{
Cursor cursor = mDb.rawQuery(
"SELECT COUNT(name) FROM game_list", null);
if(cursor.moveToFirst()) {
return cursor.getInt(0);
}
return cursor.getInt(0);
}
public String getRandomEntry()
{
//id = getAllEntries();
Random random = new Random();
int rand = random.nextInt(getAllEntries());
if(rand == 0)
++rand;
Cursor cursor = mDb.rawQuery(
"SELECT name FROM game_list WHERE _id = " + rand, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return cursor.getString(0);
}
// This method will update game.
// #param id
// #param name
// #param standard
// #return boolean
public boolean updateGame(int id, String name, String standard) {
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_GENRE, standard);
return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + id, null) > 0;
}
}
And here is the cause part of the error log:
08-01 13:03:38.325: E/AndroidRuntime(278): Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
08-01 13:03:38.325: E/AndroidRuntime(278): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
08-01 13:03:38.325: E/AndroidRuntime(278): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
08-01 13:03:38.325: E/AndroidRuntime(278): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
08-01 13:03:38.325: E/AndroidRuntime(278): at com.example.randomgamechooser.GameList.getRandomEntry(GameList.java:153)
EDIT: Here is the ListView class:
public class GameSelction extends Activity
{
GameList dbUtil = new GameList(this);
private SimpleCursorAdapter dataAdapter;
//#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_selction);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
getActionBar() .setDisplayHomeAsUpEnabled(true);
}
displayListView();
}
private void displayListView() {
dbUtil.open();
Cursor cursor = dbUtil.fetchAllGames();
// The desired columns to be bound
String[] columns = new String[] {
GameList.KEY_NAME,
GameList.KEY_GENRE,
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.name,
R.id.genre,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.game_info,
cursor,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long rowId) {
// Get the cursor, positioned to the corresponding row in the result set
//Cursor cursor = (Cursor) listView.getItemAtPosition(position);
GameList.deleteGame(rowId);
}
});
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
//opens the AddGame activity
public void openAddgame (View view) {
Intent intent = new Intent(this, AddGame.class);
startActivity(intent);
}
public void buttonBackMain (View view) {
Intent intent = new Intent(this, MainScreen.class);
startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.game_selction, menu);
return true;
}
}
The problem is in this section of code:
public String getRandomEntry()
{
//...
Cursor cursor = mDb.rawQuery(
"SELECT name FROM game_list WHERE _id = " + rand, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return cursor.getString(0);
}
What you ended up doing was saying return cursor.getString(0); whether or not there were results in the cursor. So remove the second occurrence, and it should work.
EDIT:
After scanning your code, it seems that the only place you use this method is to fill a TextView. In that case you can use this as a chance to communicate a visual error message to yourself or your users, or do anything else with it that you want. So I would suggest using something to the effect of
public String getRandomEntry()
{
//EDIT: This will make your random generator less biased toward 1.
Random random = new Random();
int rand = random.nextInt(getAllEntries()) + 1;
/* Assuming your _id starts at 1 and auto-increments, this will
* start the random digits at 1 and go as high as your highest _id */
Cursor cursor = mDb.rawQuery(
"SELECT name FROM game_list WHERE _id = " + rand, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return "There were no games in the database to choose from.";
}
EDIT:
Try using this. Notice that this code uses mDb.query(), which you used elsewhere. I'm not sure why rawQuery() would refuse to work, but maybe this will do it.
public String getRandomEntry()
{
Random random = new Random();
int rand = random.nextInt(getAllEntries()) + 1;
Cursor cursor = mDb.query(true, DATABASE_TABLE, new String[] {KEY_NAME},
KEY_ROWID + "=" + rand, null, null, null, null, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return "There were no games in the database to choose from.";
}
Based on the initial look, the SQLiteDatabase object represented by mDB appears to be empty, as that's what is throwing the error.
What the error is saying is that your code is requesting the item at index 0 (basically, the first item), but the size of your index is 0 (basically, there are no items in the index).
Somewhere along the line, your database object is either emptied or not populated. To test this, run your fetchAllGames method and verify the contents of the index.
Didn't read the whole code, but I guess the problem is that, you are trying to get first element, from empty database.
Just check if the size of cursor greater than 0, before getting element.
if (cursor.getColumnCount() > 0)
return cursor.getString(0);
else return "no items";
i got nullPointerException when trying to fetch some data from database with rawQuery.
Here's an error:
03-11 18:09:01.522: E/AndroidRuntime(2057): Uncaught handler: thread
main exiting due to uncaught exception 03-11 18:09:01.532:
E/AndroidRuntime(2057): java.lang.NullPointerException 03-11
18:09:01.532: E/AndroidRuntime(2057): at
com.math.scan.FormulaModel.setFormulaList(FormulaModel.java:27)
Look at my code:
DbHelper
package com.math.scan;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import android.content.Context;
import android.content.res.AssetManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DbHelper extends SQLiteOpenHelper{
public static final String TABLE_NAME = "formulas";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_UNKNOWN = "unknown";
public static final String COLUMN_FORMULA = "formula";
public static final String COLUMN_CTG = "ctg";
private static final String DB_NAME = "formulas.db";
private static int DB_VERSION = 1;
private static final String DB_CREATE = "CREATE TABLE "+TABLE_NAME+
"("+COLUMN_ID+" integer primary key autoincrement,"
+COLUMN_UNKNOWN+" text not null,"
+COLUMN_FORMULA+" text not null,"
+COLUMN_CTG+" text not null );";
public Context mCtx;
public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.mCtx = context;
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DB_CREATE);
// reading formulas
AssetManager asset = mCtx.getAssets();
try {
InputStream input = asset.open("formulas");
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
String content = new String(buffer);
Scanner scan = new Scanner(content);
String current;
String[] f = new String[2];
String[] formula = new String[2];
while(scan.hasNextLine()) {
current = scan.nextLine();
// get category
f = current.split("!!");
formula = f[1].split(" = ");
database.execSQL("INSERT INTO `formulas` VALUES (NULL, '"+formula[0]+"', '"+formula[1]+"', '"+f[0]+"');");
Log.d("DB", "INSERT INTO `formulas` VALUES (NULL, '"+formula[0]+"', '"+formula[1]+"', '"+f[0]+"');");
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DbHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
FormulaModel
package com.math.scan;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class FormulaModel {
private SQLiteDatabase database;
private DbHelper dbHelper;
public FormulaModel(Context context) {
dbHelper = new DbHelper(context);
}
public void open() throws SQLException {
dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public void setFormulaList(String ctg) {
open();
// app stops working here
Cursor cursor = database.rawQuery("SELECT unknown, formula FROM formulas WHERE ctg = '"+ctg+"'", null);
int results = cursor.getCount();
cursor.moveToFirst();
Global.FormuleResult = new String[results];
Global.FormuleTable = new String[results];
for(int i = 0; i < results; i++) {
Global.FormuleTable[i] = cursor.getString(1);
Global.FormuleResult[i] = cursor.getString(0);
}
close();
}
}
This is activity, where I call setFormulaList() method in FormulaModel class.
package com.math.scan;
import net.sourceforge.jeval.EvaluationException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class ProblemActivity extends Activity {
private EditText prob;
private Button solve;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.problem);
// text field
prob = (EditText) findViewById(R.id.problem);
// confirm btn
solve = (Button) findViewById(R.id.solve);
// check if confirm button was pressed
solve.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get text from the field
String problem = prob.getText().toString();
// check if expression is not empty
if(problem.length() == 0) {
// string is empty!
Toast.makeText(ProblemActivity.this, getString(R.string.empty_field), Toast.LENGTH_SHORT).show();
} else {
FormulaModel f = new FormulaModel(ProblemActivity.this);
f.setFormulaList("mech");
pears.doMagic(problem);
try {
String str = Global.eval.getVariableValue(Global.UNKNOWN);
TextView answ = (TextView) findViewById(R.id.answer);
answ.setText(getString(R.string.prob_answ) + str);
} catch (EvaluationException e) {
Toast.makeText(ProblemActivity.this, getString(R.string.prob_error), Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
I can't figure out what is wrong here.
Any ideas?
You have to set your database variable in open():
database = dbHelper.getWritableDatabase();