// write RR values to a text file kept in the application data directory for possible later use public void writeRR(View v) { try { // status.setMessage("writing RR values to file"); SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm"); // give user feedback the button worked v.playSoundEffect(SoundEffectConstants.CLICK); double starttime = series.getX(0); String mydate = (format.format(starttime)); String FILENAME = "rr_" + mydate + ".txt"; status.setMessage("writing RR values to file to Documents " + FILENAME); File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); File file = new File(path, "/" + FILENAME); dbg(file.getAbsolutePath().toString()); file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); for (int i = 1; i < series.getItemCount(); i++) { int temprr = (int) (series.getX(i) - series.getX(i - 1)); String s = String.valueOf(temprr) + "\n"; fos.write(s.getBytes()); } fos.close(); } catch (Exception e) { e.printStackTrace(); } }
public void startZephyr(View v) { v.playSoundEffect(SoundEffectConstants.CLICK); status.setMessage("Connecting Zephyr"); x = System.currentTimeMillis(); zm.connect(); }
// the zephry manager will send RR values to this listener. // RRs are the milliseconds between beats. Example, steady 60 BPM heartbeat sends rr values of // 1000 because there is a full second between beats public void updateChart(int rr) { // we throw out any 0s or absurd values. We have found this tends not to happen with a good // chest strap if ((rr < 1) || (rr > 3000)) return; int pulserate = 60000 / rr; series.add(x, pulserate); x = x + rr; // time is also the accumulation of RR values // Achartengine stuff XYSeriesRenderer renderer = new XYSeriesRenderer(); XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer(); // Set the right side to current time mRenderer.setXAxisMax(x); // set the left side to one minute earlier 60000 miliseconds mRenderer.setXAxisMin(x - 60000); mRenderer.setYAxisMin(MIN_HEART_RATE); mRenderer.setYAxisMax(MAX_HEART_RATE); mRenderer.setLabelsTextSize(LABELTEXTSIZE); renderer.setFillPoints(true); renderer.setLineWidth(2); renderer.setPointStyle(style); mRenderer.setShowLegend(false); mRenderer.setChartTitle(title); mRenderer.setShowGrid(true); mRenderer.setGridColor(gridcolor); mRenderer.setXLabels(11); mRenderer.setYLabels(5); mRenderer.setAxisTitleTextSize(25); mRenderer.setChartTitleTextSize(30); mRenderer.setLabelsTextSize(20); mRenderer.setLegendTextSize(15); mRenderer.setPointSize(2f); mRenderer.setMargins(new int[] {20, 30, 15, 0}); mRenderer.setYLabelsAlign(Align.RIGHT); mDataset.removeSeries(0); mDataset.addSeries(series); renderer.setColor(linecolor); context = getApplicationContext(); mRenderer.setApplyBackgroundColor(true); mRenderer.setBackgroundColor(bgcolor); mRenderer.addSeriesRenderer(renderer); chartview = ChartFactory.getTimeChartView(context, mDataset, mRenderer, null); chartview.invalidate(); ((TextView) findViewById(R.id.heartratelabel)).setText("HR:" + pulserate); chartview.repaint(); FrameLayout chartlayout = (FrameLayout) findViewById(R.id.chartlayout); chartlayout.removeAllViewsInLayout(); chartlayout.addView( chartview, new FrameLayout.LayoutParams( FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT)); status .checkForClear(); // this needs to be done time to time regularly so statuses are not stuck // on. }