安卓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或者安卓更加底层的原理才会有进步空间。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值