package com.algobase.activity; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileFilter; import java.io.FileReader; import java.io.FileWriter; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.ArrayList; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.content.Context; import android.content.BroadcastReceiver; import android.content.IntentFilter; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.CountDownTimer; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.EditText; import android.widget.Toast; import com.algobase.service.DataService; import com.algobase.stracks_0.sTracksRoot; import com.algobase.stracks_0.R; import com.algobase.share.dialog.*; import com.algobase.share.system.*; import com.algobase.share.ant.*; public class HRV_Activity extends Activity { static final int ANT_UNDEFINED = -1; static final int ANT_STOPPED = 0; static final int ANT_SCANNING = 1; static final int ANT_CONNECTED = 2; Handler handler; Context context; CountDownTimer cdt; TextView tv; Ant ant; float client_version = 0; int ant_available = 1; int ant_device_count = 0; int ant_restart_count = 0; ArrayList ant_hr_device_list = new ArrayList(); int ant_hr_state = ANT_UNDEFINED; String hrate_device_name = null; String hrate_connect_name = null; String hrate_connect_status = ""; String hrate_battery_status = ""; int hrate_connect_count = 0; int current_hrate = 0; int min_hrate = 0; int max_hrate = 0; float sum_hrate = 0; float avg_hrate = 0; int num_hrate = 0; int hrv_recording_interval = 120; int current_hrv_time = 0; int current_hrv_artefacts = 0; float current_hrv_rr = 0; float min_hrv_rr = 0; float max_hrv_rr = 0; float avg_hrv_rr = 0; float current_hrv_score = 0; float current_hrv_sdnn = 0; float current_hrv_rmssd = 0; float current_hrv_lnrmssd = 0; float current_hrv_pnn50 = 0; float min_hrv_rmssd = 0; float max_hrv_rmssd = 0; int dialog_style = MyDialog.STYLE_HOLO_LIGHT; private void log(String msg) { Log.v("sTracksLog",msg); //showToast(msg); } private String format(String pattern, Object... args) { String s = ""; try { s = String.format(Locale.US,pattern,args); } catch (Exception e) { showToast(e.toString()); } return s; } private void showToast(final String txt) { handler.post(new Runnable() { public void run() { Toast.makeText(context,txt, Toast.LENGTH_LONG).show(); } }); } private void acknowledge(String title, String txt) { final MyDialog diag = new MyDialog(this); diag.setTitle(title); diag.setMessage(txt); diag.setPositiveButton("continue", null); handler.post(new Runnable() { public void run() { diag.show(); } }); } void ant_restart_scanning(final String reason) { ant_restart_count++; log("ANT: Restart " + ant_restart_count); log("reason: " + reason); showToast("ANT Restart: " + reason); ant.stopScanning("all"); MyThread thr = new MyThread() { public void run() { handler.post(new Runnable() { public void run() { sleep(2000); startAnt(); } }); } }; thr.start(); } void startAnt() { ant = new Ant(this) { @Override public void writeLog(String txt) { log("ANT: " + txt); } @Override public void handleDeviceMessage(String dev, int id, String msg, String value) { if (!dev.equals("hrate")) return; String dev_name = format("%d",id); if (msg.equals("state") && value.equals("DEAD")) showToast(dev + " " + id + " " + msg + " " + value); /* if (msg.equals("stopped") && value.equals("ADAPTER_NOT_DETECTED")) showToast(dev + " " + id + " " + msg + " " + value); */ if (msg.equals("stopped")) { if (value.equals("OTHER_FAILURE") || value.equals("CHANNEL_NOT_AVAILABLE")) { log(format("ANT: %-7s %s",dev,value)); ant_restart_scanning(value); return; // do not call update_device_message } } if (msg.equals("connect_failed")) { log(format("ANT: %-7s %s",dev,msg)); if (value.equals("SEARCH_TIMEOUT")) { ant_restart_scanning(value); return; // do not call update_device_message } } if (msg.equals("device")) { // new device detected (connect if dev_name = connect_name) //showToast("Device: " + dev_name); //if (dev_name.equals(hrate_connect_name)) ant.connectToHeartRateDevice(dev_name); } if (msg.equals("connected")) { showToast("ANT+ HR-Sensor: " + dev_name); /* if (hrate_connect_count == 0) play_sound(sTracksActivity.SOUND_HRATE_SENSOR); */ hrate_connect_name = dev_name; hrate_connect_count++; } /* if (msg.equals("disconnected")) { showToast("ANT+ HR-Sensor: disconnected"); //hrate_connect_count = 0; } */ if (msg.equals("state")) { showToast(format("ANT+ HR %s : %s",dev_name,value)); /* if (value.equals("DEAD")) { log("ANT: Scanning DEAD"); log("dev = " + dev); log("msg = " + msg); log("val = " + value); ant_restart_scanning(value); return; } */ } if (msg.equals("battery")) { hrate_battery_status = value; return; } } @Override public void handleHeartRateEvent(int id, long t, int hrate, long hrnum) { num_hrate++; current_hrate = hrate; if (hrate < min_hrate || min_hrate == 0) min_hrate = hrate; if (hrate > max_hrate) max_hrate = hrate; sum_hrate += hrate; avg_hrate = sum_hrate/num_hrate; } @Override public void handleRRIntervalEvent(int id, long t, float total_time, int artefacts, int rr, int rr_min, int rr_max, float rr_avg, float sdnn, float rmssd, float pnn50) { log(format("rr: %4.0f avg: %4.0f atfs: %d ", rr,rr_avg,artefacts)); current_hrv_time = (int)total_time; current_hrv_artefacts = artefacts; current_hrv_rr = rr; min_hrv_rr = rr_min; max_hrv_rr = rr_max; avg_hrv_rr = rr_avg; current_hrv_sdnn = sdnn; current_hrv_rmssd = rmssd; current_hrv_pnn50 = pnn50; if (rmssd >= 0) { current_hrv_rmssd = rmssd; current_hrv_lnrmssd = (rmssd <= 0) ? 0 : (float)Math.log(rmssd); current_hrv_score = (100/6.5f) * current_hrv_lnrmssd; if (rmssd > max_hrv_rmssd) max_hrv_rmssd = rmssd; if (rmssd < min_hrv_rmssd || min_hrv_rmssd == 0) min_hrv_rmssd = rmssd; } } }; ant.startScanning("hrate"); } void update_display() { if (hrate_connect_name == null) { tv.setText("Scanning for HR-Sensor"); return; } String txt = ""; txt += format("ANT+ HR-Device (%s)\n", hrate_connect_name); txt += "\n"; txt += format("hrt: %3d\n", current_hrate); txt += format("avg: %3.0f\n", avg_hrate); txt += format("max: %3d\n", max_hrate); txt += format("min: %3d\n", min_hrate); txt += "\n"; txt += format("rr: %4.0f\n", current_hrv_rr); txt += format("min_rr: %4.0f\n", min_hrv_rr); txt += format("max_rr: %4.0f\n", max_hrv_rr); txt += "\n"; txt += format("sdnn: %6.1f\n", current_hrv_sdnn); txt += format("rmssd: %6.1f\n", current_hrv_rmssd); txt += format("lnrmssd:%5.1f\n", current_hrv_lnrmssd); txt += format("pnn50: %5.1f\n", current_hrv_pnn50); txt += "\n"; txt += format("score: %3.0f\n", current_hrv_score); txt += format("time: %3d\n", current_hrv_time/1000); txt += "\n"; txt += format("Battery: %s\n", hrate_battery_status); tv.setText(txt); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_Holo_Light); setContentView(R.layout.hrv_activity); context = this; handler = new Handler(); tv = (TextView)findViewById(R.id.text_view1); tv.setText("HRV Activity"); try { PackageManager pm = getPackageManager(); String package_name = getPackageName(); PackageInfo pi = pm.getPackageInfo(package_name,0); client_version = 0.001f * pi.versionCode; } catch(Exception e) {} startAnt(); cdt = new CountDownTimer(1000000000, 1000) { public void onTick(long ms) { update_display(); } public void onFinish() {} }; cdt.start(); } @Override protected void onResume() { //startDataService("connect",null,null); super.onResume(); } @Override protected void onDestroy() { //stopDataService(); super.onResume(); } @Override public void onBackPressed() { super.onBackPressed(); } }