-2

I am trying to retrieve data from SQLite database using AndroidStudio 3.0.1 but getting the following exception. I have been searching for the Error but couldn't found a good solution. Here is My Code.

inserting Data to Database

public boolean insertCoins(int coins){
   SQLiteDatabase db=this.getReadableDatabase ();
    ContentValues values=new ContentValues ();
     values.put(Col1,coins);
    long result=db.insert(Table_Name,null,values);
    if (result != -1) {
        return true;
    } else {
        return false;
    }

}

The code is giving Error Here

public Cursor getData(){
Cursor res = this.getReadableDatabase ().rawQuery("select sum("+Col1+") from "+Table_Name+"",null);
return res;
}

here is the method id Plying_Window Class that is calling insertCoins method of Database_Helper

  public void insertCoins( ){
    Database_Helper  db=new Database_Helper ( this );
    boolean isInserted=db.insertCoins( 5 );
    if(isInserted){
        Toast.makeText ( Playing_Window.this, getString( R.string.c_add),Toast.LENGTH_LONG ).show ();}
}

here is the Levels Class that is calling getData method of Database_Helper .

public class Levels extends AppCompatActivity {
static int Easy_lvl_counter=0,Medium_lvl_counter=0,Hard_lvl_counter=0;
public  TextView display_coins;
int tot_coins   =coin;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_levels );
    Actions ();get ();
    set ();
}
void set(){
    int c=get();
    tot_coins=c;
    display_coins.setText ( String.valueOf ( c ) );

}
Button btn_level1,btn_level2,btn_level3,btn_level4,btn_level5,btn_level6,btn_level7,btn_level8,btn_level9,btn_level10,btn_mainMenu;
public void Actions(){
    display_coins=findViewById ( R.id.coins );

    btn_level1= findViewById ( R.id.btn_level1 );
    btn_level2=findViewById ( R.id.btn_level2 );
    btn_level3=findViewById ( R.id.btn_level3 );
    btn_level4=findViewById ( R.id.btn_level4 );
    btn_level5=findViewById ( R.id.btn_level5 );
    btn_level6=findViewById ( R.id.btn_level6 );
    btn_level7=findViewById ( R.id.btn_level7 );
    btn_level8=findViewById ( R.id.btn_level8 );
    btn_level9=findViewById ( R.id.btn_level9 );
    btn_level10=findViewById ( R.id.btn_level10 );
    btn_mainMenu=findViewById ( R.id.btn_mainMenu );
    btn_mainMenu.setOnClickListener ( new View.OnClickListener () {
        @Override
        public void onClick(View v) {
            finish ();
            Medium_lvl_counter=0;Easy_lvl_counter=0;Hard_lvl_counter=0;

        }
    } );

    btn_level1.setOnClickListener ( new View.OnClickListener () {
        @Override
        public void onClick(View v) {
            switch (Choice){
                case 1:{Easy_lvl_counter = 1; Medium_lvl_counter=0;Hard_lvl_counter=0;
                    if(tot_coins>=0)startActivity ( new Intent ( getApplicationContext (),Playing_Window.class ) );break;}

                case 2:{Medium_lvl_counter=1;Hard_lvl_counter=0;Easy_lvl_counter=0;
                    if(tot_coins>=50){startActivity ( new Intent ( getApplicationContext (),Playing_Window.class ) );}
                    else{Toast .makeText( Levels.this, R.string.txt_coins_short, Toast.LENGTH_SHORT).show();}break; }

                case 3:{Hard_lvl_counter=1;Easy_lvl_counter = 0; Medium_lvl_counter=0;
                    if(tot_coins>=100)startActivity ( new Intent ( getApplicationContext (),Playing_Window.class ) );
                    else{Toast .makeText( Levels.this,R.string.txt_coins_short, Toast.LENGTH_SHORT).show();}break; }

            }

        }
    } );............}
public int get(){
    Database_Helper dbHelper=new Database_Helper (Levels.this);
    Cursor cursor=dbHelper.getData ();
    if(cursor.getCount ()==0){return 0;}
    else{
        while(cursor.moveToNext ()){
            String db_coins=cursor.getString ( 0);
            if(coin  ==-1)coin=0;
            else coin=Integer.valueOf ( db_coins );
        }

    }
    return coin;
}
static int coin=0;

}

here is the playingWindow class

