Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Wellness & Droid
Search
Roberto Orgiu
April 04, 2022
Programming
130
0
Share
Wellness & Droid
Slides of the talk I gave at Droidcon Italy together with Daniele Bonaldo
Roberto Orgiu
April 04, 2022
More Decks by Roberto Orgiu
See All by Roberto Orgiu
Behind the curtains
tiwiz
0
79
The Importance of Being Tested
tiwiz
0
430
An Android Dev start to Kotlin MPP
tiwiz
0
190
Fantastic API and where to find them
tiwiz
0
88
Flipping the Koin @ GDG Dev Party
tiwiz
1
78
Flipping the Koin
tiwiz
2
180
Trip into the async world @ NYC Kotlin Meetup
tiwiz
0
130
Trip into the async world
tiwiz
1
150
GraphQL IRL (Android Makers)
tiwiz
0
160
Other Decks in Programming
See All in Programming
(Re)make Regexp in Ruby: Democratizing internals for the JIT
makenowjust
3
1k
Spec Driven Development | AI Summit Vilnius
danielsogl
PRO
1
150
Back to the roots of date
jinroq
0
810
JCON - Create Agentic AI Apps, The Easy Way!
kdubois
1
110
GitHubCopilotCLIをはじめよう.pdf
htkym
0
330
Claude CodeでETLジョブ実行テストを自動化してみた
yoshikikasama
0
1.2k
[RubyKaigi 2026] Require Hooks
palkan
1
310
ソースコード→AST→オペコード、の旅を覗いてみる
o0h
PRO
1
130
20260514_its_the_context_window_stupid.pdf
heita
0
960
いつか誰かが、と思っていた フロントエンド刷新5年間の実践知
kiichisugihara
1
270
ふにゃっとしない名前の付け方 〜哲学で茹で上げる、コシのあるソフトウェア設計〜
shimomura
0
120
Explore CoroutineScope
tomoeng11
0
190
Featured
See All Featured
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
110
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
190
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
530
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.7k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Designing for Performance
lara
611
70k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
180
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
150
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
210
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
350
Typedesign – Prime Four
hannesfritz
42
3k
Making Projects Easy
brettharned
120
6.6k
Transcript
WELLNESS & DROID Photo by Jeremy Thomas on Unsplash
Daniele Bonaldo @danybony_ Roberto Orgiu @_ tiwiz
SLEEP EXERCISE RECORD
ACTIVITY RECOGNITION API EXERCISE
Let’s get started •Track user •Compute distance •Steps measurement
Getting last user’s location //Manifest.permission.ACCESS_FINE_LOCATION private val client = LocationServices.getFusedLocationProviderClient(
activity ) client.lastLocation.addOnSuccessListener { location -> . .. }
Getting updates on user’s location private val locationCallback = object
: LocationCallback() { override fun onLocationResult(r: LocationResult) { // calculate here } }
Getting updates on user’s location val locationRequest = LocationRequest .create().apply
{ priority = PRIORITY_HIGH_ACCURACY interval = 5000 }
Getting updates on user’s location client.requestLocationUpdates( locationRequest, locationCallback, Looper.getMainLooper() )
Compute distances SphericalUtil .computeDistanceBetween( lastLatLng, oldLatLng )
class StepCounter( private val activity: AppCompatActivity ) : SensorEventListener Every
step counts
Every step counts private val sensorManager : SensorManager = activity.getSystemService(SENSOR_SERVICE)
private val stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER) private var initialSteps = -1
Every step counts fun setupStepCounter() { if (stepCounterSensor != null)
{ sensorManager.registerListener(this, stepCounterSensor, SENSOR_DELAY_FASTEST) } } fun unloadStepCounter() { if (stepCounterSensor != null) { sensorManager.unregisterListener(this) } }
Every step counts override fun onSensorChanged(event: SensorEvent) { event.values.firstOrNull() ?.
toInt() ?. let { newSteps -> if (initialSteps == -1) { initialSteps = newSteps } currentSteps = newSteps - initialSteps } } override fun onAccuracyChanged( sensor: Sensor, accuracy: Int ) = Unit
SLEEP EXERCISE RECORD
SLEEP SLEEP RECOGNITION API
Sleep classify event Sleep segment event
Sleep segment event •Start timestamp •End timestamp •Duration •Status •Successful
•Not detected •Missing data
Sleep classify event •Confidence •Light level •Motion level •Timestamp
M T W T F S S
M T W T F S S
Setup Requirements •Android API Level > v29 •Android Build Tools
> v21 •Google Play Services Dependency •com.google.android.gms:play-services-location:21.0.0
Receiver Android Manifest <receiver android:name=".receiver.SleepReceiver" android:enabled="true" android:exported="true" />
Receiver Android Manifest <receiver android:name=".receiver.SleepReceiver" android:enabled="true" android:exported="true" /> SleepReceiver :
BroadcastReceiver() override fun onReceive(context: Context, intent: Intent) { if (SleepSegmentEvent.hasEvents(intent)) { .. . } else if (SleepClassifyEvent.hasEvents(intent)) { .. . } }
Permissions Android Manifest <uses-permission android:name=“android.permission.ACTIVITY_RECOGNITION" />
Permissions Android Manifest <uses-permission android:name=“android.permission.ACTIVITY_RECOGNITION" / > MainActivity ContextCompat.checkSelfPermission( context,
permission.ACTIVITY_RECOGNITION )_
Permissions Android Manifest <uses-permission android:name=“android.permission.ACTIVITY_RECOGNITION" / > MainActivity ContextCompat.checkSelfPermission(context,permission.ACTIVITY_RECOGNITION)_ val
requestPermissionLauncher: ActivityResultLauncher<String> = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> if (!isGranted) { … } else { // ready } } requestPermissionLauncher.launch(permission.ACTIVITY_RECOGNITION)
Permissions Android Manifest <uses-permission android:name=“android.permission.ACTIVITY_RECOGNITION" / > MainActivity ContextCompat.checkSelfPermission(context,permission.ACTIVITY_RECOGNITION)_ val
requestPermissionLauncher: ActivityResultLauncher<String> = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> if (!isGranted) { requestActivityRecognitionPermission() } else { // ready } } requestPermissionLauncher.launch(permission.ACTIVITY_RECOGNITION) private fun requestActivityRecognitionPermission() { val intent = Intent().apply { action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS data = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null) flags = Intent.FLAG_ACTIVITY_NEW_TASK } startActivity(intent) }
Subscribe to sleep updates MainActivity ActivityRecognition.getClient(context) .requestSleepSegmentUpdates( pendingIntent, SleepSegmentRequest.getDefaultSleepSegmentRequest() )
Confidence Motion Light Segments
SLEEP EXERCISE RECORD
GOOGLE FIT API RECORD
Choose options val fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.build()
Request permissions val account = GoogleSignIn.getAccountForExtension( activity, fitnessOptions) if (!GoogleSignIn.hasPermissions(account,
fitnessOptions)) { GoogleSignIn.requestPermissions( activity, PERMISSIONS_REQUEST_CODE, account, fitnessOptions) } else { recordToGoogleFit() }
Choose options override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
{ super.onActivityResult(requestCode, resultCode, data) when (resultCode) { Activity.RESULT_OK - > when (requestCode) { PERMISSIONS_REQUEST_CODE -> recordToGoogleFit() else -> { . .. } } else - > { ... } } }
Create a session val session = Session.Builder() .setName("Today's Run") .setIdentifier("Unique_Identifier_Here")
.setDescription("Long run around home") .setActivity(FitnessActivities.RUNNING) .setStartTime(startTime, TimeUnit.MILLISECONDS) .setEndTime(endTime, TimeUnit.MILLISECONDS) .build()
Create a request val insertRequest = SessionInsertRequest.Builder() .setSession(session) .build()
Insert request Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions) ) .insertSession(insertRequest) .addOnSuccessListener { ...
} .addOnFailureListener { e -> ... }
Q&A Photo by Simone Secci on Unsplash