如何使用 SQL 数据库保存从 Android 中的 Arduino 板接收的数据?
How to save data received from Arduino board in Android using SQL database?
目前我正在使用Arduino开发空气质量监测设备原型。该设备集成了三个气体传感器,可通过 HC-05 蓝牙模块将数据发送到我的 android 应用程序。我能够实时接收值并使用 textview 显示它,但不知道必须使用 SQL 数据库将数据保存在 android 设备本身中。我已经尝试了我在其他地方找到的所有教程,但它只在单击按钮时保存数据,但即使在尝试 buttonclick 方法时,应用程序也会崩溃(相反,我想在每次应用程序启动时在后台连续保存数据)。我是 android 开发的新手,请帮助我。
目前我需要保存(time/date、gps坐标、sensor1数据、sensor2数据、sensor3数据、整体空气质量)。
对不起,已经删除了SQL存储部分,这里是从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
}
}
}
};
好的,这是您可以改编的内容,它展示了如何创建数据库和 table(s),然后是如何插入数据以及如何检查数据是否存在。
几乎所有代码都在 SQLiteOpenHelp 子class 中,为方便起见,我将其称为 so46375780DBHelper
(您很可能会重命名它) 这应该在名为 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
}
}
简而言之,你有
- class 变量声明,
- 构造函数
- 覆盖方法
onCreate
和 onUpgrade
(两者都是必需的,但不一定需要执行任何操作)
- insertReadings 方法使用 SQLite
update
方法,该方法使用 column/value 对的 ContentValues 对象。如果插入成功,此方法将 return 值为 1 或更大(等于 _id 列的 rowid)。
- showAllDataToLog 只是为了检查数据是否存在。
接下来只需两步即可启用数据插入,这些步骤放在将要插入数据的class(或classes)中。
1 创建 SQLiteOpenHelper subclass 的实例,例如:-
so46375780DBHelper dbhlpr = new so46375780DBHelper(this);
2 使用 insertReading 方法插入一些数据,例如:-
// 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
);
注意!组成读数,您也可能希望改变方法以使用更多相关类型(请注意,SQlite 在类型方面非常灵活,几乎没有限制,如果值在任何类型的列中,您可以存储任何类型)。但是,当涉及到从 Cursor 中提取数据时,您应该选择最合适的 get?????
方法(下面仅使用 getString
方法,仅用于检查是否存在)。
以下代码会将数据列在日志中,它仅用于初步确认插入正在工作:-
// Check data (writes to the log)
dbhlpr.showAllDataToLog();
目前我正在使用Arduino开发空气质量监测设备原型。该设备集成了三个气体传感器,可通过 HC-05 蓝牙模块将数据发送到我的 android 应用程序。我能够实时接收值并使用 textview 显示它,但不知道必须使用 SQL 数据库将数据保存在 android 设备本身中。我已经尝试了我在其他地方找到的所有教程,但它只在单击按钮时保存数据,但即使在尝试 buttonclick 方法时,应用程序也会崩溃(相反,我想在每次应用程序启动时在后台连续保存数据)。我是 android 开发的新手,请帮助我。
目前我需要保存(time/date、gps坐标、sensor1数据、sensor2数据、sensor3数据、整体空气质量)。
对不起,已经删除了SQL存储部分,这里是从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
}
}
}
};
好的,这是您可以改编的内容,它展示了如何创建数据库和 table(s),然后是如何插入数据以及如何检查数据是否存在。
几乎所有代码都在 SQLiteOpenHelp 子class 中,为方便起见,我将其称为 so46375780DBHelper
(您很可能会重命名它) 这应该在名为 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
}
}
简而言之,你有
- class 变量声明,
- 构造函数
- 覆盖方法
onCreate
和onUpgrade
(两者都是必需的,但不一定需要执行任何操作) - insertReadings 方法使用 SQLite
update
方法,该方法使用 column/value 对的 ContentValues 对象。如果插入成功,此方法将 return 值为 1 或更大(等于 _id 列的 rowid)。 - showAllDataToLog 只是为了检查数据是否存在。
接下来只需两步即可启用数据插入,这些步骤放在将要插入数据的class(或classes)中。
1 创建 SQLiteOpenHelper subclass 的实例,例如:-
so46375780DBHelper dbhlpr = new so46375780DBHelper(this);
2 使用 insertReading 方法插入一些数据,例如:-
// 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 );
注意!组成读数,您也可能希望改变方法以使用更多相关类型(请注意,SQlite 在类型方面非常灵活,几乎没有限制,如果值在任何类型的列中,您可以存储任何类型)。但是,当涉及到从 Cursor 中提取数据时,您应该选择最合适的 get?????
方法(下面仅使用 getString
方法,仅用于检查是否存在)。
以下代码会将数据列在日志中,它仅用于初步确认插入正在工作:-
// Check data (writes to the log)
dbhlpr.showAllDataToLog();