Filter
-
Content Type
-
Category
Mobile/Wearable
Visual Display
Digital Appliance
Platform
Recommendations
Filter
tutorials health, galaxy watch
blogin our using health services on galaxy watch article, we introduced you to health services and the series of steps you need to follow in order to start using it within your application. now, we present the different client types provided by health services and their core functionality. exerciseclient in recent years, many applications that use and process health data are focused on workouts due to increasing awareness of the importance of maintaining a healthy lifestyle. some of those applications are more complex than others and have a lot of features, from tracking exercise performance to setting daily, weekly or monthly goals. health services provides a specialized client to facilitate tracking ongoing workouts from a wide range of exercise types, such as running, playing soccer and skiing, among others. checking the capabilities on the device as mentioned in our previous post, you have to ensure at runtime that your configuration is supported. remember, there is nothing more confusing to users than dealing with an application that does not work as expected. the code below describes how to check the capabilities of the device for an exercise type for running: healthservicesclient healthclient = healthservices.getclient(this); exerciseclient exerciseclient = healthclient.getexerciseclient(); listenablefuture<exercisecapabilities> capabilitiesfuture = passiveclient.getcapabilities(); futures.addcallback(capabilitiesfuture, new futurecallback<exercisecapabilities>() { @override public void onsuccess(@nullable exercisecapabilities result) { runningcapabilities = result .supporteddatatypesexcercise() .contains(exercisetype.running) } @override public void onfailure(throwable t) { // display an error } }, contextcompat.getmainexecutor(this)); tracking workouts using exerciseclient after ensuring that the device running your application supports the type of exercise(s) you want to track, you must specify the relevant information, such as exercise type, exercise goal, and additional parameters supported by health services. health services provides an exerciseconfig class to help you to define a configuration for an exercise tracked by your application. with the help of this class, you can define and have access to information related to the exercise such as: exercise type exercise goals data type of the exercise flags to indicate the exercise state once you set up your configuration, you can start your exercise and then listen for its progress using an update listener. the basic setup flow should be something like: set up exerciseconfig call exerciseclient.startexercise set up an update listener listen for progress and update your app finally, health services provides a useful class to set goals and keep track of them. the exercisegoal class allows you to set goals based on certain parameters, so the users of your application can create milestones or one-time goals. an example of a milestone could be a hiking app that sets a goal that is achieved multiple times when the user has covered a distance of 200m. the event is triggered every 200m. in contrast, a one-time goal could be defined as a goal that sets a milestone with a threshold equivalent to the height of mount everest. the ability to work with exercise goals in health services will be described in more detail in a separate post. note: when using exerciseclient, make sure your app requests and maintains the necessary permissions. if your app uses location data, you should consider permissions on the device, like checking that gps is enabled. also, you should ensure that a foregroundservice with the appropriate foregroundservicetype is maintained throughout the workout, as shown in the code below: <!-- add foreground service location permission for exercise tracking --> <service android:name=".exerciseservice" android:foregroundservicetype="location" android:exported="false" /> measureclient using this client is highly recommended if your application requires constant updates. in a real-world scenario, your application should use this client when its ui is in the foreground. as a good practice, your application should minimize the amount of time reading data with this client. registering callbacks to read health data can increase sensor sampling rates, increasing power consumption. use this client carefully, having user experience in mind and taking into account that users want to extend the power of the device as much as possible. checking the capabilities on the device healthservicesclient healthclient = healthservices.getclient(this); listenablefuture<measurecapabilities> capabilitiesfuture = healthclient.getcapabilities(); futures.addcallback(capabilitiesfuture, new futurecallback<capabilities>() { @override public void onsuccess(@nullable capabilities result) { boolean supportsheartrate = result .supporteddatatypesmeasure() .contains(datatype.heart_rate_bpm) } @override public void onfailure(throwable t) { // handle error here. } }, contextcompat.getmainexecutor(this)); passivemonitoringclient this client is suitable for applications that monitor health data in the background. this client makes it easier to keep track of activities during longer periods of time, taking advantage of the fact that it does not require your application to be in the foreground. some examples of activities tracked by this client are step count or floors climbed during the day, week or month. checking the capabilities on the device healthservicesclient healthclient = healthservices.getclient(this); passivemonitoringclient passiveclient = healthclient.getpassivemonitoringclient(); listenablefuture<passivemonitoringcapabilities> capabilitiesfuture = passiveclient.getcapabilities(); futures.addcallback(capabilitiesfuture, new futurecallback<passivemonitoringcapabilities>() { @override public void onsuccess(@nullable passivemonitoringcapabilities result) { supportsheartrate = result .getsupporteddatatypespassivemonitoring() .contains(datatype.heart_rate_bpm) supportsstepsevent = result .supporteddatatypesevents() .contains(datatype.steps) } @override public void onfailure(throwable t) { // display an error } }, contextcompat.getmainexecutor(this)); choosing the right health services client having a clear understanding of every client type and their applications help you to make informed decisions when creating your application. this information helps you avoid unexpected results while interacting with the sensors on the device and it improves the overall user experience of your application. receiving health data updates in the background to receive data updates in the background, your application must have a broadcastreceiver declared in its androidmanifest.xml, as we mentioned in our previous post. the updates from health services regarding passive data is delivered to this receiver. so far, we have presented the key features for every client. you can make a more informed and confident decision of how to make the most of health services within your application. we encourage you to check health services to take advantage of all of these features.
Develop Health
doctracking sweat loss notetracking sweat loss is available only for a running exercise samsung health sensor sdk provides tracking sweat loss after an exercise implementation of the sweat loss tracker differs a little from other tracker types, as it requires one more step – feeding the tracker with additional data the ‘steps per minute’ value provided from another source such as wear os’s health services library in addition, the tracker object requires one more element – trackeruserprofile which includes weight, height, age, and gender the following steps describe how to track sweat loss data getting a healthtracker instance for sweat loss after successfully connecting to the healthtrackingservice, a starting point is to get a healthtracker instance healthtrackingservice gethealthtracker healthtrackertype, trackeruserprofile, exercisetype the trackeruserprofile should be set with trackeruserprofile builder private trackeruserprofile profile; // set the user profile profile = new trackeruserprofile builder setheight height setweight weight setgender gender setage age build ; create a healthtracker instance for sweat loss with the user profile from the example above and the exercisetype running private healthtracker sweatlosstracker = null; // after healthtrackingservice connectservice is called private final connectionlistener connectionlistener = new connectionlistener { @override public void onconnectionsuccess { try { // get a healthtracker instance for sweat loss sweatlosstracker = healthtrackingservice gethealthtracker healthtrackertype sweat_loss, profile, com samsung android service health tracking data exercisetype running ; } catch final illegalargumentexception e { // exception handling } catch final unsupportedoperationexception e { // exception handling } } // override other functions of the listener }; set the event listener we discuss the listener later // set an event listener for getting sweat loss data sweatlosstracker seteventlistener trackereventlistener ; starting an exercise with health services during the exercise, you should keep feeding sweat loss tracker with steps_per_minute such data is available through health services create an exerciseclient and set the event listener for an exercise data update private exerciseclient exerciseclient; private void initexerciseclient { if exerciseclient == null { exerciseclient = healthservicesclientprovider getclient context getexerciseclient ; exerciseclient setupdatecallback exerciseupdatecallback ; } } configure a running exercise so that it can track steps_per_minute and distance steps_per_minute is later sent to health tracker using healthtracker setexercisedata and distance is helpful to check an error case when a sweat loss’s status is not zero final exerciseconfig builder exerciseconfigbuilder = exerciseconfig builder exercisetype running setdatatypes new hashset<> arrays aslist datatype distance, steps_per_minute setisautopauseandresumeenabled false setisgpsenabled false ; the data from health services comes in exerciseupdatecallback private final exerciseupdatecallback exerciseupdatecallback = new exerciseupdatecallback { @override public void onexerciseupdatereceived exerciseupdate update { // ‘steps per minute’ values are represented as sample data points extractstepsperminute update getlatestmetrics getsampledatapoints ; // use update getlatestmetrics getintervaldatapoints to get access // to such data as ‘distance’ } // override other functions of the callback }; setting the exercise state to start start the exercise using exerciseclient startexerciseasync after configuring and starting the exercise in health services, it is time to set the exercise state to start on the sweat loss tracker try { // set the exercise state to start sweatlosstracker setexercisestate exercisestate start ; } catch final illegalstateexception e { // exception handling } extracting exercise data and sending them to the tracker the example below shows how to extract ‘steps per minute’ from onexerciseupdatereceived exerciseupdate exerciseupdate they reside in exerciseupdate getlatestmetrics getsampledatapoints private void extractstepsperminute list<sampledatapoint<?>> datapoints { final int listsize = datapoints size ; final float[] spmdata = new float[listsize]; final long[] timestamp = new long[listsize]; for sampledatapoint<?> element datapoints { if element getdatatype equals steps_per_minute { spmdata[datapoints indexof element ] = long objects requirenonnull element getvalue ; timestamp[datapoints indexof element ] = getutctimefromsystemelapsedtime objects requirenonnull element gettimedurationfromboot tomillis ; } } if listsize > 0 { sweatlosstracker setexercisedata steps_per_minute, stepsperminutevalues, stepsperminutetimestamps ; } } we send the exercise data - steps_per_minute to samsung health sensor sdk’s sweat loss tracker using healthtracker setexercisedata monitoring the distance and duration of the exercise is helpful if the exercise’s duration is less than 5 minutes or the distance is less than 2 kilometers, samsung health sensor sdk gives an error in a sweat loss’ status for more errors of sweatlossset status, see samsung health sensor sdk’s api reference setting the exercise state with stop if you decide to finish the exercise, set the exercise state to stop on the tracker @override public void endexercise boolean exception, string state { try { sweatlosstracker setexercisestate exercisestate stop ; } catch final illegalstateexception e { // exception handling } } you should also stop the exercise in the context of health services using exerciseclient endexerciseasync checking the tracker event listener if the running exercise is finished, sweat loss data is available in healthtracker trackereventlistener check a sweat loss’s value and its status private final healthtracker trackereventlistener trackereventlistener = new healthtracker trackereventlistener { @override public void ondatareceived @nonnull list<datapoint> list { if list size != 0 { float sweatloss = list get 0 getvalue valuekey sweatlossset sweat_loss ; int status = list get 0 getvalue valuekey sweatlossset status ; if status == 0 // no error else // check status and handle an error } ; } else { // no data } } @override public void onflushcompleted { // } @override public void onerror healthtracker trackererror trackererror { if trackererror == healthtracker trackererror permission_error { // permission handling } if trackererror == healthtracker trackererror sdk_policy_error { // check a device’s network or submit a query in samsung dev site } // } }; unsetting the tracker event listener after getting the final sweat loss tracker, unset the registered tracker’s event listener sweatlosstracker unseteventlistener ; for more information about sweat loss tracking, refer to the sweat loss monitor sample app
Develop Health
dochow to implement the sweat loss monitor application the following flow chart represents the order of invocation of the health services main functions and the health tracking service ones, and the interaction between both the libraries the following image represents an overview of the main classes used in the sweat loss example application the sweatingbucketsservice is a foreground service, which controls both healthservicesmanager and trackingservicemanager it starts when the user presses the start button and it stops after user stops the exercise, and gets the final sweat loss value when the user destroys the activity by swiping right during the active exercise, the application will continue to work in the background in the foreground service the user knows about the running application from the notification when the user opens the application again either via notification or by tapping the application icon , the new activity will show the current exercise status a similar event occurs when the application goes to the background i e when the screen goes into the sleep mode in this case, the activity is not destroyed, only get onstop event the user can bring the activity back by tapping the notification to observe the current exercise status and, after tapping the stop button, to get the final sweat loss result sweatingbucketsservice is responsible for collecting the results from the health services and the health tracking service and exchanging the data between both the services it also reports the following status values to the ui status for sweat loss measurement sweat loss value exercise distance exercise duration average steps per minute current steps per minute connection errors not available capabilities it uses android's messenger mechanism to establish a two-way communication with the ui runtime permissions in order to measure the sweat loss, we need to get the following permissions body_sensors to use the samsung health sensor sdk’s sweat loss tracker activity_recognition for measuring the steps per minute during a running exercise additionally, we also need foreground_service to be able to continue measurement in the background internet to resolve the samsung health sensor sdk’s healthtrackingservice connection error for baklava and newer android versions, we need to replace body_sensors with com samsung android hardware sensormanager permission read_additional_health_data and foreground_service with more granulated foreground_service_health the application will display the permissions popup immediately after the start capabilities before using the health services and the samsung health sensor sdk’s apis, let us check whether the galaxy watch can measure the sweat loss we need to check availability of the following capabilities from health services exercisetype running datatype steps_per_minute datatype distance from samsung health sensor sdk healthtrackertype sweat_loss all the capabilities from both the services should be checked immediately after the application launch so that the user is informed, as soon as possible, about any problems capabilities check with health services health services is used to measure a running exercise in order to check the capabilities of the running exercise measurement with health services, we first need to obtain the exerciseclient object exerciseclient = healthservices getclient context getexerciseclient ; we need to check the capabilities of the running exercise type, steps_per_minute and distance the capabilities come asynchronously public static void checkcapabilities exerciseclient exerciseclient, healthservicescapabilitieseventlistener listener { futures addcallback exerciseclient getcapabilitiesasync , new futurecallback<exercisecapabilities> { @override public void onsuccess exercisecapabilities result { log i tag, "setexercisecapabilities onsuccess " ; final boolean runningcapabilityavailable = result getsupportedexercisetypes contains exercisetype running ; final boolean stepsperminutecapabilityavailable = result getexercisetypecapabilities exercisetype running getsupporteddatatypes contains steps_per_minute ; final boolean distancecapabilityavailable = result getexercisetypecapabilities exercisetype running getsupporteddatatypes contains datatype distance ; listener onhealthservicescapabilitiesavailabilityresult runningcapabilityavailable && stepsperminutecapabilityavailable, distancecapabilityavailable ; } @override public void onfailure @nonnull throwable t { log i tag, "setexercisecapabilities onfailure , throwable message " + t getmessage ; } }, executors newsinglethreadexecutor ; } the onhealthservicescapabilitiesavailabilityresult listener informs the viewmodel about the results of the capabilities check capabilities check with health tracking service sweat loss is measured with the samsung health sensor sdk after a running exercise if the version of the galaxy watch’s software or the samsung health sensor sdk’s library is old, measuring sweat loss may not be available therefore, checking the capabilities of samsung health sensor sdk is required before starting the measurement first, get the healthtrackingservice object and set a connection listener to connect to the samsung health sensor sdk’s health tracking service healthtrackingservice = new healthtrackingservice healthtrackingserviceconnectionlistener, myapp getappcontext ; the connection listener will be covered in the following sections after connecting to the tracking service, we can check the capabilities this time it is a synchronous call public static boolean hascapabilities context context { if healthtrackingserviceconnection getinstance context isconnected { final list<healthtrackertype> availabletrackers = healthtrackingserviceconnection getinstance context gethealthtrackingservice gettrackingcapability getsupporthealthtrackertypes ; if availabletrackers contains healthtrackertype sweat_loss { log i tag, "the system does support sweat loss tracking" ; return true; } } log e tag, "the system does not support sweat loss tracking" ; return false; } if any of the mandatory capabilities are not available, the application cannot work correctly we should display a failure message to the user setting up and starting the exercise when the user starts the exercise, he taps the start button the request goes to the sweatingbucketsservice, which in turn requests the healthservicesmanager to start the exercise we need to configure the exercise to provide us with the steps per minute and distance using exerciseconfig setting the exercise type exercisetype running setting interesting data types for a running exercise datatype steps_per_minute and datatype distance then, invoke exerciseclient startexerciseasync the implementation of the process looks like this protected void startexercise throws runtimeexception { final exerciseconfig builder exerciseconfigbuilder = exerciseconfig builder exercisetype running setdatatypes new hashset<> arrays aslist datatype distance, steps_per_minute setisautopauseandresumeenabled false setisgpsenabled false ; log i tag, "calling startexerciseasync" ; futures addcallback exerciseclient startexerciseasync exerciseconfigbuilder build , new futurecallback<void> { @override public void onsuccess @nullable void result { log i tag, "startexerciseasync onsuccess " ; } @override public void onfailure @nonnull throwable t { log i tag, "startexerciseasync onfailure starting exercise " + t getmessage ; healthserviceseventlistener onexerciseerror r string exercise_starting_error ; } }, executors newsinglethreadexecutor ; } we show the distance on the watch’s screen and the steps per minute data are sent to the healthtracker object for further processing more on this in below sections steps per minute is an instantaneous value, which is fine when we pass it to the healthtracker, as it expects such format however, we should process it to display the preferred average value to the user the distance value received indicates the distance between the current and the previous readings to display the distance value to the user, we first need to sum all the values from the beginning of the exercise subscribing to updated exercise data health services enables a watch application to receive the running exercise’s data update and to manage the exercise’s lifetime we obtained the exerciseclient in capabilities check now, we set update callback to receive the exercise results including steps per minute and distance exerciseclient setupdatecallback exerciseupdatecallback ; in the callback, we receive the updated exercise state information and the latest exercise data private final exerciseupdatecallback = new exerciseupdatecallback { @override public void onexerciseupdatereceived exerciseupdate update { log i tag, "exerciseupdate update " + update ; exercisestate = update getexercisestateinfo getstate ; log i tag, "exercise state " + exercisestate ; if exercisestate == exercisestate active { if !wasexerciseactive { healthserviceseventlistener onexercisebecomeactive ; } } else { wasexerciseactive = false; if exercisestate == exercisestate ended { switch update getexercisestateinfo getendreason { case exerciseendreason user_end healthserviceseventlistener onexerciseuserended ; break; case exerciseendreason auto_end_superseded log i tag, "exercise terminated it was superseded by other exercise, started by other client " ; healthserviceseventlistener onexerciseautoended r string error_exercise_terminated ; break; case exerciseendreason auto_end_permission_lost log i tag, "exercise permission lost " ; healthserviceseventlistener onexerciseautoended r string error_exercise_permission_lost ; break; } } } wasexerciseactive = exercisestate == exercisestate active; updateintervaldatapoints update getlatestmetrics getintervaldatapoints ; updatesampledatapoints update getlatestmetrics getsampledatapoints ; } }; the detailed exercise state is returned with the update callback as update getexercisestateinfo getstate ; we can start tracking when the state becomes active and stop tracking when it becomes ended the ended status can have several reasons available in update getexercisestateinfo getendreason user_end the exercise ended by the user auto_end_superseded the exercise object has been superseded by another application auto_end_permission_lost the permission has been revoked by the user we should display an error message when the reason is not user_end the exercise results updates are typically received every second, but when the application goes to the background after a couple of seconds, the battery saving mechanism is activated, resulting in the data being updated every 150 secs, i e 2 5 min the results' resolution remains the same, but the data come in batches in the example, the application data is sent to the sweatingbucketsservice via callbacks ondistancedatareceived, onstepsperminutedatareceived the data is sent immediately to the health tracking service connecting to the health tracking service first, connect to the health tracking service private static final connectionlistener connectionlistener = new connectionlistener { @override public void onconnectionsuccess { log i tag, "connection to healthtrackingservice succeeded " ; connected = true; healthtrackingserviceconnectionlistener onhealthtrackingserviceconnectionresult true ; } @override public void onconnectionended { log i tag, "connection to healthtrackingservice ended " ; connected = false; } @override public void onconnectionfailed healthtrackerexception e { connected = false; log i tag, "connection to healthtrackingservice failed error message " + e getmessage ; if e hasresolution { healthtrackingserviceconnectionlistener onhealthtrackingserviceconnectionerrorwithresolution e ; } else { healthtrackingserviceconnectionlistener onhealthtrackingserviceconnectionresult false ; } } }; private static void inithealthtrackingservice { if healthtrackingservice == null { healthtrackingservice = new healthtrackingservice connectionlistener, myapp getappcontext ; } } we are informing the sweatlossviewmodel about the result using callback with onhealthtrackingserviceconnectionresult boolean result in the sweat loss monitor application the samsung health sensor sdk provides apis to resolve connection exceptions if the watch’s health platform is not installed, or its version is old to run the sdk’s library in the error cases, we can check the error’s resolution and resolve them by calling the sdk’s healthtrackerexception hasresolution and healthtrackerexception resolve to check the error’s resolution, the internet permission is required resolving the exception entails being redirected to a view, which downloads the health platform application on the watch setting an event listener to get a sweat loss result once we connect, it is time to acquire the healthtracker object to use the sweat loss feature try { sweatlosstracker = healthtrackingserviceconnection getinstance context gethealthtrackingservice gethealthtracker healthtrackertype sweat_loss, new userprofile gettrackeruserprofile , com samsung android service health tracking data exercisetype running ; } catch final illegalargumentexception e { log i tag, "tracker not created, an exception " + e getmessage ; } the sweat loss amount varies depending on the user’s height, weight, age, and gender set the user profile information with the userprofile object we can define the trackeruserprofile as public class userprofile { public trackeruserprofile gettrackeruserprofile { // the following user profile values are needed for sweat loss calculations // in the real market-ready application the numbers should be editable in ui // height in cm final float height = 182f; // weight in kg final float weight = 80f; // gender 0 woman, 1 man final int gender = 1; final int age = 45; final trackeruserprofile builder builder = new trackeruserprofile builder ; builder setheight height ; builder setweight weight ; builder setgender gender ; builder setage age ; return builder build ; } } to get the sweat loss result, set a trackereventlistener private final healthtracker trackereventlistener trackereventlistener = new healthtracker trackereventlistener { @override public void ondatareceived @nonnull list<datapoint> list { log i tag, "ondatareceived invoked " ; final valuekey<float> sweatlossvaluekey = valuekey sweatlossset sweat_loss; final valuekey<integer> statusvaluekey = valuekey sweatlossset status; // there is always up to 1 element in the list if !list isempty { log i tag, "ondatareceived list size is " + list size + ", timestamp " + list get 0 gettimestamp ; final float sweatloss = list get 0 getvalue sweatlossvaluekey ; final int status = list get 0 getvalue statusvaluekey ; sweatlossstatus = status; sweatlossvalue = sweatloss; log i tag, "sweat loss " + sweatloss + " status " + status ; final boolean finalresult = finalresult status, sweatloss ; //unset listener right after getting final result if finalresult unsettrackerupdatelistener ; trackingserviceeventlistener onsweatlossdatareceived status, sweatloss, finalresult ; } else { log i tag, "ondatareceived list size is null" ; } } @override public void onflushcompleted { log i tag, " onflushcompleted called" ; } @override public void onerror healthtracker trackererror trackererror { if trackererror == healthtracker trackererror permission_error { trackingserviceeventlistener onhealthtrackererror r string tracker_error_permission_error ; } if trackererror == healthtracker trackererror sdk_policy_error { trackingserviceeventlistener onhealthtrackererror r string tracker_error_sdk_policy_denied ; } } }; start an exercise and setting the exercise’s state to start when the user taps the start button on the sweat loss monitor application, we start the exercise in health services by calling startexerciseasync when the exercise starts, we should set the sweatlosstracker’s exercise state to start sweatlosstracker setexercisestate exercisestate start ; during the exercise, the watch’s related sensors measure the exercise and health services updates the exercise’s steps per minute and distance in the background the updated steps per minute must be sent to the sweat loss healthtracker with healthtracker setexercisedata public void feedtrackerwithstepsperminutedata float[] stepsperminutevalues, long[] stepsperminutetimestamps { log i tag, "feedtrackerwithstepsperminutedata " ; final datatype steps_per_minute = datatype step_per_minute; try { log i tag, "feed tracker with stepsperminute data " + arrays tostring stepsperminutevalues ; sweatlosstracker setexercisedata steps_per_minute, stepsperminutevalues, stepsperminutetimestamps ; } catch final illegalargumentexception e { log i tag, " error data spm " + arrays tostring stepsperminutevalues + " utctime " + stepsperminutetimestamps[0] ; } catch final illegalstateexception e { log i tag, e getmessage ; } } get a sweat loss measurement result after the exercise when the user taps the stop button on the sweat loss monitor application to end the exercise, stop the exercise with health services as follows invoke exerciseclient stopexerciseasync wait until the status of the exercise read in update callback changes to ended inform the healthtracker about the stopped exercise to set the sweat loss healthtracker’s exercise state to stop, just invoke sweatlosstracker setexercisestate exercisestate stop ; it gives the final sweat loss measurement result through trackereventlistener that we have set in setting an event listener to get a sweat loss result the result includes the sweat loss amount and the sweat loss measurement result’s status flag see the samsung health sensor sdk’s api reference document for the sweat loss status details unset the sweat loss event listener after receiving the sweat loss result, unset the sweat loss healthtracker’s event listener sweatlosstracker unseteventlistener ; after unsetting the update listener, the watch’s sensors used by healthtracker will stop working
tutorials health, galaxy watch
bloghealth services provides an advanced set of apis that allow your application to take full advantage of the powerful hardware available on galaxy watches running wear os powered by samsung. thanks to this careful combination of hardware and software, applications are able to reliably track information from sensors in the watch. this solution allows developers to specify what type of data they are using in their applications, as well as allowing users to decide what data can be processed and accessed. getting things ready to take advantage of health services health services works on devices such as galaxy watch4 and galaxy watch4 classic operating on wear os powered by samsung. health services requires android 11 (api level 30) or above. add required information to your app’s configuration files to start using health services in a new or existing android studio project, you just need to follow a series of steps described below: add the appropriate library dependency to your app’s build.gradle file. dependencies { implementation 'androidx.health:health-services-client:1.0.0-alpha03 // ... } in your app’s android manifest, add the necessary configuration to allow your app to connect with the health service. <queries> <package android:name="com.google.android.wearable.healthservices" /> </queries> add the permissions required by your app. <uses-permission android:name="android.permission.body_sensors" /> <uses-permission android:name="android.permission.activity_recognition" /> <uses-permission android:name="android.permission.foreground_service" /> <uses-permission android:name="android.permission.access_fine_location" /> in order to improve the security of your application and to ensure a good user experience, you should only add the permissions that are required by your application from the list above. additionally, if your application features passive monitoring, you have to add the lines below to your app’s manifest to register the health event broadcast receiver. <receiver android:name="com.samsung.android.eventsmonitor.eventbroadcastreceiver" android:exported="true"> <intent-filter> <action android:name="hs.passivemonitoring.health_event" /> </intent-filter> <receiver/> requesting permissions programmatically apart from being registered in the app’s manifest, permissions have to be requested programmatically to validate and get user consent at runtime. the code below shows how to request these permissions: requestpermissions(new string[] {manifest.permission.body_sensors, manifest.permission.foreground_service, manifest.permission.activity_recognition, manifest.permission.access_fine_location}, 0); at runtime, if your application has requested the permissions correctly, a popup similar to the one below appears after the execution of your application: to get the result of the permission request you have made previously, you should check the result as shown in the code below: @override public void onrequestpermissionsresult(int requestcode, @nonnull string[] permissions, @nonnull int[] grantresults) { if(requestcode == 0) { list<string> notgrantedpermissions= new linkedlist<>(); setpermissiongranted(true); for(int i=0; i<permissions.length; i++) { if(grantresults[i] == permission_denied) { setpermissiongranted(false); notgrantedpermissions.add(permissions[i]); } } if(!getpermissiongranted()) { // handle permission denied here. } } super.onrequestpermissionsresult(requestcode,permissions,grantresults); } checking the device capabilities there is nothing more annoying than an application that does not work as expected, causing a bad user experience or even worse, a crash. fortunately, health services provides a way to verify if the current setup you have configured supports the functionality required. it accomplishes this by using apis to get the capabilities and supported data types for the current configuration. this allows developers to handle errors and decide the best way to notify the users of the app about potential problems. the code below is an example of the usage of such apis for exerciseclient: // connection to the health services healthservicesclient healthclient = healthservices.getclient(this); exerciseclient exerciseclient = healthclient.getexerciseclient(); listenablefuture<exercisecapabilities> capabilitiesfuture = passiveclient.getcapabilities(); futures.addcallback(capabilitiesfuture, new futurecallback<exercisecapabilities>() { @override public void onsuccess(@nullable exercisecapabilities result) { runningcapabilities = result .supporteddatatypesexcercise() .contains(exercisetype.running) } @override public void onfailure(throwable t) { // display an error } }, contextcompat.getmainexecutor(this)); enjoy your adventure creating the ultimate health application now that you have finally set up health services in your app’s project, you are ready to start using the apis to enhance the capabilities of your application. we encourage you to check our next series of posts to discover even more from health services on galaxy watch!
Learn Code Lab
codelabtrack deadlift exercise on galaxy watch objective create a native app for galaxy watch, operating on wear os powered by samsung, using health services to track deadlift exercise this app measures repetition count, calories burned, and time spent during the exercise overview health services provides a simple and unified way for accessing a wide range of health and wellness related data with health services api, you will no longer need to develop your own algorithms processing sensors data in order to compute metrics like heart rate, steps counts, distance, calories burned, and other more these are now accessible through health services embedded on wearables operating on wear os powered by samsung see health platform descriptions for detailed information set up your environment you will need the following galaxy watch4 or newer android studio latest version recommended java se development kit jdk 11 or later sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! health track deadlift sample code 132 83 kb turn on developer mode and adjust its settings on your watch, go to settings > about watch > software and tap on software version 5 times upon successful activation of developer mode, a toast message will display as on the image below afterwards, developer options will be visible under settings tap developer options and enable the following options adb debugging debug over wi-fi turn off automatic wi-fi connect your galaxy watch to wi-fi go to settings > connection > wi-fi and make sure that wi-fi is enabled from the list of available wi-fi networks, choose and connect to the same one as your pc when successfully connected, tap a wi-fi network name, swipe down, and note the ip address you will need this to connect your watch over adb from your pc connect your galaxy watch to android studio in android studio, go to terminal and type adb connect <ip address as mentioned in previous step> when prompted, tap always allow from this computer to allow debugging upon successful connection, you will see the following message in android studio’s terminal connected to <ip address of your watch> now, you can run the app directly on your watch start your project after downloading the sample code containing the project files, open your android studio and click open to open an existing project locate the downloaded android project deadlift from the directory and click ok check dependency and app manifest in the dependencies section of gradle scripts > build gradle module app file, see the appropriate dependency for health services dependencies { implementation 'androidx health health-services-client 1 0 0-beta03' // } notesince the library might update from time to time, it is recommended to choose the version suggested by android studio in androidmanifest xml file, note the following <queries> element <queries> <package android name="com google android wearable healthservices" /> </queries> section with requests for necessary permissions <uses-permission android name="android permission body_sensors" /> <uses-permission android name="android permission activity_recognition" /> check capabilities to check what can be measured during an exercise, you need to check its capabilities go to app > java > com samsung sdc21 deadlift open the deadliftutil java file and navigate to the checkcapabilities method an inner class c definition implements the methods of the futurecallback interface within this definition, define the onsuccess method to retrieve the exercise type capabilities public void onsuccess exercisecapabilities result { objects requirenonnull result ; log i tag, "got exercise capabilities" ; /*********************************************************************************** * [practice 1] define the onsuccess method * * - hint uncomment lines below and replace todo 1 * call getexercisetypecapabilities method of result object, * passing already initialized t as an argument **********************************************************************************/ final exercisetype t = exercisetype deadlift; // final exercisetypecapabilities capabilities = "todo 1" // final exerciseconfig builder builder = exerciseconfig builder t ; // builder setdatatypes capabilities getsupporteddatatypes ; // exerciseconfigbuilder = builder; } next, implement the findcapabilitesfuture method to get a callback with exercisecapabilities getcapabilitiesasync returns the exercisecapabilities of the exerciseclient for the device static listenablefuture<exercisecapabilities> findcapabilitiesfuture exerciseclient client { /******************************************************************************************* * [practice 1] create a listenablefuture object that will get a callback with * with exercise capabilities choose the correct method from exerciseclient * * - hint uncomment line and replace null with todo 2 * for checking capabilities use getcapabilitiesasync method ******************************************************************************************/ return null; //"todo 2"; } start the exercise inside the startexercise method, there is a call to the futures addcallback method this method adds a callback function that executes when the asynchronous operation of starting the exercise completes set an update callback for the exercise client within the onsuccess method of the callback function public void onsuccess void result { log i tag, "successfully started" ; /*************************************************************************** * [practice 2] set an update callback * * - hint uncomment lines below and fill todos * 1 make appropriate call of setupdatecallback method * and pass exerciseupdatelistener object as an argument * 2 change ismeasurementrunning flag value to true **************************************************************************/ // exerciseclient setupdatecallback "todo 3 1 " ; log i tag, "successfully set update listener" ; // "todo 3 2 " } in the deadlift java file, call the startexercise method in onbuttonclickhelper public void onbuttonclickhelper { /******************************************************************************************* * [practice 2] start the exercise using a method from deadliftutil java * * - hint uncomment line below and fill todo 4 * call startexercise method on util object * ****************************************************************************************/ // "todo 4" } get the results go to the deadliftutil java file, and in the getnewrepsvalue method, call the getlatestmetrics method from the exerciseupdate class to get the data collected during the exercise store the data in the resultlist, where the last element holds the most up-to-date value of all your repetitions public long getnewrepsvalue exerciseupdate update, deltadatatype<long, intervaldatapoint<long>> datatype { /******************************************************************************************* * [practice 3] get the data collected during exercise * * - hint uncomment lines below and fill todo 5 * call getlatestmetrics method of exerciseupdate object * then, get the data of appropriate type * for this, you can use dedicated method getdata , passing datatype as an argument * ****************************************************************************************/ // final list<intervaldatapoint<long>> resultlist = "todo 5" // if !resultlist isempty { // final int lastindex = resultlist size - 1; // return resultlist get lastindex getvalue ; // } return no_new_value; } run unit tests for your convenience, you will find an additional unit tests package this will let you verify your code changes even without using a physical watch see instruction below on how to run unit tests right click on com samsung sdc21 deadlift test > deadliftunittest and execute run 'deadliftunittest' command if you completed all the tasks correctly, you will see all the unit tests passed successfully run the app after building the apk, you can run the application on a connected device to measure actual deadlift parameters right after the app is started, it will request for the user permission allow the app to receive data of the activity afterwards, the application main screen will be shown before doing deadlifts, press the start button to track your exercise when done, tap on the stop button you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a deadlift exercise tracker app by yourself! if you're having trouble, you may download this file health track deadlift complete code 132 42 kb learn more by going to health platform
tutorials health, galaxy watch
bloggalaxy watch offers a convenient way of measuring exercise progress. modern sensors designed specifically for health services provide the most precise readings. after connecting to health services, you can measure certain exercises and track their values. this blog describes all the important steps to build an exercise tracking app using the health services api. we use example code introduced in health code lab for tracking exercise. you can download the source code from this code lab. health services defines a variety of exercise types. for a full exercise type list, take a look at exercisetype. on galaxy watch4 and galaxy watch4 classic, a repetition counter is available for the following exercises: back_extension barbell_shoulder_press bench_press bench_sit_up burpee crunch deadlift forward_twist dumbbell_curl_right_arm dumbbell_front_raise dumbbell_lateral_raise dumbbell_triceps_extension_left_arm dumbbell_triceps_extension_right_arm dumbbell_triceps_extension_two_arm dumbbell_curl_left_arm jump_rope jumping_jack lat_pull_down lunge squat upper_twist in this application, we are going to use deadlift. the example code used for deadlift can be easily adapted to track all repetition-based exercises. the basics of connecting to health services are covered in the blog using health services on galaxy watch. setting up an exercise once connected to the health services api, we are ready to set up the exercise. in this case we use deadlift as a sample exercise. first, we need to get the exercise client: exerciseclient exerciseclient = client.getexerciseclient(); after that, we need to set the exercise type in the configuration builder: exercisetype exercisetype = exercisetype.deadlift exerciseconfigbuilder exerciseconfigbuilder = exerciseconfig.builder() .setexercisetype(exercisetype); to see what can be tracked for our exercise, we need to check its capabilities. we do this by using a listenablefuture object and listening for a callback from health services. listenablefuture<exercisecapabilities> capabilitieslistenablefuture = exerciseclient.getcapabilities(); when we receive a callback, we can receive a set with capabilities: futurecallback<exercisecapabilities>() { @override public void onsuccess(@nullable exercisecapabilities result) { try { exercisetypecapabilities exercisetypecapabilities = result.getexercisetypecapabilities(exercisetype); set<datatype> exercisecapabilitiesset = exercisetypecapabilities.getexercisecapabilities(result); } if you do not want to track some of these values, at this point, you can remove them from a set. by default, all datatypes that a certain exercise can measure are being stored as a set. by removing them before setting up a configuration builder, you can exclude tracking unnecessary values. once we are ready, we can finish configuring an exercise: exerciseconfigbuilder = exerciseconfig.builder() .setexercisetype(exercisetype) .setdatatypes(exercisecapabilitiesset); setting up exercise listener an exercise listener is an object that allows us to get exercise updates from health services, whenever they are available. to set up the listener, we need to override three methods: exerciseupdatelistener exerciseupdatelistener = new exerciseupdatelistener() { @override public void onexerciseupdate(exerciseupdate update) { //processing your update } @override public void onavailabilitychanged(datatype datatype, availability availability) { //processing availability } @override public void onlapsummary(exerciselapsummary summary) { //processing lap summary } }; starting and stopping the exercise we are ready to start tracking our exercise. to do that, we use the listenablefuture object that gets callbacks from the healthservices api whenever an update is available. to build this object, we send our configuration to the exercise client while starting measurement: listenablefuture<void> startexerciselistenablefuture = exerciseclient.startexercise(exerciseconfigbuilder.build()); when we get a callback from the healthservices api, we start our listener: listenablefuture<void> updatelistenablefuture = exerciseclient.setupdatelistener(exerciseupdatelistener); we finish exercise in a similar way, by creating a listenablefuture object that asks the health services api to stop tracking exercise: listenablefuture<void> endexerciselistenablefuture = exerciseclient.endexercise() processing exercise update data exercise update data contains various information about the performed exercise. after setting up a listener, we retrieve it in a callback: public void onexerciseupdate(@nonnull exerciseupdate update) { try { updaterepcount(update); } catch (deadliftexception exception) { log.e(tag, "error getting exercise update: ", exception); } } in this example, we focus on one of most important readings—latest metrics. we store them in a map: map<datatype, list<datapoint>> map = update.getlatestmetrics(); now we can read particular values by looking for their key: list<datapoint> reppoints = map.get(datatype.rep_count); list<datapoint> caloriespoints = map.get(datatype.total_calories); the last value on the list is the latest reading in the current update. we can use it in our application, for example, when updating a label: string repvalue = string.format("%d", iterables.getlast(reppoints).getvalue().aslong()); txtreps.settext(string.format("reps count: %s", repvalue)); this is how exercise data can be accessed and processed using health services on galaxy watch. it’s a quick and convenient way to track its progress that everybody can implement into a watch application.
Develop Health
docsweat loss monitor samsung offers the samsung health sensor sdk available for the galaxy watch running wear os the sdk’s apis allow a watch application to track various health sensor data based on a rich set of sensors that are supported by galaxy watch one of such data is the sweat loss after an exercise to track other health sensor data, see samsung health sensor sdk what is required to get the sweat loss value in order to use the sweat loss measurement functionality, the following environment is required galaxy watch 4 series or later models, running wear os, powered by samsung latest watch software version which apis are used to measure the sweat loss a watch application will use the following sdk and apis mainly to calculate the sweat loss value samsung health sensor sdk healthtrackingservice connecting to the health tracking service, obtaining a sweat loss tracker healthtracker setting an event listener to receive the sweat loss value health services exerciseclient a client for tracking a particular exercise parameters, in our case, steps per minute during running which data is used to calculate the sweat loss the samsung health sensor sdk calculates the sweat loss based on the following data user’s profile weight, height, age, gender exercise type the samsung health sensor sdk supports only the running exercise processed data from the watch’s sensors e g heart rate exercise data collected by health services steps per minute are fed to the healthtracker to help calculate the accurate sweat loss amount the sweat loss can be assessed only when the following requirements are met exercise duration longer than 5 minutes running distance longer than 2 kilometers sweat loss amount 100 milliliters or greater non-zero heart rate values during a workout 80% or greater non-zero spm steps per minute values during a workout 80% or greater spm values during a workout 110 or greater
We use cookies to improve your experience on our website and to show you relevant advertising. Manage you settings for our cookies below.
These cookies are essential as they enable you to move around the website. This category cannot be disabled.
These cookies collect information about how you use our website. for example which pages you visit most often. All information these cookies collect is used to improve how the website works.
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and tailor the website to provide enhanced features and content for you.
These cookies gather information about your browser habits. They remember that you've visited our website and share this information with other organizations such as advertisers.
You have successfully updated your cookie preferences.