3

I am creating an Android app that would save data in an SQLite database and then read from this same database. This is so that I wouldn't need to get the data online each time to a MySQL server. I connected it to an external database and extracted the data and tried to see if the data is being saved but the when I try to get the data from the SQLite database with the fuction getAllMonths it seems that it's empty


public class DatabaseHelper extends SQLiteOpenHelper {

    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "pm";


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

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE consommation( date TEXT UNIQUE, conso_eau NUMERIC , conso_elec NUMERIC )");
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS consommation");

        // Create tables again
        onCreate(db);
    }

    public void insertMonth(String date, double conso_eau, double conso_elec) {
        // get writable database as we want to write data
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        // `id` and `timestamp` will be inserted automatically.
        // no need to add them
        values.put("date", date);
        values.put("conso_eau", conso_eau);
      //  values.put("prix_eau", prix_eau);
        values.put("conso_elec", conso_elec);
       // values.put("prix_elec", prix_elec);
        // insert row
        db.insert("consommation", null, values);

        // close db connection
        db.close();

    }

    public ArrayList<Month> getAllMonths() {
        ArrayList<Month> months = new ArrayList<>();

        // Select All Query
        String selectQuery = "SELECT  * FROM consommation ORDER BY date DESC";

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

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Month m = new Month(cursor.getString(0), cursor.getFloat(1),cursor.getFloat(3));
                months.add(m);
            } while (cursor.moveToNext());
        }

        // close db connection
        db.close();

        // return notes list
        return months;
    }

    public void deleteAll() {
        SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL("delete from consommation");
        db.close();
    }
}

and for the class that gets the the data saves it and when i try to check it tells me that it's empty


public class historique extends AppCompatActivity {
    private String idc;
    private DatabaseHelper db;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


       if (idc != null) {
            if (!SharedPrefManager.getInstance(getApplicationContext()).getHisto()) {
                db.deleteAll();
                getthingy();


           }

        } else {
            Intent intent = new Intent(historique.this, LoginActivity.class);
            startActivity(intent);
            finish();
        }
    }

    public void getthingy() {

        String url = "http://192.168.1.3/pm/historique.php?con=%1$s";
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();
        RequestQueue queue = Volley.newRequestQueue(this);
        String uri = String.format(url, 1);
        JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, uri, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            if (response.getString("status").equals("success")) {

                                JSONObject dataResult = response.getJSONObject("result");
                                JSONArray jArr = (JSONArray) dataResult.getJSONArray("data");
                                Log.d("hani",jArr+"working...");
                                JSONArray innerObj;
                                for(int i = 0; i < jArr.length();i++) {
                                    innerObj = jArr.getJSONArray(i);
                                    Log.d("hani","working...");
                                    db.insertMonth(innerObj.getString(0), innerObj.getDouble(1),innerObj.getDouble(2));

                                }

                               SharedPrefManager.getInstance(getApplicationContext()).setHisto(true);


                                progressDialog.hide();

                            } else {
                                Toast.makeText(getApplicationContext(), response.getString("result"), Toast.LENGTH_SHORT).show();
                                progressDialog.hide();
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d("Error.Response", error.getMessage());
                    }
                }
        );


        // Add the request to the RequestQueue.
        queue.add(getRequest);
    }

}

and so i added this function for test and called it Oncreate()

public void getdat()
    {
        ArrayList<Month> months = new ArrayList<>();
        months=db.getAllMonths();
        double tmp[] = new double[0];
        int i =0 ;
        ArrayList<BarEntry> datavals= new ArrayList<>();
        for(Month dat : months)
        {
            tmp[i] = dat.getConso_eau();
            Log.d("test_db",""+tmp[i]);
        }

    }

and i get this error