public class Playing_Window extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate ( savedInstanceState );
    setContentView ( R.layout.activity_playing__window );
    Actions ();
}
Levels obj_lev;
boolean timer_Count=false;
private EditText box1, box2 , box3, box4, box5, box6, box7, box8, box9, box10, box11, box12, box13, box14, box15, box16, box17, box18, box19    , box20, box21, box22, box23, box24, box25;
private AlertDialog.Builder builder;AlertDialog alertdialog;
private CountDownTimer timer;
void Actions() {
    obj_lev=new Levels ();
    builder = new AlertDialog.Builder(Playing_Window.this);
.
.
.
.
void dialogShow(){

    builder.setMessage ( getString( R.string.con_Text) );
    builder.setPositiveButton( R.string.txt_ok, new 
DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            dialogInterface.dismiss();
            Levels obj=new Levels ();obj.get ();
            finish ();
        }
    });
    alertdialog=builder.create();
    alertdialog.show();
}
void dialogShowIncomplete(){

    builder.setMessage ( "Fill all the Boxes Correctly ! " );
    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            dialogInterface.dismiss();
        }
    });
    alertdialog=builder.create();
    alertdialog.show();

}
.
.
.
public void insertCoins( ){
    Database_Helper  db=new Database_Helper ( this );
    boolean isInserted=db.insertCoins( 5 );
    if(isInserted){
        Toast.makeText ( Playing_Window.this, getString( 
R.string.c_add),Toast.LENGTH_LONG ).show ();}
}

}

Here is the Stack Trace for My Exception . Thanks for Your Time

Process: com.sudoku.jamshaid.sudoku, PID: 23032
                                                                        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.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:267)
                                                                            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
                                                                            at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
                                                                            at com.sudoku.jamshaid.sudoku.Database_Helper.getData(Database_Helper.java:45)
                                                                            at com.sudoku.jamshaid.sudoku.Levels.get(Levels.java:241)
                                                                            at com.sudoku.jamshaid.sudoku.Playing_Window$3.onClick(Playing_Window.java:2555)
                                                                            at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                            at android.os.Looper.loop(Looper.java:135)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5221)
                                                                            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:899)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
  • The Context passed to this class is null... Anyway, sqlite helpers aren't recommended anymore unless you really are comfortable with it https://developer.android.com/training/data-storage/room/index.html – OneCricketeer Feb 04 '18 at 17:05
  • 1
    @cricket_007 Thanks for your response. I couldn't get that as i am new to Android Development. Can you please elaborate that? –  Feb 04 '18 at 17:07
  • 1) Other libraries exist to ease SQLite development. Use them. 2) This class is not the problem. Don't focus on the line of the error, but how the code got there. In this case, you've not added `Levels` or `Playing_Window` to your question, so we cannot help you... Please [edit] your post to show a [mcve] – OneCricketeer Feb 04 '18 at 17:12
  • 1
    @cricket_007 the code is giving Error at getData() method in spite of insertCoins(). **Before** Levels.get() Stack Trace says at com.sudoku.jamshaid.sudoku.Database_Helper.getData(Database_Helper.java:45) –  Feb 04 '18 at 17:33
  • The fact that `insertCoins` is not in the error message, I assure you that it is not the issue you're asking about – OneCricketeer Feb 04 '18 at 17:39
  • 1
    @cricket_007 Updated the Question again by adding the get() method. Please take a look again –  Feb 04 '18 at 18:04
  • 1
    @cricket_007 added the required class –  Feb 04 '18 at 18:19
  • At any point did you do something along the lines of `Levels l = new Levels(); l.get();`? For example, in the playing window class that you're also not showing still? Because if so, that's never how you create an Activity in Android – OneCricketeer Feb 04 '18 at 18:37
  • 1
    @cricket_007 let me post that too –  Feb 04 '18 at 18:39
  • 1
    @cricket_007 it has been added. check the question –  Feb 04 '18 at 18:47

3 Answers3

0

Here is your code, every where you are using db i,e SQLiteDatabase.

At the time of insertCoins again you are creating SQliteDatabase reference.

 public boolean insertCoins(int coins){
   SQLiteDatabase db=this.getReadableDatabase ();

Use one globally SQLiteDatabase db;

Try this :

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL ( "create table " + Table_Name + " (ID integer   PRIMARY KEY AUTOINCREMENT," + Col1 + " INTEGER not null " + ")" );

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL ( "Drop table if exists "+Table_Name );
    onCreate ( db );
}
public boolean insertCoins(int coins){
    db=this.getReadableDatabase ();
    ContentValues values=new ContentValues ();
     values.put(Col1,coins);
    long result=db.insert(Table_Name,null,values);
    if (result != -1) {
        return true;
    } else {
        return false;
    }

}

Code for Getting data from Sqlite :

 private void setData() {

        Constants.cList = new ArrayList<LoadDataResult>();
        // Select All Query
        String selectQuery = "SELECT  * FROM " + Constants.TABLE_NAME;

        db = databaseHelper.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                LoadDataResult product = new LoadDataResult();
                product.setName(cursor.getString(1));
                product.setSku(cursor.getString(2));
                product.setUpc(cursor.getString(3));
                product.setAssoc_upc(cursor.getString(4));
                product.setPrice(cursor.getString(5));
                product.setDisplaySize(cursor.getString(6));
                product.setDisplaySizeYes(Integer.parseInt(String.valueOf(cursor.getInt(7))));
                product.setStatus(cursor.getString(8));
                Log.e("DATASQL",""+cursor.getString(3));

                // Adding contact to list
                Constants.cList.add(product);
            } while (cursor.moveToNext());
          //  utils.hideDialog();
        }

}

