/* HitoeManager Copyright (c) 2016 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.hitoe.data; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.os.Handler; import android.util.Log; import android.widget.Toast; import org.deviceconnect.android.deviceplugin.hitoe.BuildConfig; import org.deviceconnect.android.deviceplugin.hitoe.util.RawDataParseUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import jp.ne.docomo.smt.dev.hitoetransmitter.HitoeSdkAPI; import jp.ne.docomo.smt.dev.hitoetransmitter.sdk.HitoeSdkAPIImpl; /** * This class manages a Hitoe devices. * @author NTT DOCOMO, INC. */ public class HitoeManager { /** Log's tag name. */ private static final String TAG = "HitoeManager"; /** * Instance of ScheduledExecutorService. */ private ScheduledExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor(); /** * ScheduledFuture of scan timer. */ private ScheduledFuture<?> mScanTimerFuture; /** * Defines a delay 1 second at first execution. */ private static final long SCAN_FIRST_WAIT_PERIOD = 30 * 1000; /** * Defines a period 10 seconds between successive executions. */ private static final long SCAN_WAIT_PERIOD = 20 * 1000; /** * Stops scanning after 1 second. */ private static final long SCAN_PERIOD = 2000; /** Wait 5000 msec. */ private static final int CONNECTING_RETRY_WAIT = 500; /** Connecting retry count. */ private static final int CONNECTING_RETRY_COUNT = 10; /** Device scanning flag. */ private boolean mScanning; /** Device scanning running. */ private boolean mIsCallbackRunning; /** Device scan timestamp. */ private final Map<HitoeDevice, Long> mNowTimestamps; /** Handler. */ private Handler mHandler = new Handler(); /** * Application context. */ private Context mContext; /** * Instance of {@link HitoeDBHelper}. */ private HitoeDBHelper mDBHelper; /** * Hitoe SDK API. */ private HitoeSdkAPI mHitoeSdkAPI; // ------------------------------------ // Listener. // ------------------------------------ /** Hitoe Discovery Listener. */ private List<OnHitoeConnectionListener> mConnectionListeners; /** Notify HeartRate data listener. */ private OnHitoeHeartRateEventListener mHeartRataListener; /** Notify Accleration data listener. */ private OnHitoeDeviceOrientationEventListener mDeviceOrientationListener; /** Notify ECG data listener. */ private OnHitoeECGEventListener mECGListener; /** Notify Pose Estimation data listener. */ private OnHitoePoseEstimationEventListener mPoseEstimationListener; /** Notify Stress Estimation data listener. */ private OnHitoeStressEstimationEventListener mStressEstimationListener; /** Notify Walk state data listener. */ private OnHitoeWalkStateEventListener mWalkStateListener; /** Registered Hitoe devices .*/ private final List<HitoeDevice> mRegisterDevices; /** HeartRate Datas. */ private final Map<HitoeDevice, HeartRateData> mHRData; /** Acceleration Datas. */ private final Map<HitoeDevice, AccelerationData> mAccelData; /** ECG Datas. */ private final Map<HitoeDevice, HeartRateData> mECGData; /** Pose Estimation datas. */ private final Map<HitoeDevice, PoseEstimationData> mPoseEstimationData; /** Stress Estimation datas. */ private final Map<HitoeDevice, StressEstimationData> mStressEstimationData; /** Walk State datas. */ private final Map<HitoeDevice, WalkStateData> mWalkStateData; /** Save data for extended analysis. */ private ArrayList<TempExData> mListForEx; /** Lock for the extension analysis. */ private ReentrantLock mLockForEx; /** Expanded analysis flag. */ private boolean mFlagForEx; /** Acceleration's interval. */ private long mInterval = 0; /** Temporary storage data for pose estimation. */ private ArrayList<String> mListForPosture; /** Lock for pose estimation. */ private ReentrantLock mLockForPosture; /** Temporary storage data for walking state estimation. */ private ArrayList<String> mListForWalk; /** Lock for walking state estimation. */ private ReentrantLock mLockForWalk; /** Temporary storage data for the left and right balance estimation. */ private ArrayList<String> mListForLRBalance; /** Lock for the left and right balance estimation. */ private ReentrantLock mLockForLRBalance; /** Hitoe API Callback. */ HitoeSdkAPI.APICallback mAPICallback = new HitoeSdkAPI.APICallback() { @Override public void onResponse(final int apiId, final int responseId, final String responseString) { final StringBuilder messageTextBuilder = new StringBuilder(); if (BuildConfig.DEBUG) { Log.d(TAG, "CbCallback:apiId=" + String.valueOf(apiId) + ",responseId=" + String.valueOf(responseId) + ",resonseObject=" + responseString.replace(HitoeConstants.BR, HitoeConstants.VB)); } switch (apiId) { case HitoeConstants.API_ID_GET_AVAILABLE_SENSOR: notifyDiscoveryHitoeDevice(responseId, responseString); break; case HitoeConstants.API_ID_CONNECT: notifyConnectHitoeDevice(responseId, responseString); break; case HitoeConstants.API_ID_DISCONNECT: // disconnect sensor break; case HitoeConstants.API_ID_GET_AVAILABLE_DATA: notifyAvailableData(responseId, responseString); break; case HitoeConstants.API_ID_ADD_RECIVER: notifyAddReceiver(responseId, responseString); break; case HitoeConstants.API_ID_REMOVE_RECEIVER: notifyRemoveReceiver(responseId, responseString); break; case HitoeConstants.API_ID_GET_STATUS: break; default: if (BuildConfig.DEBUG) { Log.e(TAG, "etc state"); } break; } } }; /** * Data receiver. */ HitoeSdkAPI.DataReceiverCallback mDataReceiverCallback = new HitoeSdkAPI.DataReceiverCallback() { @Override public void onDataReceive(final String connectionId, final int responseId, final String dataKey, final String rawData) { int pos = getPosForConnectionId(connectionId); if (pos == -1) { if (BuildConfig.DEBUG) { Log.d(TAG, "no connectionId"); } return; } HitoeDevice receiveDevice = mRegisterDevices.get(pos); if (receiveDevice.getSessionId() == null) { return; } if (dataKey.equals("raw.ecg")) { extractHealth(HeartData.HeartRateType.ECG, rawData, receiveDevice); } else if (dataKey.equals("raw.acc")) { analyzeAccelerationData(rawData, receiveDevice); AccelerationData currentAccel = mAccelData.get(receiveDevice); if (currentAccel == null) { currentAccel = new AccelerationData(); } currentAccel = RawDataParseUtils.parseAccelerationData(currentAccel, rawData); mAccelData.put(receiveDevice, currentAccel); } else if (dataKey.equals("raw.rri")) { extractHealth(HeartData.HeartRateType.RRI, rawData, receiveDevice); } else if (dataKey.equals("raw.bat")) { extractBattery(rawData, receiveDevice); } else if (dataKey.equals("raw.hr")) { extractHealth(HeartData.HeartRateType.Rate, rawData, receiveDevice); } else if (dataKey.equals("ba.freq_domain")) { parseFreqDomain(receiveDevice, rawData); } else if (dataKey.equals("ex.stress")) { StressEstimationData stress = RawDataParseUtils.parseStressEstimation(rawData); mStressEstimationData.put(receiveDevice, stress); } else if (dataKey.equals("ex.posture")) { PoseEstimationData pose = RawDataParseUtils.parsePoseEstimation(rawData); mPoseEstimationData.put(receiveDevice, pose); } else if (dataKey.equals("ex.walk")) { WalkStateData walk = mWalkStateData.get(receiveDevice); if (walk == null) { walk = new WalkStateData(); } walk = RawDataParseUtils.parseWalkState(walk, rawData); mWalkStateData.put(receiveDevice, walk); } else if (dataKey.equals("ex.lr_balance")) { WalkStateData walk = mWalkStateData.get(receiveDevice); if (walk == null) { walk = new WalkStateData(); } walk = RawDataParseUtils.parseWalkStateForBalance(walk, rawData); mWalkStateData.put(receiveDevice, walk); } if (dataKey.startsWith(HitoeConstants.EX_DATA_PREFFIX)) { // Expanded analysis discard the connection receiveDevice.removeConnectionId(connectionId); } else { // Perform any extension //Do not run if it is already running TempExData exData = null; try { mLockForEx.lock(); if (!mFlagForEx && mListForEx.size() > 0) { mFlagForEx = true; exData = mListForEx.get(0); mListForEx.remove(0); } } finally { mLockForEx.unlock(); } if (exData != null) { addExReceiverProcess(pos, exData); } } notifyListeners(receiveDevice); } }; /** * Constructor. * * @param context application context */ public HitoeManager(final Context context) { mContext = context; mDBHelper = new HitoeDBHelper(context); mListForEx = new ArrayList<>(); mLockForEx = new ReentrantLock(); mRegisterDevices = Collections.synchronizedList( new ArrayList<HitoeDevice>()); mHRData = new ConcurrentHashMap<>(); mECGData = new ConcurrentHashMap<>(); mPoseEstimationData = new ConcurrentHashMap<>(); mStressEstimationData = new ConcurrentHashMap<>(); mWalkStateData = new ConcurrentHashMap<>(); mAccelData = new ConcurrentHashMap<>(); mConnectionListeners = new ArrayList<>(); mListForPosture = new ArrayList<>(); mLockForPosture = new ReentrantLock(); mListForWalk = new ArrayList<>(); mLockForWalk = new ReentrantLock(); mListForLRBalance = new ArrayList<>(); mLockForLRBalance = new ReentrantLock(); mListForEx = new ArrayList<>(); mLockForEx = new ReentrantLock(); mNowTimestamps = new ConcurrentHashMap<>(); mHitoeSdkAPI = HitoeSdkAPIImpl.getInstance(context); mHitoeSdkAPI.setAPICallback(mAPICallback); readHitoeDeviceForDB(); } // ------------------------------------ // Public Method // ------------------------------------ /** * Set Hitoe Connection Listener. * @param l listener */ public void addHitoeConnectionListener(final OnHitoeConnectionListener l) { mConnectionListeners.add(l); } /** * Remove Hitoe Connection listener. * @param l connection listener */ public void removeHitoeConnectionListener(final OnHitoeConnectionListener l) { mConnectionListeners.remove(l); } /** * Set Hitoe HeartRate Listener. * @param l listener */ public void setHitoeHeartRateEventListener(final OnHitoeHeartRateEventListener l) { mHeartRataListener = l; } /** * Set Hitoe Acceleration Listener. * @param l listener */ public void setHitoeDeviceOrientationEventListener(final OnHitoeDeviceOrientationEventListener l) { mDeviceOrientationListener = l; } /** * Set Hitoe ECG listener. * @param l listener */ public void setHitoeECGEventListener(final OnHitoeECGEventListener l) { mECGListener = l; } /** * Set Hitoe Pose Estimation listener. * @param l listener */ public void setHitoePoseEstimationEventListener(final OnHitoePoseEstimationEventListener l) { mPoseEstimationListener = l; } /** * Set Hitoe Stress Estimation listener. * @param l listener */ public void setHitoeStressEstimationEventListener(final OnHitoeStressEstimationEventListener l) { mStressEstimationListener = l; } /** * Set Hitoe Walk state listener. * @param l listener */ public void setHitoeWalkStateEventListener(final OnHitoeWalkStateEventListener l) { mWalkStateListener = l; } /** * Gets the list of BLE device that was registered to automatic connection. * * @return list of BLE device */ public List<HitoeDevice> getRegisterDevices() { return mRegisterDevices; } /** * Read device info. */ public void readHitoeDeviceForDB() { List<HitoeDevice> list = mDBHelper.getHitoeDevices(null); for (int i = 0; i < list.size(); i++) { HitoeDevice device = list.get(i); if (mRegisterDevices.size() > 0) { if (!containsDevice(device.getId())) { mRegisterDevices.add(device); } } else { mRegisterDevices.add(device); } } } /** * Get mRegisterDevice for service id. * @param serviceId service Id * @return Hitoe Device object */ public HitoeDevice getHitoeDeviceForServiceId(final String serviceId) { for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getId() != null) { if (mRegisterDevices.get(i).getId().equals(serviceId)) { return mRegisterDevices.get(i); } } } return null; } /** * Get HeartRateData. * @param serviceId index id * @return HeartRateData */ public HeartRateData getHeartRateData(final String serviceId) { int pos = getPosForServiceId(serviceId); if (pos == -1) { return null; } return mHRData.get(mRegisterDevices.get(pos)); } /** * Get ECG Data. * @param serviceId index id * @return ECGData */ public HeartRateData getECGData(final String serviceId) { int pos = getPosForServiceId(serviceId); if (pos == -1) { return null; } return mECGData.get(mRegisterDevices.get(pos)); } /** * Get Stress Estimation Data. * @param serviceId index id * @return StressEstimationData */ public StressEstimationData getStressEstimationData(final String serviceId) { int pos = getPosForServiceId(serviceId); if (pos == -1) { return null; } return mStressEstimationData.get(mRegisterDevices.get(pos)); } /** * Get Pose Estimation Data. * @param serviceId index id * @return Pose Estimation Data */ public PoseEstimationData getPoseEstimationData(final String serviceId) { int pos = getPosForServiceId(serviceId); if (pos == -1) { return null; } return mPoseEstimationData.get(mRegisterDevices.get(pos)); } /** * Get Walk State Data. * @param serviceId index id * @return Walk State data */ public WalkStateData getWalkStateData(final String serviceId) { int pos = getPosForServiceId(serviceId); if (pos == -1) { return null; } return mWalkStateData.get(mRegisterDevices.get(pos)); } /** * Get AccelerationData. * @param serviceId index id * @return AccelerationData */ public AccelerationData getAccelerationData(final String serviceId) { int pos = getPosForServiceId(serviceId); if (pos == -1) { return null; } return mAccelData.get(mRegisterDevices.get(pos)); } /** * Stats the HitoeManager. */ public void start() { synchronized (mRegisterDevices) { for (int i = 0; i < mRegisterDevices.size(); i++) { HitoeDevice device = mRegisterDevices.get(i); if (device.isRegisterFlag()) { connectHitoeDevice(device); } } } } /** * Stops the HitoeManager. */ public void stop() { for (int i = 0; i < mRegisterDevices.size(); i++) { mHitoeSdkAPI.disconnect(mRegisterDevices.get(i).getSessionId()); mRegisterDevices.get(i).setRegisterFlag(false); mDBHelper.updateHitoeDevice(mRegisterDevices.get(i)); mRegisterDevices.get(i).setSessionId(null); } scanHitoeDevice(false); } /** * Discovery hitoe device. */ public void discoveryHitoeDevices() { StringBuilder paramStringBuilder = new StringBuilder(); paramStringBuilder.append("search_time=") .append(String.valueOf(HitoeConstants.GET_AVAILABLE_SENSOR_PARAM_SEARCH_TIME)); mHitoeSdkAPI.getAvailableSensor(HitoeConstants.GET_AVAILABLE_SENSOR_DEVICE_TYPE, paramStringBuilder.toString()); if (mRegisterDevices.size() > 0) { for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onDiscovery(mRegisterDevices); } } } } /** * Connect to Hitoe Device by address. * * @param device device for hitoe device */ public void connectHitoeDevice(final HitoeDevice device) { mExecutor.submit(new Runnable() { @Override public void run() { if (device == null || device.getPinCode() == null) { return; } StringBuilder paramBuilder = new StringBuilder(); paramBuilder.append("disconnect_retry_time=" + HitoeConstants.CONNECT_DISCONNECT_RETRY_TIME); if (paramBuilder.length() > 0) { paramBuilder.append(HitoeConstants.BR); } paramBuilder.append("disconnect_retry_count=" + HitoeConstants.CONNECT_DISCONNECT_RETRY_COUNT); if (paramBuilder.length() > 0) { paramBuilder.append(HitoeConstants.BR); } paramBuilder.append("nopacket_retry_time=" + HitoeConstants.CONNECT_NOPACKET_RETRY_TIME); if (paramBuilder.length() > 0) { paramBuilder.append(HitoeConstants.BR); } paramBuilder.append("pincode="); paramBuilder.append(device.getPinCode()); String param = paramBuilder.toString(); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice remoteDevice = adapter.getRemoteDevice(device.getId()); if (remoteDevice.getName() == null) { // If RemoteDevice is Null, Discovery process needs to be done once. // Retry 10 times and continue processing when RemoteDevice is found. discoveryHitoeDevices(); int i = 0; for (i = 0; i < CONNECTING_RETRY_COUNT; i++) { try { Thread.sleep(CONNECTING_RETRY_WAIT); } catch (InterruptedException e) { e.printStackTrace(); } remoteDevice = adapter.getRemoteDevice(device.getId()); if (remoteDevice.getName() != null) { break; } } if (i == CONNECTING_RETRY_COUNT && remoteDevice.getName() == null) { return; } } mHitoeSdkAPI.connect(device.getType(), device.getId(), device.getConnectMode(), param); device.setResponseId(HitoeConstants.RES_ID_SENSOR_CONNECT); mDBHelper.addHitoeDevice(device); mStressEstimationData.put(device, new StressEstimationData()); for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getId().equals(device.getId())) { mRegisterDevices.set(i, device); } else { mRegisterDevices.get(i).setResponseId(HitoeConstants.RES_ID_SENSOR_DISCONECT_NOTICE); } } } }); } /** * Disconnect hitoe device. * @param device hitoe device */ public void disconnectHitoeDevice(final HitoeDevice device) { mExecutor.submit(new Runnable() { @Override public void run() { HitoeDevice current = getHitoeDeviceForServiceId(device.getId()); int res = mHitoeSdkAPI.disconnect(current.getSessionId()); current.setRegisterFlag(false); current.setSessionId(null); mDBHelper.updateHitoeDevice(current); if (!existConnected()) { scanHitoeDevice(false); } for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onDisconnected(res, device); } } } }); } /** * Delete hitoe device info for db. * @param device hitoe device */ public void deleteHitoeDevice(final HitoeDevice device) { mDBHelper.removeHitoeDevice(device); for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getId().equals(device.getId())) { HitoeDevice d = mRegisterDevices.remove(i); for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onDeleted(d); } } } } } /** * Tests whether this mConnectedDevices contains the address. * @param id address will be checked * @return true if address is an element of mConnectedDevices, false otherwise */ public boolean containConnectedHitoeDevice(final String id) { synchronized (mRegisterDevices) { for (HitoeDevice d : mRegisterDevices) { if (d.getId().equals(id) && d.getSessionId() != null) { return true; } } } return false; } // Private method // ------------------------------------ // Notifyメソッド群 // ------------------------------------ /** * Notify for found Hitoe Devices. * @param responseId Response id * @param responseString Response String */ private void notifyDiscoveryHitoeDevice(final int responseId, final String responseString) { if (responseId != HitoeConstants.RES_ID_SUCCESS || responseString == null) { return; } String[] sensorList = responseString.split(HitoeConstants.BR, -1); List<HitoeDevice> pins = mDBHelper.getHitoeDevices(null); for (int i = 0; i < sensorList.length; i++) { String sensorStr = sensorList[i].trim(); if (sensorStr.length() == 0) { continue; } if (!sensorStr.contains("memory_setting") && !sensorStr.contains("memory_get")) { HitoeDevice device = new HitoeDevice(sensorStr); if (mRegisterDevices.size() == 0) { mRegisterDevices.add(device); } if (!containsDevice(device.getId())) { mRegisterDevices.add(device); } } } for (HitoeDevice pin : pins) { for (HitoeDevice register: mRegisterDevices) { if (register.getId().equals(pin.getId())) { register.setPinCode(pin.getPinCode()); register.setRegisterFlag(pin.isRegisterFlag()); } } } for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onDiscovery(mRegisterDevices); } } } /** * Notify for connected hitoe devices. * @param responseId Response id * @param responseString Response string */ private void notifyConnectHitoeDevice(final int responseId, final String responseString) { int pos = getCurrentPos(responseId); if (pos == -1) { for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onConnectFailed(null); } } return; } if (responseId == HitoeConstants.RES_ID_SENSOR_DISCONECT_NOTICE) { for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onConnectFailed(mRegisterDevices.get(pos)); } } return; } else if (responseId == HitoeConstants.RES_ID_SENSOR_CONNECT_NOTICE) { for (OnHitoeConnectionListener l: mConnectionListeners) { l.onConnected(mRegisterDevices.get(pos)); } return; } else if (responseId != HitoeConstants.RES_ID_SENSOR_CONNECT) { for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onConnectFailed(mRegisterDevices.get(pos)); } } return; } mRegisterDevices.get(pos).setSessionId(responseString); mRegisterDevices.get(pos).setRegisterFlag(true); mDBHelper.updateHitoeDevice(mRegisterDevices.get(pos)); mHitoeSdkAPI.getAvailableData(mRegisterDevices.get(pos).getSessionId()); mRegisterDevices.get(pos).setResponseId(HitoeConstants.RES_ID_SUCCESS); for (OnHitoeConnectionListener l: mConnectionListeners) { if (l != null) { l.onConnected(mRegisterDevices.get(pos)); } } } /** * Notify AvailableData. * @param responseId response id * @param responseString Response string */ private void notifyAvailableData(final int responseId, final String responseString) { if (responseId != HitoeConstants.RES_ID_SUCCESS || responseString == null) { return; } int pos = getCurrentPos(responseId); if (pos == -1) { return; } mRegisterDevices.get(pos).setAvailableData(responseString); List<String> keyList = mRegisterDevices.get(pos).getAvailableRawDataList(); StringBuilder paramStringBuilder = new StringBuilder(); String[] keys = new String[keyList.size()]; String paramString; for (int i = 0; i < keyList.size(); i++) { keys[i] = keyList.get(i); if (keyList.get(i).equals("raw.ecg")) { if (paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("raw.ecg_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_ECG_SAMPLING_INTERVAL)); } else if (keyList.get(i).equals("raw.acc")) { if (paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("raw.acc_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_ACC_SAMPLING_INTERVAL)); } else if (keyList.get(i).equals("raw.rri")) { if (paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("raw.rri_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_RRI_SAMPLING_INTERVAL)); } else if (keyList.get(i).equals("raw.hr")) { if (paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("raw.hr_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_HR_SAMPLING_INTERVAL)); } else if (keyList.get(i).equals("raw.bat")) { if (paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("raw.bat_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BAT_SAMPLING_INTERVAL)); } } paramString = paramStringBuilder.toString(); mHitoeSdkAPI.addReceiver(mRegisterDevices.get(pos).getSessionId(), keys, mDataReceiverCallback, paramString, null); scanHitoeDevice(true); } /** * Notify add receiver. * @param responseId response id * @param responseString response string */ private void notifyAddReceiver(final int responseId, final String responseString) { if (responseId != HitoeConstants.RES_ID_SUCCESS || responseString == null) { mFlagForEx = false; return; } int pos = getCurrentPos(responseId); if (pos == -1) { return; } mRegisterDevices.get(pos).setConnectionId(responseString); if (responseString.startsWith(HitoeConstants.RAW_CONNECTION_PREFFIX)) { addBaReceiverProcess(pos); } else { TempExData exData = null; try { mLockForEx.lock(); if (mListForEx.size() > 0) { exData = mListForEx.get(0); mListForEx.remove(0); } else { mFlagForEx = false; } } finally { mLockForEx.unlock(); } if (exData != null) { addExReceiverProcess(pos, exData); } } } /** * Notify Remove receiver. * @param responseId response id * @param responseString response string */ private void notifyRemoveReceiver(final int responseId, final String responseString) { if (responseId != HitoeConstants.RES_ID_SUCCESS || responseString == null) { return; } int pos = getCurrentPos(responseId); if (pos == -1) { return; } mRegisterDevices.get(pos).setRegisterFlag(false); mRegisterDevices.get(pos).removeConnectionId(responseString); mDBHelper.updateHitoeDevice(mRegisterDevices.get(pos)); if (responseString.startsWith(HitoeConstants.BA_CONNECTION_PREFFIX)) { removeRawReceiverProcess(mRegisterDevices.get(pos).getRawConnectionId()); } else if (responseString.startsWith(HitoeConstants.RAW_CONNECTION_PREFFIX)) { disconnectProcess(pos); } } /** * Notify Listeners. * @param receiveDevice now receive device */ private void notifyListeners(final HitoeDevice receiveDevice) { if (mHeartRataListener != null) { mHeartRataListener.onReceivedData(receiveDevice, mHRData.get(receiveDevice)); } if (mECGListener != null) { mECGListener.onReceivedData(receiveDevice, mHRData.get(receiveDevice)); } if (mPoseEstimationListener != null) { mPoseEstimationListener.onReceivedData(receiveDevice, mPoseEstimationData.get(receiveDevice)); } if (mStressEstimationListener != null) { mStressEstimationListener.onReceivedData(receiveDevice, mStressEstimationData.get(receiveDevice)); } if (mWalkStateListener != null) { mWalkStateListener.onReceivedData(receiveDevice, mWalkStateData.get(receiveDevice)); } if (mDeviceOrientationListener != null) { mDeviceOrientationListener.onReceivedData(receiveDevice, mAccelData.get(receiveDevice)); } if (mECGListener != null) { mECGListener.onReceivedData(receiveDevice, mECGData.get(receiveDevice)); } if (mStressEstimationListener != null) { mStressEstimationListener.onReceivedData(receiveDevice, mStressEstimationData.get(receiveDevice)); } if (mPoseEstimationListener != null) { mPoseEstimationListener.onReceivedData(receiveDevice, mPoseEstimationData.get(receiveDevice)); } } /** * Add ba Receiver process. * @param pos device pos */ private void addBaReceiverProcess(final int pos) { List<String> keyList = mRegisterDevices.get(pos).getAvailableBaDataList(); StringBuilder paramStringBuilder = new StringBuilder(); String[] keys = new String[keyList.size()]; String paramString; if (keyList.size() == 0) { return; } for (int i = 0; i < keyList.size(); i++) { keys[i] = keyList.get(i); if (keyList.get(i).equals("ba.extracted_rri")) { if (paramStringBuilder.indexOf("ba.sampling_interval") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.sampling_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_SAMPLING_INTERVAL)); } if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.ecg_threshhold=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_ECG_THRESHHOLD)); if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.ecg_skip_count=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_SKIP_COUNT)); } else if (keyList.get(i).equals("ba.cleaned_rri")) { if (paramStringBuilder.indexOf("ba.sampling_interval") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.sampling_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_SAMPLING_INTERVAL)); } if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.rri_min=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_RRI_MIN)); if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.rri_max=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_RRI_MAX)); if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.sample_count=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_SAMPLE_COUNT)); if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.rri_input=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_RRI_INPUT)); } else if (keyList.get(i).equals("ba.interpolated_rri")) { if (paramStringBuilder.indexOf("ba.freq_sampling_interval") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.freq_sampling_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_FREQ_SAMPLING_INTERVAL)); } if (paramStringBuilder.indexOf("ba.freq_sampling_window") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.freq_sampling_window=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_FREQ_SAMPLING_WINDOW)); } if (paramStringBuilder.indexOf("ba.rri_sampling_rate") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.rri_sampling_rate=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_RRI_SAMPLING_RATE)); } } else if (keyList.get(i).equals("ba.freq_domain")) { if (paramStringBuilder.indexOf("ba.freq_sampling_interval") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.freq_sampling_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_FREQ_SAMPLING_INTERVAL)); } if (paramStringBuilder.indexOf("ba.freq_sampling_window") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.freq_sampling_window=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_FREQ_SAMPLING_WINDOW)); } if (paramStringBuilder.indexOf("ba.rri_sampling_rate") == -1) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.rri_sampling_rate=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_RRI_SAMPLING_RATE)); } } else if (keyList.get(i).equals("ba.time_domain")) { if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.time_sampling_interval=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_TIME_SAMPLING_INTERVAL)); if (paramStringBuilder.length() > 0 && paramStringBuilder.lastIndexOf(HitoeConstants.BR) != paramStringBuilder.length() - 1) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ba.time_sampling_window=") .append(String.valueOf(HitoeConstants.ADD_RECEIVER_PARAM_BA_TIME_SAMPLING_WINDOW)); } } paramString = paramStringBuilder.toString(); int resId = mHitoeSdkAPI.addReceiver(mRegisterDevices.get(pos).getSessionId(), keys, mDataReceiverCallback, paramString, null); mRegisterDevices.get(pos).setResponseId(resId); } /** * Register Ex receiver. * @param pos device pos * @param exData ex data */ private void addExReceiverProcess(final int pos, final TempExData exData) { String keyString = exData.getKey(); ArrayList<String> dataList = exData.getDataList(); if (!mRegisterDevices.get(pos).getAvailableExDataList().contains(keyString)) { try { mLockForEx.lock(); mFlagForEx = false; } finally { mLockForEx.unlock(); } return; } int responseId; String[] keys = new String[1]; keys[0] = keyString; StringBuilder paramStringBuilder = new StringBuilder(); StringBuilder dataStringBuilder = new StringBuilder(); String paramString; String dataString; for (int i = 0; i < dataList.size(); i++) { if (dataStringBuilder.length() > 0) { dataStringBuilder.append(HitoeConstants.BR); } dataStringBuilder.append(dataList.get(i)); } if (keyString.equals("ex.posture")) { if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.acc_axis_xyz=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_ACC_AXIS_XYZ); if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.posture_window=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_POSTURE_WINDOW); } else if (keyString.equals("ex.walk")) { if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.acc_axis_xyz=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_ACC_AXIS_XYZ); if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.walk_stride=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_WALK_STRIDE); if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.run_stride_cof=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_RUN_STRIDE_COF); if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.run_stride_int=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_RUN_STRIDE_INT); } else if (keyString.equals("ex.lr_balance")) { if (paramStringBuilder.length() > 0) { paramStringBuilder.append(HitoeConstants.BR); } paramStringBuilder.append("ex.acc_axis_xyz=") .append(HitoeConstants.ADD_RECEIVER_PARAM_EX_ACC_AXIS_XYZ); } paramString = paramStringBuilder.toString(); dataString = dataStringBuilder.toString(); mHitoeSdkAPI.removeReceiver(null); responseId = mHitoeSdkAPI.addReceiver(null, keys, mDataReceiverCallback, paramString, dataString); if (responseId != HitoeConstants.RES_ID_SUCCESS) { try { mLockForEx.lock(); mFlagForEx = false; } finally { mLockForEx.unlock(); } } } /** * Remove raw receiver process. * @param rawConnectionId raw connection id */ private void removeRawReceiverProcess(final String rawConnectionId) { if (rawConnectionId == null) { return; } mHitoeSdkAPI.removeReceiver(rawConnectionId); } /** * Disconnect Hitoe device. * @param pos hitoe devie position */ private void disconnectProcess(final int pos) { if (pos == -1) { return; } HitoeDevice device = mRegisterDevices.get(pos); if (device.getSessionId() == null) { return; } mRegisterDevices.get(pos).setSessionId(null); mRegisterDevices.get(pos).setRegisterFlag(false); mDBHelper.updateHitoeDevice(mRegisterDevices.get(pos)); mHitoeSdkAPI.disconnect(device.getSessionId()); if (mRegisterDevices.size() == 0) { scanHitoeDevice(false); } } /** * Get Current register device. * @param responseId current response id * @return current register pos */ private int getCurrentPos(final int responseId) { int pos = -1; for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getResponseId() == responseId) { pos = i; break; } } return pos; } /** * Is exist register device. * @param id service id * @return true:exist false: non exist */ private boolean containsDevice(final String id) { boolean isRegister = false; for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getId().equals(id)) { isRegister = true; } } return isRegister; } /** * Get mRegisterDevice's Position for Connection id. * @param connectionId connection Id * @return position */ private int getPosForConnectionId(final String connectionId) { int pos = -1; for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getRawConnectionId() != null) { if (mRegisterDevices.get(i).getRawConnectionId().equals(connectionId)) { pos = i; break; } } if (mRegisterDevices.get(i).getBaConnectionId() != null) { if (mRegisterDevices.get(i).getBaConnectionId().equals(connectionId)) { pos = i; break; } } if (mRegisterDevices.get(i).getExConnectionList().size() > 0) { for (int j = 0; j < mRegisterDevices.get(i).getExConnectionList().size(); j++) { String exConnectionId = mRegisterDevices.get(i).getExConnectionList().get(j); if (exConnectionId == null) { continue; } if (exConnectionId.equals(connectionId)) { pos = i; break; } } } } return pos; } /** * Get mRegisterDevice's Position for service id. * @param serviceId service Id * @return position */ private int getPosForServiceId(final String serviceId) { int pos = -1; for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).getId() != null) { if (mRegisterDevices.get(i).getId().equals(serviceId)) { pos = i; break; } } } return pos; } /** * 周波数領域特徴量データをパースする. * @param receiveDevice ReceiveDevice * @param data 周波数領域特徴量データ */ private void parseFreqDomain(final HitoeDevice receiveDevice, final String data) { String[] lineList = data.split(HitoeConstants.BR); ArrayList<String> stressInputList = new ArrayList<String>(); if (receiveDevice.getAvailableExDataList().contains("ex.stress")) { for (int i = 0; i < lineList.length; i++) { stressInputList.add(lineList[i]); } try { mLockForEx.lock(); mListForEx.add(new TempExData("ex.stress", stressInputList)); } finally { mLockForEx.unlock(); } } } /** * Extract health data. * @param type Health data type * @param rawData raw data * @param receiveDevice Hitoe device */ private void extractHealth(final HeartData.HeartRateType type, final String rawData, final HitoeDevice receiveDevice) { HeartRateData currentHeartRate = mHRData.get(receiveDevice); if (currentHeartRate == null) { currentHeartRate = new HeartRateData(); } if (type == HeartData.HeartRateType.Rate) { HeartData heart = RawDataParseUtils.parseHeartRate(rawData); currentHeartRate.setHeartRate(heart); mHRData.put(receiveDevice, currentHeartRate); } else if (type == HeartData.HeartRateType.RRI) { HeartData rri = RawDataParseUtils.parseRRI(rawData); currentHeartRate.setRRInterval(rri); mHRData.put(receiveDevice, currentHeartRate); } else if (type == HeartData.HeartRateType.EnergyExpended) { HeartData energy = RawDataParseUtils.parseEnergyExpended(rawData); currentHeartRate.setEnergyExpended(energy); mHRData.put(receiveDevice, currentHeartRate); } else if (type == HeartData.HeartRateType.ECG) { HeartData ecg = RawDataParseUtils.parseECG(rawData); currentHeartRate.setECG(ecg); mECGData.put(receiveDevice, currentHeartRate); } } /** * Extract Battery data. * @param rawData raw data * @param receiveDevice Hitoe device */ private void extractBattery(final String rawData, final HitoeDevice receiveDevice) { String[] lineList = rawData.split(HitoeConstants.BR); String levelString = lineList[lineList.length - 1]; String[] level = levelString.split(",", -1); TargetDeviceData current = RawDataParseUtils.parseDeviceData(receiveDevice, Float.parseFloat(level[1])); HeartRateData currentHeartRate = mHRData.get(receiveDevice); if (currentHeartRate == null) { currentHeartRate = new HeartRateData(); } currentHeartRate.setDevice(current); mHRData.put(receiveDevice, currentHeartRate); } /** * Analyze Acceleration data. * Get Posture Data, Walk State data, LR Balance data. * @param rawData raw data * @param receiveDevice receive device */ private void analyzeAccelerationData(final String rawData, final HitoeDevice receiveDevice) { String[] lineList = rawData.split(HitoeConstants.BR); ArrayList<String> postureInputList = new ArrayList<String>(); ArrayList<String> walkInputList = new ArrayList<String>(); ArrayList<String> lrBalanceInputList = new ArrayList<String>(); ArrayList<String> workList = new ArrayList<String>(); for (int i = 0; i < lineList.length; i++) { if (receiveDevice.getAvailableExDataList().contains("ex.posture")) { try { mLockForPosture.lock(); mListForPosture.add(lineList[i]); if (mListForPosture.size() > HitoeConstants.EX_POSTURE_UNIT_NUM + 5) { for (int j = 0; j < HitoeConstants.EX_POSTURE_UNIT_NUM; j++) { postureInputList.add(mListForPosture.get(j)); } for (int j = HitoeConstants.EX_POSTURE_UNIT_NUM; j < HitoeConstants.EX_POSTURE_UNIT_NUM + 5; j++) { postureInputList.add(mListForPosture.get(j)); } workList = new ArrayList<>(); for (int j = 25; j < mListForPosture.size(); j++) { workList.add(mListForPosture.get(j)); } mListForPosture = workList; } } finally { mLockForPosture.unlock(); } if (postureInputList.size() > 0) { try { mLockForEx.lock(); mListForEx.add(new TempExData("ex.posture", postureInputList)); } finally { mLockForEx.unlock(); } postureInputList.clear(); } } if (receiveDevice.getAvailableExDataList().contains("ex.walk")) { try { mLockForWalk.lock(); mListForWalk.add(lineList[i]); if (mListForWalk.size() > HitoeConstants.EX_WALK_UNIT_NUM + 5) { for (int j = 0; j < HitoeConstants.EX_WALK_UNIT_NUM; j++) { walkInputList.add(mListForWalk.get(j)); } for (int j = HitoeConstants.EX_WALK_UNIT_NUM; j < HitoeConstants.EX_WALK_UNIT_NUM + 5; j++) { walkInputList.add(mListForWalk.get(j)); } workList = new ArrayList<>(); for (int j = 25; j < mListForWalk.size(); j++) { workList.add(mListForWalk.get(j)); } mListForWalk = workList; } } finally { mLockForWalk.unlock(); } if (walkInputList.size() > 0) { try { mLockForEx.lock(); mListForEx.add(new TempExData("ex.walk", walkInputList)); } finally { mLockForEx.unlock(); } walkInputList.clear(); } } if (receiveDevice.getAvailableExDataList().contains("ex.lr_balance")) { try { mLockForLRBalance.lock(); mListForLRBalance.add(lineList[i]); if (mListForLRBalance.size() > HitoeConstants.EX_LR_BALANCE_UNIT_NUM + 5) { for (int j = 0; j < HitoeConstants.EX_LR_BALANCE_UNIT_NUM; j++) { lrBalanceInputList.add(mListForLRBalance.get(j)); } for (int j = HitoeConstants.EX_LR_BALANCE_UNIT_NUM; j < HitoeConstants.EX_LR_BALANCE_UNIT_NUM + 5; j++) { lrBalanceInputList.add(mListForLRBalance.get(j)); } workList = new ArrayList<>(); for (int j = 25; j < mListForLRBalance.size(); j++) { workList.add(mListForLRBalance.get(j)); } mListForLRBalance = workList; } } finally { mLockForLRBalance.unlock(); } if (lrBalanceInputList.size() > 0) { try { mLockForEx.lock(); mListForEx.add(new TempExData("ex.lr_balance", lrBalanceInputList)); } finally { mLockForEx.unlock(); } lrBalanceInputList.clear(); } } } } /** * Scan Hitoe device. * @param enable scan flag */ private synchronized void scanHitoeDevice(final boolean enable) { if (enable) { if (mScanning || mScanTimerFuture != null) { // scan have already started. return; } mScanning = true; mIsCallbackRunning = true; mNowTimestamps.clear(); for (HitoeDevice heart: mRegisterDevices) { mNowTimestamps.put(heart, System.currentTimeMillis()); } mScanTimerFuture = mExecutor.scheduleAtFixedRate(new Runnable() { @Override public void run() { for (HitoeDevice heart: mHRData.keySet()) { HeartRateData data = mHRData.get(heart); long timestamp = data.getHeartRate().getTimeStamp(); long history = mNowTimestamps.get(heart); if (BuildConfig.DEBUG) { Log.d(TAG, "================>"); Log.d(TAG, "timestamp:" + timestamp); Log.d(TAG, "history:" + history); Log.d(TAG, "CallbackRunning:" + mIsCallbackRunning); Log.d(TAG, "isRegisterFlag:" + heart.isRegisterFlag()); Log.d(TAG, "<================"); } if (mIsCallbackRunning && history == timestamp && heart.isRegisterFlag()) { final String name = heart.getName(); mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(mContext, "Disconnect to " + name, Toast.LENGTH_SHORT).show(); } }); mIsCallbackRunning = false; } else if (!mIsCallbackRunning && history < timestamp && heart.isRegisterFlag()) { final String name = heart.getName(); mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(mContext, "Connect to " + name, Toast.LENGTH_SHORT).show(); } }); mIsCallbackRunning = true; } mNowTimestamps.put(heart, timestamp); if (heart.isRegisterFlag()) { connectHitoeDevice(heart); } } } }, SCAN_FIRST_WAIT_PERIOD, SCAN_WAIT_PERIOD, TimeUnit.MILLISECONDS); } else { mScanning = false; cancelScanTimer(); } } /** * Stopped the scan timer. */ private synchronized void cancelScanTimer() { if (mScanTimerFuture != null) { mScanTimerFuture.cancel(true); mScanTimerFuture = null; } } /** * Is Exist Disconnected. * @return true:exist connect, false: non exist connect */ private boolean existConnected() { int connectCount = 0; for (int i = 0; i < mRegisterDevices.size(); i++) { if (mRegisterDevices.get(i).isRegisterFlag()) { connectCount++; } } return (connectCount > 0); } // ------------------------------------ // Listener. // ------------------------------------ /** * Hitoe Device Discovery Listener. */ public interface OnHitoeConnectionListener { /** * Connected Device. * @param device Hitoe device */ void onConnected(final HitoeDevice device); /** * Connect fail device. * @param device Hitoe device */ void onConnectFailed(final HitoeDevice device); /** * Discovery Listener. * @param devices Found hitoe devices */ void onDiscovery(List<HitoeDevice> devices); /** * Disconnected Listener. * @param res response id * @param device disconnect device */ void onDisconnected(final int res, final HitoeDevice device); /** * Deleted Listener. * @param device delte device */ void onDeleted(final HitoeDevice device); } /** * Hitoe Device HeartRate Listener. */ public interface OnHitoeHeartRateEventListener { /** * Received data for Hitoe HeartRate data. * @param device Hitoe device * @param data HeartRate data */ void onReceivedData(final HitoeDevice device, final HeartRateData data); } /** * Hitoe Device ECG Listener. */ public interface OnHitoeECGEventListener { /** * Received data for Hitoe ECG Data. * @param device Hitoe device * @param data ECG data */ void onReceivedData(final HitoeDevice device, final HeartRateData data); } /** * Hitoe Device Pose Estimation Listener. */ public interface OnHitoePoseEstimationEventListener { /** * Received data for Hitoe Pose estimation data. * @param device Hitoe device * @param data pose estimation data */ void onReceivedData(final HitoeDevice device, final PoseEstimationData data); } /** * Hitoe Device Stress Estimation Listener. */ public interface OnHitoeStressEstimationEventListener { /** * Received data for Hitoe Stress Estimation data. * @param device Hitoe device * @param data stress estimation data */ void onReceivedData(final HitoeDevice device, final StressEstimationData data); } /** * Hitoe Device Walk State Listener. */ public interface OnHitoeWalkStateEventListener { /** * Received data for Hitoe walk state data. * @param device Hitoe device * @param data walk state */ void onReceivedData(final HitoeDevice device, final WalkStateData data); } /** * Hitoe Device Device Orientation Listener. */ public interface OnHitoeDeviceOrientationEventListener { /** * Received data for Hitoe device orientation data. * @param device Hitoe device * @param data device orientation */ void onReceivedData(final HitoeDevice device, final AccelerationData data); } }