AChartEngine是一个很强大的图表引擎,我在上学的时候就接触过,并且利用它做了一个传感器的应用,想想现在也很久远了,今天就把这个app的源码贴出来供其他人研究这款引擎。

app的效果如下:

github项目地址:https://github.com/AlexZhuo/SensorMonitor

此APP的主要特性如下:

1、支持手机传感器数量探测,支持加速度,磁场,距离等传感器数据的实时获取

2、使用了一些github上的第三方控件来美化UI,

3、支持全屏显示

4、通过旧版的xUtils 2实现了数据库实时记录

5、通过POI来将数据库的数据导出为excel,方便以后分析。

AChartEngine根据事先准备好的数据进行绘图,也就是说是一帧一帧的进行绘制,如果我们想动态生成波浪图并让坐标轴随之移动其实也不难,只需要隔一段时间在旧数据上添加数据并刷新一下view即可。

想要在项目中使用这个图标引擎,AChartEngine的jar包的下载地址:

http://repository-achartengine.forge.cloudbees.com/snapshot/org/achartengine/achartengine/1.2.0/

注意版本,以后说不定还会出新版。

下面把控制绘图的代码贴一下,原理其实不是很复杂,github上有全部app的代码,如果你喜欢也可以在原来基础上帮我完善一下(学生时代第一个上线项目,想想还有点小激动)。

