3

Currently i am developing Prototype of Air quality monitoring device using Arduino. The device integrated with three gas sensors that will send the the data over the HC-05 bluetooth module to my android app. I am able to receive the values in real time and display it using textview but have no idea on have to save the data in android device itself using SQL database. I have tried all tutorials that i found elsewhere but it only save data on a button click, but even when trying the buttonclick method the app crashes (instead i want to save the data continuously on the background,every time the app starts). I am very new to android development, please help me.

Currently i need to save (time/date, gps coordinate, sensor1 data, sensor2 data, sensor3 data, overall air quality).

I am sorry, already removed the SQL storing part, here the code for get real time data from Arduino.

//data received from Arduino as #data+data+data+~
    bluetoothIn = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == handlerState) { //if message is what we want
                String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
                recDataString.append(readMessage); //keep appending to string until ~
                int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line
                if (endOfLineIndex > 0) { // make sure there data before ~
                    String dataInPrint = recDataString.substring(0, endOfLineIndex);

                    if (recDataString.charAt(0) == '#') //if it starts with # we know it is what we are looking for
                    {

                        dataInPrint = dataInPrint.substring(1, dataInPrint.length() - 1); //remove the Hash tag symbol
                        StringTokenizer st = new StringTokenizer(dataInPrint,"+");
                        String sensor0 = st.nextToken();
                        String sensor1 = st.nextToken();
                        String sensor2 = st.nextToken();


                        showMq135.setText(sensor0);    //update the textviews with sensor values
                        showMq9.setText(sensor1);
                        showDust.setText(sensor2);


                        p1 = (ProgressBar) findViewById(R.id.progressBarMq135);
                        int p135 = Integer.parseInt(sensor0);
                        p1.setMax(100);
                        p1.setProgress(p135);




                        p2 = (ProgressBar) findViewById(R.id.progressBarMq9);
                        int p9 = Integer.parseInt(sensor1);
                        p2.setMax(100);
                        p2.setProgress(p9);




                        p3 = (ProgressBar) findViewById(R.id.progressBarDust);
                        int pDust = Integer.parseInt(sensor2);
                        p3.setMax(100);
                        p3.setProgress(pDust);




                        if (p135 >= 51 || p9 >= 51 || pDust >= 51) {

                            showAirQuality.setTextColor(Color.RED);
                            showAirQuality.setText("Hazardous/Very unhealthy");
                            sound.start();
                        }

                        else {
                            showAirQuality.setTextColor(Color.BLUE);
                            showAirQuality.setText("Normal/Intermediate");
                        }


                    }
                    recDataString.delete(0, recDataString.length());//clear all string data

                }
            }
        }
    };
2
  • I'd suggest that you include code for a Minimal, Complete and verifiable example. This should include, the error by the way of the relevant extract from the logcat, relavant code from the activity and the databasehelper (i.e. the class that is a subclass of SQLiteOpenHelper) or whatever other methods you use to create the database and if any the code you use to store the data. Commented Sep 23, 2017 at 3:54
  • Regarding SQL do you mean that you want to save the data in an SQLite database? If unsure then I'd suggest you read Appropriate Uses For SQLite, there is a useful checklist at the bottom. SQL itself is not a database management system rather it is a language used for accessing databases. e.g. SQLite uses SQL, MySQL uses SQL and so on. Commented Sep 23, 2017 at 4:05

1 Answer 1

2

Ok here's something that you could adapt, it shows how to create database and table(s) and then how to insert data and also a how to do a check check that the data exists.

Virtually all of the code is in the SQLiteOpenHelp subclass, which for my convenience I have called so46375780DBHelper (you would very likely rename this) this should be in a file named so46375780DBHelper.java :-

