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
100
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
47
The Importance of Being Tested
tiwiz
0
390
An Android Dev start to Kotlin MPP
tiwiz
0
150
Fantastic API and where to find them
tiwiz
0
60
Flipping the Koin @ GDG Dev Party
tiwiz
1
48
Flipping the Koin
tiwiz
2
140
Trip into the async world @ NYC Kotlin Meetup
tiwiz
0
91
Trip into the async world
tiwiz
1
110
GraphQL IRL (Android Makers)
tiwiz
0
140
Other Decks in Programming
See All in Programming
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
3
500
git worktree × Claude Code × MCP ~生成AI時代の並列開発フロー~
hisuzuya
1
590
코딩 에이전트 체크리스트: Claude Code ver.
nacyot
0
840
脱Riverpod?fqueryで考える、TanStack Queryライクなアーキテクチャの可能性
ostk0069
0
310
NPOでのDevinの活用
codeforeveryone
0
870
Azure AI Foundryではじめてのマルチエージェントワークフロー
seosoft
0
190
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
2
150
チームのテスト力を総合的に鍛えて品質、スピード、レジリエンスを共立させる/Testing approach that improves quality, speed, and resilience
goyoki
5
980
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
570
Python型ヒント完全ガイド 初心者でも分かる、現代的で実践的な使い方
mickey_kubo
1
150
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
140
Rubyでやりたい駆動開発 / Ruby driven development
chobishiba
1
740
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
What's in a price? How to price your products and services
michaelherold
246
12k
Balancing Empowerment & Direction
lara
1
440
Fireside Chat
paigeccino
37
3.5k
Six Lessons from altMBA
skipperchong
28
3.9k
4 Signs Your Business is Dying
shpigford
184
22k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.7k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
How to train your dragon (web standard)
notwaldorf
96
6.1k
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