import java.util.List;import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.exception.DbException;
import com.situ.model.Accelerate_info;public class AccelActivity extends Activity{public SensorManager sensorManager;public Sensor accelSensor ;TextView xText ;TextView yText ;TextView zText ;TextView sumText;TextView danWei ;TextView title;private Vibrator vibrator;  SensorEventListener threeParamListener;SensorEventListener oneParamListener;SensorEventListener twoParamListener;Handler avgHandler;Thread avgThread;int sensor_id = 0;//图表相关private XYSeries series;private XYMultipleSeriesDataset mDataset;private GraphicalView chart;private XYMultipleSeriesRenderer renderer;private Context context;private int yMax = 20;//y轴最大值,根据不同传感器变化private int xMax = 100;//一屏显示测量次数@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_accel);sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);avgHandler = new AveHandler();//给控件实例化if(xText==null){findViews();}Intent intent = getIntent();avgThread = new Thread(runnable);//定期更新平均值的线程启动avgThread.start();//初始化各个监听器initListeners();switch (wtd) {case Sensor.TYPE_ACCELEROMETER:title.setText("加速度传感器");danWei.setText("N/M^2");accelSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(threeParamListener, accelSensor, sensorManager.SENSOR_DELAY_UI);yMax = 20;sensor_id = 1;break;default:break;}//初始化图表initChart("*0.5s", danWei.getText().toString(),0,xMax,0,yMax);}/*** 抓取view中文本控件的函数*/private void findViews(){xText = (TextView) findViewById(R.id.xAxis);yText = (TextView) findViewById(R.id.yAxis);zText = (TextView) findViewById(R.id.zAxis);sumText = (TextView) findViewById(R.id.sum);danWei = (TextView) findViewById(R.id.danWei);title = (TextView) findViewById(R.id.title);}/*** 初始化各类监听器*/private void initListeners() {threeParamListener = new SensorEventListener() {//有三个返回参数的监听器@Overridepublic void onSensorChanged(SensorEvent event) {// TODO Auto-generated method stubxText.setText(event.values[0]+""); yText.setText(event.values[1]+""); zText.setText(event.values[2]+""); double sum = threeDimenToOne(event.values[0], event.values[1], event.values[2]);giveAverage(sum);//将当前测量的结果写入buffer,然后定期求buffer里面的平均值,并显示}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {// TODO Auto-generated method stub}};}/*** 初始化图表*/private void initChart(String xTitle,String yTitle,int minX,int maxX,int minY,int maxY){//这里获得main界面上的布局,下面会把图表画在这个布局里面LinearLayout layout = (LinearLayout)findViewById(R.id.chart);//这个类用来放置曲线上的所有点,是一个点的集合,根据这些点画出曲线series = new XYSeries("历史曲线");//创建一个数据集的实例,这个数据集将被用来创建图表mDataset = new XYMultipleSeriesDataset();//将点集添加到这个数据集中mDataset.addSeries(series);//以下都是曲线的样式和属性等等的设置,renderer相当于一个用来给图表做渲染的句柄int lineColor = Color.BLACK;PointStyle style = PointStyle.CIRCLE;renderer = buildRenderer(lineColor, style, true);//设置好图表的样式setChartSettings(renderer, xTitle,yTitle, minX, maxX, //x轴最小最大值minY, maxY, //y轴最小最大值Color.BLACK, //坐标轴颜色Color.WHITE//标签颜色);//生成图表chart = ChartFactory.getLineChartView(this, mDataset, renderer);//将图表添加到布局中去layout.addView(chart, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();if(threeParamListener!=null){sensorManager.unregisterListener(threeParamListener);}if(oneParamListener!=null){sensorManager.unregisterListener(oneParamListener);}if(avgThread!=null)avgThread.interrupt();DbUtils db = DbUtils.create(getApplicationContext());//xUtils框架try {List<Accelerate_info> list = db.findAll(Selector.from(Accelerate_info.class).where("sensor", "=", sensor_id));//看看一共写入了数据库多少数据System.out.println("数量是"+list.size());} catch (DbException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 根据三个坐标向量求和向量的模* @param x* @param y* @param z* @return*/public static double threeDimenToOne(double x,double y,double z){return Math.sqrt(x*x+y*y+z*z);}public  int index = 0;//指示这段时间一共写入了多少个数据//在这里可以设置缓冲区的长度,用于求平均数double[] buffer = new double[500];//半秒钟最多放500个数public int INTERVAL = 500;//每半秒求一次平均值public double AVERAGE = 0;//存储平均值/*** 一个子线程,没隔固定时间计算这段时间的平均值,并给textView赋值*/Runnable runnable = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubSystem.out.println("线程已经启动");while(true){try {Thread.sleep(INTERVAL);//没隔固定时间求平均数} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();avgThread = new Thread(runnable);avgThread.start();}if(index!=0){double sum = 0;for (int i=0;i<index;i++) {sum+=buffer[i];}AVERAGE = sum/new Double(index);index=0;//让下标恢复}avgHandler.sendEmptyMessage(1);//提示handler更新ui}}};/*** 更新平均值的显示值*/public void setAverageView(){//更新textViewif(sumText==null)return;sumText.setText(AVERAGE+"");}/*** 每隔固定时间给平均值赋值,并且更新图表的操作* @author love fang**/class AveHandler extends Handler{@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsetAverageView();//显示平均值updateChart();//更新图表//把当前值存入数据库DbUtils db = DbUtils.create(getApplicationContext());Accelerate_info accelerate_info = new Accelerate_info(System.currentTimeMillis(), AVERAGE, sensor_id);try {db.save(accelerate_info);//将当前平均值存入数据库} catch (DbException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("保存失败");}}}/*** 接受当前传感器的测量值,存到缓存区中去,并将下标加一* @param data*/public void giveAverage(double data){buffer[index]=data;index++;}/***设置图表曲线样式**/protected XYMultipleSeriesRenderer buildRenderer(int color, PointStyle style, boolean fill) {XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();//设置图表中曲线本身的样式,包括颜色、点的大小以及线的粗细等XYSeriesRenderer r = new XYSeriesRenderer();r.setColor(color);r.setPointStyle(style);r.setFillPoints(fill);r.setLineWidth(2);//这是线宽renderer.addSeriesRenderer(r);return renderer;}/*** 初始化图表* @param renderer* @param xTitle* @param yTitle* @param xMin* @param xMax* @param yMin* @param yMax* @param axesColor* @param labelsColor*/protected void setChartSettings(XYMultipleSeriesRenderer renderer, String xTitle, String yTitle,double xMin, double xMax, double yMin, double yMax, int axesColor, int labelsColor) {//有关对图表的渲染可参看api文档renderer.setChartTitle(title.getText().toString());//设置标题renderer.setXAxisMin(xMin);//设置x轴的起始点renderer.setXAxisMax(xMax);//设置一屏有多少个点renderer.setYAxisMin(yMin);renderer.setYAxisMax(yMax);renderer.setBackgroundColor(Color.BLACK);renderer.setLabelsColor(Color.YELLOW);renderer.setAxesColor(axesColor);renderer.setLabelsColor(labelsColor);renderer.setShowGrid(true);renderer.setGridColor(Color.BLUE);//设置格子的颜色renderer.setXLabels(20);//没有什么卵用renderer.setYLabels(20);//把y轴刻度平均分成多少个renderer.setXTitle(xTitle);//x轴的标题renderer.setYTitle(yTitle);//y轴的标题renderer.setYLabelsAlign(Align.RIGHT);renderer.setPointSize((float) 2);renderer.setShowLegend(false);}int[] xv = new int[1000];//用来显示的数据double[] yv = new double[1000];private int addX = -1;private double addY = 0;/*** 更新图表的函数,其实就是重绘*/private void updateChart() {//设置好下一个需要增加的节点addY = AVERAGE;//需要增加的值//移除数据集中旧的点集mDataset.removeSeries(series);//判断当前点集中到底有多少点,因为屏幕总共只能容纳100个,所以当点数超过100时,长度永远是100//每一个新点坐标都后移一位series.add(addX++, addY);//最重要的一句话,以xy对的方式往里放值if(addX>100){//如果超出了屏幕边界,实现坐标轴自动移动的方法renderer.setXAxisMin(addX-100);//显示范围为100renderer.setXAxisMax(addX);}//重要:在数据集中添加新的点集mDataset.addSeries(series);//视图更新,没有这一步,曲线不会呈现动态//如果在非UI主线程中,需要调用postInvalidate(),具体参考apichart.invalidate();}
}