public class so46375780DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "airquality";
    public static final int DBVERSION = 1;
    public static final String READINGS_TBL = "air_readings";
    public static final String READINGID_COL = "_id";
    public static final String READINGTIMESTAMP_COL = "timestamp";
    public static final String READINGLOCATION_COL = "location";
    public static final String READINGSENSOR1_COL = "sensor1";
    public static final String READINGSENSOR2_COL = "sensor2";
    public static final String READINGSENSOR3_COL = "sensor3";
    public static final String READINGAIRQLTY_COL = "airquality";

    SQLiteDatabase db;

    // SQL to create the table
    String tblcrtsql = "CREATE TABLE " + READINGS_TBL + "(" +
            READINGID_COL + " INTEGER PRIMARY KEY, " + // unqiue identifier
            READINGTIMESTAMP_COL + " INTEGER, " +
            READINGLOCATION_COL + " TEXT, " +
            READINGSENSOR1_COL + " TEXT, " +
            READINGSENSOR2_COL + " TEXT, " +
            READINGSENSOR3_COL + " TEXT, " +
            READINGAIRQLTY_COL + " TEXT" +
            ")";

    // Database Helper Constructor
    so46375780DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        db = this.getWritableDatabase();    // Open the database
    }

    @Override
    // Called when Database is openbed when it doesn't already exist
    // ^^^^^^^^ IMPORTANT to note ^^^^^^^^
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(tblcrtsql); // Create the table(s)
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldversion, int newversio) {

    }

    public boolean insertReading(String location,
                                 String sensor1,
                                 String sensor2,
                                 String sensor3,
                                 String airquality) {
        ContentValues cv = new ContentValues();
        cv.put(READINGTIMESTAMP_COL,
                Long.toString(
                System.currentTimeMillis()
                )
        );
        cv.put(READINGLOCATION_COL,location);
        cv.put(READINGSENSOR1_COL,sensor1);
        cv.put(READINGSENSOR2_COL,sensor2);
        cv.put(READINGSENSOR3_COL,sensor3);
        cv.put(READINGAIRQLTY_COL,airquality);
        return (db.insert(READINGS_TBL,null,cv) < 1);
    }

    public void showAllDataToLog() {

        //get all rows eqv to SELECT * FROM air_readings;
        Cursor csr = db.query(READINGS_TBL,null,null,null,null,null,null);
        // Traverse the cursor
        while (csr.moveToNext()) {
            String rowinfo = "Row " +
                    csr.getPosition() +
                    " of " +
                    csr.getCount() + ".";
            for (int i=0; i < csr.getColumnCount();i++) {
                rowinfo = rowinfo +
                        "\n\t Column=" + csr.getColumnName(i) +
                        "\t Value=" + csr.getString(i);
            }
            Log.d("DBINFO",rowinfo);
        }
        csr.close(); // Should always close cursor when finished with them
    }
}

In brief you have the

  • class variable declarations,
  • the contructor
  • overidden methods onCreate and onUpgrade (both required, but not necessarily required to do anything)
  • insertReadings method that uses the SQLite update method, which utilises a ContentValues object for the column/value pairs. This method will return a value of 1 or greater (the rowid which equates to the _id column), if the insert was successful.
  • showAllDataToLog just there to check the data exists.

Next it's just a matter of 2 steps to enable insertion of data, these steps are placed in the class (or classes) where the data will be inserted.

  • 1 Create an instance of the SQLiteOpenHelper subclass e.g. :-

    so46375780DBHelper dbhlpr = new so46375780DBHelper(this);
    
  • 2 Use the insertReading method to insert some data e.g. :-

    // Insert a row
    dbhlpr.insertReading(
            "001,345",          //coords
            "76.5",             // sensor 1 reading
            "57.3",             // sensor 2 reading
            "12.6",             // sensor 2 reading
            "LOUSY"             // air quality
    );
    

Note! made up readings, also you may wish to alter the method to utilise more relevant types (note SQlite is extremely flexible with types, with few limitations you can store any type if value in any type of column). However, when it comes to extracting the data from a Cursor you should chose the most appropriate get????? method (below only the getString method is used which is Ok for just checking the existence).

The following code will list the data to the log, it is only intended for initial re-assurance that the inserts are working :-

    // Check data (writes to the log)
    dbhlpr.showAllDataToLog();
Sign up to request clarification or add additional context in comments.

2 Comments

It works perfectly, I struggle for make this work for over a month, you solved it within one hour. Seriously appreciate your help MikeT. You are my savior, i am only left with 3 months for complete my final year project.
@kampungboboi great to hear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.