Yama ichi version with working Service
This commit is contained in:
parent
c9e31bf9f0
commit
8361439a9a
3 changed files with 103 additions and 27 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
|
|
@ -47,9 +47,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
public void onClick(View v) {
|
||||
serviceButton.setEnabled(false);
|
||||
if(HeartRateService.isRunning()) {
|
||||
startHeartRateMonitor();
|
||||
} else {
|
||||
stopHeartRateMonitor();
|
||||
} else {
|
||||
startHeartRateMonitor();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -80,6 +80,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
public void startHeartRateMonitor() {
|
||||
Log.d(TAG, "Start HR");
|
||||
if(HeartRateService.isRunning()) {
|
||||
Toast.makeText(this, "Already running", Toast.LENGTH_LONG);
|
||||
} else {
|
||||
|
@ -100,9 +101,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
public void stopHeartRateMonitor() {
|
||||
// stop tracking
|
||||
Intent intent = new Intent(MainActivity.this, HeartRateService.class);
|
||||
intent.setAction(HeartRateService.ACTION_STOP);
|
||||
startService(intent);
|
||||
// Intent intent = new Intent(MainActivity.this, HeartRateService.class);
|
||||
Log.d(TAG, "Stop HR");
|
||||
stopService(new Intent(this, HeartRateService.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,13 +4,17 @@ import android.app.AlertDialog;
|
|||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
@ -38,8 +42,11 @@ import java.math.BigDecimal;
|
|||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class HeartRateService extends Service {
|
||||
private static final String TAG = HeartRateService.class.getSimpleName();
|
||||
|
@ -69,11 +76,19 @@ public class HeartRateService extends Service {
|
|||
NotificationCompat.Builder builder;
|
||||
NotificationManager notificationManager;
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
Timer lifelineTimer;
|
||||
DeviceState currentDeviceState;
|
||||
|
||||
boolean restartService = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
notificationManager =
|
||||
(NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
|
||||
|
||||
startLifelineTimer();
|
||||
setRunning(true);
|
||||
|
||||
requestAccessToPcc();
|
||||
|
@ -103,7 +118,6 @@ public class HeartRateService extends Service {
|
|||
*/
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (intent.getAction().equals(ACTION_START)) {
|
||||
Log.i(TAG, "Received start id " + startId + ": " + intent);
|
||||
Intent notificationIntent = new Intent(this, MainActivity.class);
|
||||
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
|
@ -124,11 +138,6 @@ public class HeartRateService extends Service {
|
|||
startForeground(NOTIFICATION_ID,
|
||||
builder.build());
|
||||
|
||||
} else if (intent.getAction().equals(ACTION_STOP)) {
|
||||
Log.i(TAG, "Received stop id " + startId + ": " + intent);
|
||||
stopForeground(true);
|
||||
stopSelf();
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
|
@ -138,14 +147,18 @@ public class HeartRateService extends Service {
|
|||
@Override
|
||||
public void onDeviceStateChange(final DeviceState state)
|
||||
{
|
||||
currentDeviceState = state;
|
||||
if(DeviceState.DEAD.equals(state) || DeviceState.CLOSED.equals(state)) {
|
||||
sendBroadcast(new Intent(BROADCAST_MONITOR_DISCONNECTED));
|
||||
updateNotification("Disconnected");
|
||||
waitAndReconnect();
|
||||
} else if (DeviceState.TRACKING.equals(state)) {
|
||||
sendBroadcast(new Intent(BROADCAST_MONITOR_CONNECTED));
|
||||
updateNotification("Connected!");
|
||||
} else {
|
||||
Intent i = new Intent(BROADCAST_MONITOR_UNKNOWN);
|
||||
i.putExtra("status", state.getIntValue());
|
||||
updateNotification("Unknown status: "+ String.valueOf(state.getIntValue()));
|
||||
sendBroadcast(i);
|
||||
}
|
||||
}
|
||||
|
@ -162,24 +175,29 @@ public class HeartRateService extends Service {
|
|||
switch (resultCode) {
|
||||
case SUCCESS:
|
||||
i.putExtra("msg", "Success");
|
||||
updateNotification("Access");
|
||||
connectHr(result);
|
||||
break;
|
||||
case CHANNEL_NOT_AVAILABLE:
|
||||
showNotification("Channel Not Available");
|
||||
i.putExtra("msg", "Channel Not Available");
|
||||
updateNotification("Channel not available");
|
||||
break;
|
||||
case OTHER_FAILURE:
|
||||
showNotification("RequestAccess failed. See logcat for details.");
|
||||
i.putExtra("msg", "RequestAccess failed. See logcat for details.");
|
||||
updateNotification("RequestAccess failed");
|
||||
break;
|
||||
case USER_CANCELLED:
|
||||
showNotification("Cancelled. Do reset.");
|
||||
i.putExtra("msg", "Cancelled. Do reset.");
|
||||
updateNotification("Cancelled, do reset");
|
||||
break;
|
||||
case UNRECOGNIZED:
|
||||
default:
|
||||
showNotification("Unknown error. Do reset.");
|
||||
i.putExtra("msg", "unknown error. Do reset.");
|
||||
updateNotification("Unknown error, do reset");
|
||||
break;
|
||||
}
|
||||
sendBroadcast(i);
|
||||
|
@ -195,6 +213,8 @@ public class HeartRateService extends Service {
|
|||
final int computedHeartRate, final long heartBeatCount,
|
||||
final BigDecimal heartBeatEventTime, final AntPlusHeartRatePcc.DataState dataState)
|
||||
{
|
||||
currentDeviceState = DeviceState.TRACKING;
|
||||
|
||||
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
|
||||
otherSymbols.setDecimalSeparator('.');
|
||||
DecimalFormat df = new DecimalFormat("#.##", otherSymbols);
|
||||
|
@ -216,8 +236,8 @@ public class HeartRateService extends Service {
|
|||
intent.putExtra("time", textHeartBeatEventTime);
|
||||
sendBroadcast(intent);
|
||||
|
||||
builder.setContentText(textHeartRate + " bpm");
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build());
|
||||
updateNotification(textHeartRate + " bpm / " + textHeartBeatCount + " beats / " + textHeartBeatEventTime );
|
||||
|
||||
|
||||
JSONObject jObjectData = new JSONObject();
|
||||
// final String msg = String.format("{\"rate\":\"%s\", \"count\":\"%s\", \"time\":\"%s\"}", textHeartRate, textHeartBeatCount, textHeartBeatEventTime);
|
||||
|
@ -226,7 +246,7 @@ public class HeartRateService extends Service {
|
|||
jObjectData.put("rate", textHeartRate);
|
||||
jObjectData.put("count", textHeartBeatCount);
|
||||
jObjectData.put("time", textHeartBeatEventTime);
|
||||
jObjectData.put("timestamp", DateFormat.getDateTimeInstance().format(new Date()));
|
||||
jObjectData.put("timestamp", dateFormat.format(new Date()));
|
||||
jObjectData.put("token", getToken());
|
||||
|
||||
msg = jObjectData.toString();
|
||||
|
@ -248,6 +268,11 @@ public class HeartRateService extends Service {
|
|||
|
||||
}
|
||||
|
||||
public void updateNotification(String msg) {
|
||||
builder.setContentText(msg);
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build());
|
||||
}
|
||||
|
||||
|
||||
String token = null;
|
||||
/**
|
||||
|
@ -272,8 +297,9 @@ public class HeartRateService extends Service {
|
|||
return null;
|
||||
}
|
||||
try {
|
||||
Log.d(TAG, "JSON: "+ json);
|
||||
JSONObject jsonObject = new JSONObject(json);
|
||||
token = jsonObject.getString("token'");
|
||||
token = jsonObject.getString("token");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
|
@ -312,6 +338,40 @@ public class HeartRateService extends Service {
|
|||
});
|
||||
}
|
||||
|
||||
protected void startLifelineTimer() {
|
||||
lifelineTimer = new Timer();
|
||||
|
||||
lifelineTimer.scheduleAtFixedRate(new TimerTask(){
|
||||
@Override
|
||||
public void run(){
|
||||
Log.d(TAG, "A Kiss every 10 seconds");
|
||||
if(DeviceState.TRACKING.equals(currentDeviceState)) {
|
||||
Log.i(TAG, "Alive and kicking!");
|
||||
return;
|
||||
}
|
||||
Log.w(TAG, "Device status different... ");
|
||||
String val;
|
||||
if(currentDeviceState == null) {
|
||||
val = "null";
|
||||
} else {
|
||||
val = String.valueOf(currentDeviceState.getIntValue());
|
||||
}
|
||||
Log.w(TAG, "Device status: '"+ val +"'");
|
||||
|
||||
// something is off: warn & attempt restart
|
||||
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
v.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||
} else {
|
||||
//deprecated in API 26
|
||||
v.vibrate(1000);
|
||||
}
|
||||
restart();
|
||||
}
|
||||
},20000,10000);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* wait to reconnect to dead HR-monitor
|
||||
*/
|
||||
|
@ -322,14 +382,20 @@ public class HeartRateService extends Service {
|
|||
hrPcc.subscribeHeartRateDataEvent(null);
|
||||
}
|
||||
|
||||
new android.os.Handler().postDelayed(
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
Log.i(TAG, "Attempt reconnect");
|
||||
requestAccessToPcc();
|
||||
}
|
||||
},
|
||||
20000); // 20 sec delay for connection
|
||||
// triggers: "sending message to a handler on a dead thread"
|
||||
// new android.os.Handler().postDelayed(
|
||||
// new Runnable() {
|
||||
// public void run() {
|
||||
// Log.i(TAG, "Attempt reconnect");
|
||||
requestAccessToPcc();
|
||||
// }
|
||||
// },
|
||||
// 20000); // 20 sec delay for connection
|
||||
}
|
||||
|
||||
protected void restart(){
|
||||
restartService = true;
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,9 +403,10 @@ public class HeartRateService extends Service {
|
|||
*/
|
||||
protected void requestAccessToPcc()
|
||||
{
|
||||
if(hrPcc != null) {
|
||||
hrPcc.subscribeHeartRateDataEvent(null);
|
||||
}
|
||||
// if(hrPcc != null) {
|
||||
// hrPcc.subscribeHeartRateDataEvent(null);
|
||||
// }
|
||||
Log.d(TAG, "Request Access To PCC");
|
||||
sendBroadcast( new Intent(BROADCAST_MONITOR_CONNECT_ATTEMPT) );
|
||||
releaseHandle = AntPlusHeartRatePcc.requestAccess(this, 4818, 0, resultReceiver, stateChangeReceiver);
|
||||
}
|
||||
|
@ -352,12 +419,19 @@ public class HeartRateService extends Service {
|
|||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.i(TAG, "Stop service");
|
||||
stopForeground(true);
|
||||
lifelineTimer.cancel();
|
||||
if(releaseHandle != null)
|
||||
{
|
||||
releaseHandle.close();
|
||||
}
|
||||
setRunning(false);
|
||||
super.onDestroy();
|
||||
|
||||
if(restartService ) {
|
||||
startService(new Intent(this, HeartRateService.class));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isRunning() {
|
||||
|
|
Loading…
Reference in a new issue