Android使用AChartEngine制作动态心电图效果相关推荐

  1. android led闪烁功能,如何在Android应用层中制作一个LED指示灯效果

    如何在Android应用层中制作一个LED指示灯效果 发布时间:2020-12-08 16:12:59 来源:亿速云 阅读:86 作者:Leah 本篇文章给大家分享的是有关如何在Android应用层中 ...

  2. 在Android Studio如何制作聊天气泡

    在Android Studio如何制作一个聊天气泡 最近在学习移动编程开发,利用Android Studio编写代码.作为初学者,多多少少会有点难.        在开发的过程中,遇到了很多的困难,而 ...

  3. 在android studio中制作九宫格图片

    本文介绍如何在android studio中制作一张九宫格图片. 1.选中准备进行处理的图片*.png,直接修改名为*.9.png.放入android studio 工程的drawable目录下.(. ...

  4. android通讯录效果,Android通讯录中的弹窗效果

    通讯录索引效果,网上很多了,我这里做个记录. 相信大家都体验过android通讯录中的弹窗效果.如图所示: android中提供了QuickContactBadge来实现这一效果.这里简单演示下. 理 ...

  5. Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...

  6. Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习...

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...

  7. ps怎么制作流体_ps相框制作教程:ps怎么制作相框效果

    ​​今天分享ps相框制作教程:ps怎么制作相框效果,平常看到很多人在秀朋友圈时候,能把照片填充一个相框,让照片瞬间高大上,ps相框制作教程:ps怎么制作相框效果给大家安排上,作为我的粉丝不用羡慕其他人 ...

  8. 使用jQuery制作手风琴效果.(转)

    http://www.cssrain.cn/article.asp?id=1369 使用jQuery制作手风琴效果 本例主要讲解如何利用jQuery创建一个简单的手风琴风格的竖向菜单,从易到难. 第一 ...

  9. 滤镜应用——制作彩虹效果

    滤镜应用--制作彩虹效果 原图: 效果图: 步骤: 1.打开素材图片,新建图层1,选择"矩形选框工具",在图层1上圈出一个矩形选区,选择"渐变工具",选择色谱线 ...

最新文章

  1. 编程大神竟“玩”出了不像 C 的 C 程序
  2. Swift - 给图片添加文字水印(图片上写文字,并可设置位置和样式)
  3. Redis:内存满了的解决方案
  4. 查询时要处理好各种异常情况
  5. Java CountDownLatch的两种常用场景
  6. Pixhawk代码分析-姿态解算篇A
  7. 基于Linux和MiniGUI的嵌入式系统软件开发指南(六)
  8. 【spark】示例:连接操作
  9. RESTFULL 03 rest-framework视图
  10. “混合云产业推进联盟”成立,ZStack实力助推
  11. Cocoscreator 3.01 ios平台Facebook登陆
  12. python自动生成加减法算术题
  13. Gnirehtet使用教程 —— 将电脑网络通过USB共享给Android 设备
  14. Python入门学习小记:100以内素数/质数之和
  15. os.path.dirname()用法
  16. 流行的软件测试工具介绍
  17. 关于 惯导及其相关领域的一些术语解释
  18. 分享如何有效的提升网站PV值
  19. 赵小楼《天道》深度解析(69)不要执著于豆豆和书,或寻找高人。更多的是要在意内容、内容、内容。你掌握之后,你也是高人
  20. 2023五一建模A题完整版本【原创首发】

热门文章

  1. 康耐视视觉库编程参考(1)Cognex.VisionPro.ToolGroup Namespace
  2. python实现整数因式分解
  3. HTML期末大作业~花店鲜花商城网站模板设计与实现(HTML+CSS+JavaScript)
  4. 大数据架构师必读:医药企业大数据应用案例
  5. 求最长公共子序列的空间优化。
  6. C语言经典递推算法之杨辉三角展开(详解)
  7. 如何解决Office365无法登录
  8. 序列到序列的网络seq2seq
  9. xavier,kaiming初始化中的fan_in,fan_out在卷积神经网络是什么意思
  10. 相片更换底色,蓝色变红色,红色变蓝色