2019-06-07 08:30:53.577 7259-7259/com.example.pm_hs E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.pm_hs, PID: 7259
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.pm_hs/com.example.pm_hs.historique}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.example.pm_hs.DatabaseHelper.getAllMonths()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.example.pm_hs.DatabaseHelper.getAllMonths()' on a null object reference
        at com.example.pm_hs.historique.getdat(historique.java:106)
        at com.example.pm_hs.historique.onCreate(historique.java:47)
        at android.app.Activity.performCreate(Activity.java:6975)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

Mysql part seems to work fine as i tested it with postman and even the log statement shows that they're being extracted correctly from Mysql database

if someone can guide me through the right path as i am new in
thank you in advance

  • Are there any errors showing up in the logcat? – Michael Dodd Jun 07 '19 at 08:03
  • no no error unless i try to use ``` getAllMonths ``` then it says that there is a fatal exception attempt to call elements from a null array , the array where i try to save the return value of getAllMonths – Abdelhamid Sajid Jun 07 '19 at 08:17
  • Right, so could you post the stacktrace from that crash [as an edit to your question](https://stackoverflow.com/posts/56490291/edit)? – Michael Dodd Jun 07 '19 at 08:18
  • show how you use `getAllMonths` – Vladyslav Matviienko Jun 07 '19 at 08:25
  • I am not sure what is "idc" variable in the activity class but there is no assignment and it will be null. Now there is a conditon that if this is not null then there will be call to getch from server and then store the data to the local DB. I think as idc is null so the table is null due to idc not null condition i.e, if (idc != null). As a result there is empty data. Please make sure you are getting log Log.d("hani","working..."); which is inside the for loop to save server data to local table. – Hari N Jha Jun 07 '19 at 08:28
  • to get the error i talked about i added this function and called it in Oncreate() – Abdelhamid Sajid Jun 07 '19 at 08:32
  • i edited the question with how i call getAllMonths and the logcat – Abdelhamid Sajid Jun 07 '19 at 08:37
  • MikeT's answer is right. The error says `Attempt to invoke virtual method 'java.util.ArrayList com.example.pm_hs.DatabaseHelper.getAllMonths()' on a null object reference` - you didn't initialize `db` – Vladyslav Matviienko Jun 07 '19 at 08:51

1 Answers1

0

I believe that your issue is that you are not instantiating your DatabaseHelper db, you are just declaring it using

private DatabaseHelper db;

You need to instantiate it using

db = new DatabseHelper(this);

This should be done in the historique activity's onCreate method.

e.g. :-

public class historique extends AppCompatActivity {
    private String idc;
    private DatabaseHelper db;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        db = new DatabseHelper(this); //<<<<<<<<<<

        ........ rest of the code

However, considering the logic, the getThinggy method will never be called as the String variable idc will always be null as idc is declared but never instantiated/set. Thus in the following only the code in the else clause will run, that is the activity will always start the LoginActivity:-

   if (idc != null) {
        if (!SharedPrefManager.getInstance(getApplicationContext()).getHisto()) {
            db.deleteAll();
            getthingy();
       }

    } else {
        Intent intent = new Intent(historique.this, LoginActivity.class);
        startActivity(intent);
        finish();
    }

Re Edit

The null pointer exception is due to the db being null as per the first part of the answer. You need to instantiate db again as per the first part of this answer.

The message

Attempt to invoke virtual method 'java.util.ArrayList com.example.pm_hs.DatabaseHelper.getAllMonths()' on a null object reference

is saying that the getAllMonths method cannot be invoked because the pointer to the method (the DatabaseHelper object db according to the code you have supplied) is null.

MikeT
  • 51,415
  • 16
  • 49
  • 68
  • you were correct sir now it says that cursor window has 47 rows which is correct as for idc is called in the sharedprefManager that i made sorry i didn't disclose it ```public Boolean getHisto() { SharedPreferences sharedPreferences = ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); return sharedPreferences.getBoolean(HISTO, false); } ``` – Abdelhamid Sajid Jun 07 '19 at 08:51
  • @AbdelhamidSajid that's good. If you believe that this helped you solve the problem, could you please tick it as answering your question. – MikeT Jun 07 '19 at 08:53