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
0
84
Wellness & Droid
Slides of the talk I gave at Droidcon Italy together with Daniele Bonaldo
Roberto Orgiu
April 04, 2022
Tweet
Share
More Decks by Roberto Orgiu
See All by Roberto Orgiu
Behind the curtains
tiwiz
0
28
The Importance of Being Tested
tiwiz
0
350
An Android Dev start to Kotlin MPP
tiwiz
0
120
Fantastic API and where to find them
tiwiz
0
42
Flipping the Koin @ GDG Dev Party
tiwiz
1
36
Flipping the Koin
tiwiz
2
130
Trip into the async world @ NYC Kotlin Meetup
tiwiz
0
70
Trip into the async world
tiwiz
1
92
GraphQL IRL (Android Makers)
tiwiz
0
140
Other Decks in Programming
See All in Programming
バグを見つけた?それAppleに直してもらおう!
uetyo
0
180
fs2-io を試してたらバグを見つけて直した話
chencmd
0
230
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
230
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
330
17年周年のWebアプリケーションにTanStack Queryを導入する / Implementing TanStack Query in a 17th Anniversary Web Application
saitolume
0
250
HTTP compression in PHP and Symfony apps
dunglas
2
1.7k
Go の GC の不得意な部分を克服したい
taiyow
2
770
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
300
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
1
150
nekko cloudにおけるProxmox VE利用事例
irumaru
3
420
クリエイティブコーディングとRuby学習 / Creative Coding and Learning Ruby
chobishiba
0
3.9k
php-conference-japan-2024
tasuku43
0
220
Featured
See All Featured
A Philosophy of Restraint
colly
203
16k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Facilitating Awesome Meetings
lara
50
6.1k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
We Have a Design System, Now What?
morganepeng
51
7.3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
How GitHub (no longer) Works
holman
311
140k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.1k
Adopting Sorbet at Scale
ufuk
73
9.1k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Agile that works and the tools we love
rasmusluckow
328
21k
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