安卓MPAndroidChart--LineChart实现动态曲线(传感器通信)
程序员文章站
2022-03-19 16:59:20
目录一、前言二、效果图三、代码实现3.1 定义变量3.2 初始化表格3.3 开启线程,开始与传感器通信三、总结一、前言本次记录的是一年前做的项目,与烟雾、火焰传感器模块通信,记录数据,并显示实时动态曲线。对于参加比赛来说,很多时候单靠软件是很不现实的。因此软件与硬件的通信显得十分重要,软硬件联动往往能在一些比赛中获得更好好的成绩。本次功能基于蓝牙模块实现与传感器通信,获取数据之后利用MPAndroidChart–LineChart实现各指数的实时动态曲线图。二、效果图以上是我实现的效果图,红色曲线...
一、前言
本次记录的是一年前做的项目,与烟雾、火焰传感器模块通信,记录数据,并显示实时动态曲线。对于参加比赛来说,很多时候单靠软件是很不现实的。因此软件与硬件的通信显得十分重要,软硬件联动往往能在一些比赛中获得更好好的成绩。本次功能基于蓝牙模块实现与传感器通信,获取数据之后利用MPAndroidChart–LineChart实现各指数的实时动态曲线图。
二、效果图
以上是我实现的效果图,红色曲线表示火焰指数变化,黄色曲线表示烟雾指数的实时变化。
三、代码实现
3.1 定义变量
private boolean isodd = true; //控制数据读取
private boolean isopen = true; //控制警报
public BluetoothSocket msocket = null;
private LineChart lineChart_sensor;
private XAxis xAxis;
private YAxis yAxis_left, yAxis_right;
Legend legend;
LineData lineData;
//点与数据集合
List<Float> flamelists = new ArrayList<> ();
List<Float> smoglists = new ArrayList<> ();
List<Entry> entries_flame = new ArrayList<> ();
List<Entry> entries_smog = new ArrayList<> ();
LineDataSet lineDataSet_flame = new LineDataSet (entries_flame, "火焰指数");
LineDataSet lineDataSet_smog = new LineDataSet (entries_smog, "烟雾指数");
//创建随机数
private Random random = new Random ();
private DecimalFormat decimalFormat = new DecimalFormat ("#.000");
private String string_smog = "正常", string_flame = "正常", string_isnormal = "正常";
private boolean isadd=false;//判断奇偶,控制数据传输
3.2 初始化表格
/**
* 初始化表格
*/
private void initChart() {
lineChart_sensor = findViewById (R.id.lc_sensor);
lineChart_sensor.setDrawBorders (true);
xAxis = lineChart_sensor.getXAxis ();
yAxis_left = lineChart_sensor.getAxisLeft ();
yAxis_right = lineChart_sensor.getAxisRight ();
legend = lineChart_sensor.getLegend ();
lineData = new LineData ();
lineChart_sensor.setData (lineData);
//设置图表基本属性
setChartBasicAttr (lineChart_sensor);
//设置xy轴
setXYAxis (lineChart_sensor, xAxis, yAxis_left, yAxis_right);
//添加线条
initLine ();
//设置图例
createLegend (legend);
}
/**
* 设置图表基本属性
*/
void setChartBasicAttr(LineChart mlineChart) {
mlineChart.setDrawGridBackground (false);//是否展示网格线
mlineChart.setDrawBorders (true);//显示边界
mlineChart.setDragEnabled (true);//可拖动
mlineChart.setScaleEnabled (true);//可缩放
mlineChart.setTouchEnabled (true);//可触摸
//设置动画效果
mlineChart.animateX (1500);
}
/**
* 设置X、Y轴
*/
private void setXYAxis(LineChart mlineChart_sensor, XAxis mxAxis, YAxis myAxis_left, YAxis myAxis_right) {
mxAxis.setPosition (XAxis.XAxisPosition.BOTTOM);//x轴设置f显示在底部
mxAxis.setAxisMinimum (0f); // 设置X轴的最小值
mxAxis.setAxisMaximum (20); // 设置X轴的最大值
mxAxis.setLabelCount (30, false); // 设置X轴的刻度数量,第二个参数表示是否平均分配
mxAxis.setGranularity (1f); // 设置X轴坐标之间的最小间隔
mlineChart_sensor.setVisibleXRangeMaximum (5);//最多在x轴上显示的总量
myAxis_left.setAxisMinimum (0f);
myAxis_right.setAxisMinimum (0f);
myAxis_left.setAxisMaximum (1f);
myAxis_right.setAxisMaximum (1f);
myAxis_left.setLabelCount (1000);
myAxis_left.setGranularity (0.001f);//设置x轴坐标之间的最小间隔
myAxis_right.setLabelCount (1000);
myAxis_right.setGranularity (0.001f);
mlineChart_sensor.setVisibleYRangeMaximum (30, YAxis.AxisDependency.LEFT);
mlineChart_sensor.setVisibleYRangeMaximum (30, YAxis.AxisDependency.RIGHT);
myAxis_right.setEnabled (false);
}
/**
* 设置图例
*/
private void createLegend(Legend mlegend) {
mlegend.setForm (Legend.LegendForm.LINE);
mlegend.setTextSize (12f);
//显示位置
mlegend.setVerticalAlignment (Legend.LegendVerticalAlignment.BOTTOM);
mlegend.setHorizontalAlignment (Legend.LegendHorizontalAlignment.LEFT);
mlegend.setOrientation (Legend.LegendOrientation.HORIZONTAL);
//是否绘制在图表里
mlegend.setDrawInside (false);
mlegend.setEnabled (true);
}
/**
*初始化线条
*/
void initLine() {
createLine (flamelists, entries_flame, lineDataSet_flame, getResources ().getColor (R.color.red_700), lineData, lineChart_sensor);
createLine (smoglists, entries_smog, lineDataSet_smog, getResources ().getColor (R.color.yellow_700), lineData, lineChart_sensor);
for (int i = 0; i < lineData.getDataSetCount (); i++) {
lineChart_sensor.getLineData ().getDataSets ().get (i).setVisible (true); //
}
}
/**
* 功能:动态创建一条曲线
*/
private void createLine(List<Float> datalist, List<Entry> entries, LineDataSet mlineDataSet, int color, LineData mlineData, LineChart mlineChart) {
for (int i = 0; i < datalist.size (); i++) {
Entry entry = new Entry (i, datalist.get (i));
entries.add (entry);
}
//初始化线条
initLineDataSet (mlineDataSet, color, LineDataSet.Mode.CUBIC_BEZIER);
if (mlineData == null) {
mlineData = new LineData ();
mlineData.addDataSet (mlineDataSet);
mlineChart.setData (mlineData);
} else {
mlineChart.getLineData ().addDataSet (mlineDataSet);
}
mlineChart.invalidate ();
}
3.3 开启线程,开始与传感器通信
这里在handler我没使用实际数据,使用的是随机数模拟数据。
//对话框打开蓝牙
if (!bluetoothAdapter.isEnabled ()) {
Intent intent = new Intent (BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult (intent, RESULT_OK);
}
//作为客户端连接
try {
new ClientThread (BtMac).start ();
} catch (IOException e) {
e.printStackTrace ();
}
开启线程,进行通信。
private class ClientThread extends Thread {
private BluetoothDevice mdevice;
private InputStream is;
private Boolean isflame = true;
Method method;
public ClientThread(String adress) throws IOException {
mdevice = bluetoothAdapter.getRemoteDevice (adress);
Log.e ("ConnectThread: ", "连接线程");
}
@Override
public void run() {
// 关闭发现设备
Log.e ("run: ", "开启线程");
bluetoothAdapter.cancelDiscovery ();
try {
method = mdevice.getClass ().getMethod ("createRfcommSocket", new Class[]{int.class});
msocket = (BluetoothSocket) method.invoke (mdevice, 1);
} catch (Exception e) {
}
try {
msocket.connect ();
Log.e ("run: ", "连接成功");
is = msocket.getInputStream ();
if (is != null) {
//long currentTime = System.currentTimeMillis ();
byte[] bufferflame, buffersmog;
int count1, count2;
int ch;
while (true) {
count1 = 0;
count2 = 0;
bufferflame = new byte[1024];
buffersmog = new byte[1024];
Message msgflame = new Message ();
Message msgsmog = new Message ();
while ((ch = is.read ()) != '\n') {
if (ch == ',') {
isflame = false;
continue;
}
if (ch != -1 && isflame) {
bufferflame[count1] = (byte) ch;
count1++;
}
if (ch != -1 && !isflame) {
buffersmog[count2] = (byte) ch;
count2++;
}
}
isflame = true;
bufferflame[count1] = (byte) '\n';
count1++;
buffersmog[count2] = (byte) '\n';
count2++;
msgflame.obj = new String (bufferflame, 0, count1);
handler.sendMessage (msgflame);
sleep (100);
msgsmog.obj = new String (buffersmog, 0, count2);
handler.sendMessage (msgsmog);
}
}
} catch (IOException e) {
e.printStackTrace ();
} catch (InterruptedException e) {
e.printStackTrace ();
}
{
try {
msocket.close ();
Log.e ("run: ", "连接失败");
} catch (IOException e1) {
e1.printStackTrace ();
}
}
}
public void cancle() {
try {
msocket.close ();
} catch (IOException closeException) {
}
}
Handler handler = new Handler () {
@Override
public void handleMessage(Message msg) {
super.handleMessage (msg);
if (isodd) {
string_flame= (String) msg.obj;
if (isadd){
addLine1Data (getRandom (0.5f));
addLine2Data (getRandom (0.5f));}
isodd = false;
} else {
string_smog=(String) msg.obj;
if (isadd){
addLine1Data (getRandom (0.5f));
addLine2Data (getRandom (0.5f));}
isodd = true;
}
Log.e ("handleMessage: ", (String) msg.obj);
}
};
}
三、总结
现在来看我的这个代码确实是冗余了,虽然实现了效果。但是由于当初的知识还比较浅薄,由此写出的代码是十分凌乱的,今后需要跟进一步学习,不能光做UI,得学学Java或者安卓更加底层的原理才会有进步空间。
本文地址:https://blog.csdn.net/qq_44706002/article/details/110502782