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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
83
The Importance of Being Tested
tiwiz
0
440
An Android Dev start to Kotlin MPP
tiwiz
0
200
Fantastic API and where to find them
tiwiz
0
94
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
Sans tests, vos agents ne sont pas fiables
nabondance
0
170
New "Type" system on PicoRuby
pocke
1
310
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.2k
These Five Tricks Can Make Your Apps Greener, Cheaper, & Nicer
hollycummins
0
230
net-httpのHTTP/2対応について
naruse
0
270
AI 時代のソフトウェア設計の学び方
masuda220
PRO
28
11k
TSKaigi2026-静的解析への投資がAI時代のコード品質を支える ── カスタムESLintルールの設計と運用
hayatokudou
6
1.3k
Inside Stream API
skrb
1
250
~ 秘伝のタレ化した『神スプシ』と戦う ~ 関数型パラダイムで壊れない仕組みへ
h0r15h0
1
140
tsserverとは何だったのか、これからどうなるのか
nowaki28
1
410
[BalkanRuby 2026] Drop your app/services!
palkan
3
710
AIエージェントの隔離技術の徹底比較
kawayu
0
440
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Un-Boring Meetings
codingconduct
0
300
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
580
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
310
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
190
Designing for Timeless Needs
cassininazir
1
230
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
A Soul's Torment
seathinner
6
2.8k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
130
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
30 Presentation Tips
portentint
PRO
1
300
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
170
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