Try to use this, Change your getData() and try

public Cursor getData(){
    String selectQuery = "SELECT  * FROM " + Table_Name;
    Cursor res = this.getReadableDatabase().rawQuery(selectQuery,null);
    return res;
}
Abhishek kumar
  • 4,347
  • 8
  • 29
  • 44
0
obj_lev=new Levels ();
... 
Levels obj=new Levels ();obj.get ();

This is never how you start an Activity in Android. Your error is because an Activity is a Context object, and your database needs a Context. When you call new on the Activity, none of the Activity lifecycle is started (onCreate for example, is never executed), and its Context is never setup, so it's null, and passed into the database handler, which is where you actually ran into the issue when attempting to use it.

Even looking at the rest of the code, I'm not sure how you expected the buttons in the Level class to work, or the text views to be set when none of the methods in onCreate are called.

You need to actually start it.

Overall, your get() method will not work from the "playing window" because holding onto an instance of an Activity from another is just the wrong pattern in Android development.

What you need instead is a wrapper around a Context that holds a database

public class LevelDB {  // this is not an Activity 
    private Context mContext;
    private Database_Helper mDb;

    public LevelDB(Context c) {
        mContext = c;
        mDb = new Database_Helper(c);
    }

    public int get() {
        SQLiteDatabase db = mDb.getReadableDatabase();
        return -1; // TODO: query the database 
    } 
} 

And now you would do

LevelDB obj=new LevelDB (Playing_Window.this);
int value = obj.get ();

And you can do the exact same thing in the other Activities, by passing the correct Context.

For example

public  TextView display_coins;
LevelDB mDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_levels );
    display_coins = findViewById(...);
    mDb = new LevelDB (Levels.this);
    int value = mDb.get ();
    display_coins.setText(""+value);
}

The alternative approach is to use your current code, but with a static method instead that takes a Context

public static int get(Context c){
    Database_Helper dbHelper=new Database_Helper (c);
    Cursor cursor=dbHelper.getData ();

Other than that, I pointed at the Room library in the comments. Use it - it'll help you manage the database better (but it won't solve your error of using Activities incorrectly)

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • 1
    i am not starting an Activity. i am just creating a reference to **Levels** to access its **get()** method. –  Feb 04 '18 at 18:53
  • Okay, you don't need to start an Activity, but using `new` on a subclass of one is still wrong... Why can't you just get the database helper from the onClick method? What purpose does creating a Levels class give you? – OneCricketeer Feb 04 '18 at 18:59
  • 1
    Thanks.it helped me in solving the error. but following that, i am unable to set the value returned by the DB in textView named as **display_coins** in Activity **Levels**. Can you help me in resolvin that problem please? –  Feb 04 '18 at 20:52
  • Well, you cannot update that Levels Activity without actually starting it. And using static variables is not how you share values across Activities. I have added how you would set that value – OneCricketeer Feb 04 '18 at 23:03
  • 1
    Thanks for Your time and giving an Idea. I have resolve my Problem by When next Activity starts the previous one closed forcibly using **fininsh()** and when next one ends forcibly using **finishh** previous one start there through **startActivity method**. is that a correct way in android? using the static variables, i have been getting data across the classes while learning **java**. why that method isn't correct in Android? –  Feb 05 '18 at 05:08
  • You typically call finish **after** you startActivity (or don't finish at all if you want to go back to that Activity). Intents, SharedPreferences, or Databases are the correct ways to persist data in Android, and share across **Context** boundaries. You **can** have static variables within non-Android lifecycle classes. If you want to share messages upon events, you use an EventBus or BroadcastReceiver – OneCricketeer Feb 05 '18 at 16:40
-2

I think it's because you are using getReadableDatabase, you should use getWritableDatabase. If not that, then maybe Col1 doesn't exist/has nothing in it, or perhaps your database hasn't been created. It's a null pointer, shouldn't be too hard to figure out

  • The database isn't being written to, and that method will throw the same exception when the Context is not assigned, regardless of the column existing – OneCricketeer Feb 04 '18 at 17:07
  • @cricket_007 you are right. it is throwing the same exception While trying with getWriteblDatabase method –  Feb 04 '18 at 17:09
  • Data is being inserted successfully. i am facing that exception while trying to retrieve data from database –  Feb 04 '18 at 17:10
  • @Nancy you will need a writable database to call "insert coins" – OneCricketeer Feb 04 '18 at 17:13
  • @cricket_007 by changing database to write able i am still getting the same exception, –  Feb 04 '18 at 17:18
  • @Nancy that's a completely different error. 1) Fix the context 2) You **always** need a writable database to write 3) The error in the question is unrelated to the insertCoin method – OneCricketeer Feb 04 '18 at 17:22
  • @cricket_007 i have update the Question. related code has also been added. Please take a look again. Thanks –  Feb 04 '18 at 17:27