SlideShare a Scribd company logo
1 of 25
Download to read offline
Android Direct Boot
@irgaly
2019/07/11
HealthTech 0.5#3
@TIMESHARING
Summary
• About O:SLEEP
• O:SLEEP Alarm
•
• Android AlarmManager
• Android Doze Mode
• Alarm
• Alarm 1 ~ 3
• Android Direct Boot
•
• Foreground Service
• Direct Boot +
• Conclusion: Problems & Solutions
About O:SLEEP
•
• Android / iOS
•
•
https://play.google.com/store/apps/details?id=jp.oinc.osleep&hl=ja
O:SLEEP Alarm
• 2019/6/24 v1.3.0:
•
•
O:SLEEP Alarm
•
•
•
•
• AlarmManager Intent
•
AlarmManager
setAlarmClock()
PendingIntent Broadcast Intent
O:SLEEP
Notification

Manager

MediaPlayer

Vibrator
AlarmManager
• setExactAndAllowWhileIdle
• API 23 (Android 6.0)~
• “it will not dispatch these alarms more than about every minute (at which
point every such pending alarm is dispatched); when in low-power idle modes
this duration may be significantly longer, such as 15 minutes.”
• Exact 1 ( )
• → Doze Mode ( )
AlarmManagerCompat
AlarmManager
• setAlarmClock
• Doze Mode ( )
• API 21 (Android 5.0) ~
•
AlarmManagerCompat
Doze Mode
•
• Android 6.0 Doze
•
•
•
•
https://developer.android.com/training/monitoring-device-state/doze-
standby?hl=JA
Alarm Notification
Job
Alarm
•
•
•
1
•
•
setAlarmClock() setAlarmClock() setAlarmClock()
Alarm 1
•
setAlarmClock() setAlarmClock()
7:00
GMT+09:00 -> 2019/07/11 07:00 +09:00
GMT+08:00 -> 2019/07/11 07:00 +08:00 ←1
( )
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name=“android.intent.action.TIMEZONE_CHANGED"/>
…
Alarm 2
• AlarmManager
•
• System Locked Boot (Direct Boot, )
• System Boot (Locked Boot )
Locked Boot
setAlarmClock()
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
…
System Boot
setAlarmClock()
Alarm 3
•
• (Broadcast)
•
•
•
setAlarmClock()
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
…
setAlarmClock()
merge
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
</intent-filter>
Locked Boot System Boot
Direct Boot
•
•
https://developer.android.com/training/articles/direct-boot
Direct Boot
• Context Context
• createDeviceProtectedStorageContext Context
Direct Boot
•
fun AlarmRoomDatabase(application: Application):
AlarmRoomDatabase {
// Android 7.0 Direct Boot Context
val context = ContextCompat
.createDeviceProtectedStorageContext(application)
?: application
return Room.databaseBuilder(
context,
AlarmRoomDatabase::class.java,
“AlarmRoomDatabase"
).build()
}
Direct Boot
• LOCKED_BOOT_COMPLETED BroadcastReceiver
• android:directBootAware=“true”: Direct Boot
BroadcastReceiver Service
<receiver
android:name=".app.receiver.SystemEventBroadcastReceiver"
android:directBootAware="true"
tools:targetApi="n">
<intent-filter>
<action
android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
…
</receiver>
<service
android:name=".app.service.AlarmService"
android:directBootAware="true"
tools:targetApi="n"/>
Direct Boot
• Context
Preferences Database
Direct Boot
Context
Context OK
•
•
AlarmSetting
Room SQLite Database
AlarmSchedule
Room SQLite Database
@Entity
data class AlarmSetting(
@PrimaryKey val id: String,
@Embedded(prefix = "time_") val time:
LocalTime,
val repeatDayOfWeek: Set<DayOfWeek>,
val enabled: Boolean,
…
@Entity
data class AlarmSchedule(
@PrimaryKey val id: String,
val alarmSettingId: String,
val time: DateTimeTz,
…
)
Foreground Service
• MediaPlayer
• Android 8.0
• Foreground Service
Android OS
BroadcastReceiverOSLEEP
ForegroundService
ForegroundNotification
Foreground Service
• Notification Channel
• ForegroundNotification
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channel: ChannelType) {
notificationManager.createNotificationChannel(
NotificationChannel(
"alarm",
" ",
NotificationManager.IMPORTANCE_MAX
).apply {
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
}
)
}
class AlarmForegroundService : DaggerService() {
…
override fun onCreate() {
super.onCreate()
startForeground(0, NotificationCompat.Builder(context, "")
.setOngoing(true) //
.setContentTitle(context.getString(R.string.title_alarm_notification))
.setContentText(context.getString(R.string.text_alarm_notification))
.setSmallIcon(R.drawable.ic_notification)
.setCategory(Notification.CATEGORY_ALARM)
.setPriority(PRIORITY_MAX)
.setVisibility(VISIBILITY_PUBLIC)
.setContentIntent(
PendingIntent.getBroadcast(…)
).build())
}
…
Foreground Service
• MediaPlayer
private var _player: MediaPlayer? = null
private val player: MediaPlayer get() {
return _player ?: MediaPlayer().apply {
setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
}.also {
_player = it
}
}
override suspend fun playAlarm(soundUrl: String, repeat: Boolean) =
suspendCoroutine<Unit> { continuation ->
player.apply {
reset()
setDataSource(context, Uri.parse(soundUrl))
isLooping = repeat
setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
prepare()
start()
}
continuation.resume(Unit)
}
Foreground Service
• Vibrator
private val vibrator by lazy {
context.getSystemService<Vibrator>() ?: throw
RuntimeException("Vibrator ")
}
override fun vibrateAlarmRepeat(vibrateTime: TimeSpan, pauseTime:
TimeSpan) {
// OFF 0, ON , OFF... list
val pattern = listOf(0L, vibrateTime.millisecondsLong,
pauseTime.millisecondsLong)
if (Build.VERSION_CODES.O <= Build.VERSION.SDK_INT) {
vibrator.vibrate(
VibrationEffect.createWaveform(
pattern.toLongArray(),
0
),
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
)
} else {
vibrator.vibrate(
pattern.toLongArray(),
0,
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
)
}
}
TimeSpan https://github.com/korlibs/klock
: Direct Boot +
• Direct Boot Media Content Provider
• File Path
• MediaColumns.DATA File Path
private fun getSystemAlarms(): List<AlarmSound> {
return context.contentResolver.query(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI,
null,
"${MediaStore.Audio.Media.IS_ALARM} != 0",
null,
"${MediaStore.Audio.Media.TITLE} ASC"
)?.use { cursor ->
cursor.asSequence().map {
AlarmSound(
it.getString(it.getColumnIndex(MediaStore.Audio.Media.TITLE)),
it.getString(it.getColumnIndex(MediaStore.MediaColumns.DATA))
)
}.toList()
} ?: emptyList()
}
fun Cursor.asSequence(): Sequence<Cursor> {
return generateSequence(seed = takeIf { it.moveToFirst() }) {
takeIf { it.moveToNext() }
}
}
Conclusion: Problems & Solutions
• AlarmManager
• →
• Doze Mode
• → setAlarmClock
• Direct Boot
• → createDeviceProtectedStorageContext
•
• → Foreground Service

More Related Content

What's hot

SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
"CERT Secure Coding Standards" by Dr. Mark Sherman
"CERT Secure Coding Standards" by Dr. Mark Sherman"CERT Secure Coding Standards" by Dr. Mark Sherman
"CERT Secure Coding Standards" by Dr. Mark ShermanRinaldi Rampen
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達zaki4649
 
週末趣味のAWS Transit Gatewayでの経路制御
週末趣味のAWS Transit Gatewayでの経路制御週末趣味のAWS Transit Gatewayでの経路制御
週末趣味のAWS Transit Gatewayでの経路制御Namba Kazuo
 
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話KEISUKE KONISHI
 
node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成shigeki_ohtsu
 
今更聞けないOAuth2.0
今更聞けないOAuth2.0今更聞けないOAuth2.0
今更聞けないOAuth2.0Takahiro Sato
 
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜Masaru Kurahayashi
 
とある診断員とAWS
とある診断員とAWSとある診断員とAWS
とある診断員とAWSzaki4649
 
AWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoTAWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoTAmazon Web Services Japan
 
ウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説するウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説するHiroshi Tokumaru
 
AWS Black Belt Online Seminar 2018 AWS上の位置情報
AWS Black Belt Online Seminar 2018 AWS上の位置情報AWS Black Belt Online Seminar 2018 AWS上の位置情報
AWS Black Belt Online Seminar 2018 AWS上の位置情報Amazon Web Services Japan
 
AWS Black Belt Techシリーズ AWS Key Management Service
AWS Black Belt Techシリーズ AWS Key Management ServiceAWS Black Belt Techシリーズ AWS Key Management Service
AWS Black Belt Techシリーズ AWS Key Management ServiceAmazon Web Services Japan
 
DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]
DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]
DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]DeNA
 
AWS Black Belt Techシリーズ AWS Elastic Beanstalk
AWS Black Belt Techシリーズ  AWS  Elastic  BeanstalkAWS Black Belt Techシリーズ  AWS  Elastic  Beanstalk
AWS Black Belt Techシリーズ AWS Elastic BeanstalkAmazon Web Services Japan
 
20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...
20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...
20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...Amazon Web Services Japan
 
20190320 AWS Black Belt Online Seminar Amazon EBS
20190320 AWS Black Belt Online Seminar Amazon EBS20190320 AWS Black Belt Online Seminar Amazon EBS
20190320 AWS Black Belt Online Seminar Amazon EBSAmazon Web Services Japan
 

What's hot (20)

SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
"CERT Secure Coding Standards" by Dr. Mark Sherman
"CERT Secure Coding Standards" by Dr. Mark Sherman"CERT Secure Coding Standards" by Dr. Mark Sherman
"CERT Secure Coding Standards" by Dr. Mark Sherman
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達
 
週末趣味のAWS Transit Gatewayでの経路制御
週末趣味のAWS Transit Gatewayでの経路制御週末趣味のAWS Transit Gatewayでの経路制御
週末趣味のAWS Transit Gatewayでの経路制御
 
Keycloak入門
Keycloak入門Keycloak入門
Keycloak入門
 
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
 
node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成
 
Black Belt Online Seminar AWS Amazon S3
Black Belt Online Seminar AWS Amazon S3Black Belt Online Seminar AWS Amazon S3
Black Belt Online Seminar AWS Amazon S3
 
Helidon 概要
Helidon 概要Helidon 概要
Helidon 概要
 
今更聞けないOAuth2.0
今更聞けないOAuth2.0今更聞けないOAuth2.0
今更聞けないOAuth2.0
 
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
 
とある診断員とAWS
とある診断員とAWSとある診断員とAWS
とある診断員とAWS
 
AWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoTAWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoT
 
ウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説するウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説する
 
AWS Black Belt Online Seminar 2018 AWS上の位置情報
AWS Black Belt Online Seminar 2018 AWS上の位置情報AWS Black Belt Online Seminar 2018 AWS上の位置情報
AWS Black Belt Online Seminar 2018 AWS上の位置情報
 
AWS Black Belt Techシリーズ AWS Key Management Service
AWS Black Belt Techシリーズ AWS Key Management ServiceAWS Black Belt Techシリーズ AWS Key Management Service
AWS Black Belt Techシリーズ AWS Key Management Service
 
DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]
DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]
DeNAのQCTマネジメント IaaS利用のベストプラクティス [AWS Summit Tokyo 2019]
 
AWS Black Belt Techシリーズ AWS Elastic Beanstalk
AWS Black Belt Techシリーズ  AWS  Elastic  BeanstalkAWS Black Belt Techシリーズ  AWS  Elastic  Beanstalk
AWS Black Belt Techシリーズ AWS Elastic Beanstalk
 
20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...
20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...
20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 ...
 
20190320 AWS Black Belt Online Seminar Amazon EBS
20190320 AWS Black Belt Online Seminar Amazon EBS20190320 AWS Black Belt Online Seminar Amazon EBS
20190320 AWS Black Belt Online Seminar Amazon EBS
 

Similar to Android Direct Boot となにがなんでも鳴るアラームアプリ開発

DEFCON 18- These Aren't the Permissions You're Looking For
DEFCON 18- These Aren't the Permissions You're Looking ForDEFCON 18- These Aren't the Permissions You're Looking For
DEFCON 18- These Aren't the Permissions You're Looking ForMichael Scovetta
 
Being Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentBeing Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentReto Meier
 
Debugging webOS applications
Debugging webOS applicationsDebugging webOS applications
Debugging webOS applicationsfpatton
 
PUG Challenge 2016 - The nativescript pug app challenge
PUG Challenge 2016 -  The nativescript pug app challengePUG Challenge 2016 -  The nativescript pug app challenge
PUG Challenge 2016 - The nativescript pug app challengeBronco Oostermeyer
 
Android 5.0 internals and inferiority complex droidcon.de 2015
Android 5.0 internals and inferiority complex droidcon.de 2015Android 5.0 internals and inferiority complex droidcon.de 2015
Android 5.0 internals and inferiority complex droidcon.de 2015Aleksander Piotrowski
 
Jollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-levelJollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-levelJollen Chen
 
Mitigating data theft_in_android
Mitigating data theft_in_androidMitigating data theft_in_android
Mitigating data theft_in_androidRashmi Bhandari
 
Drilling Cyber Security Data With Apache Drill
Drilling Cyber Security Data With Apache DrillDrilling Cyber Security Data With Apache Drill
Drilling Cyber Security Data With Apache DrillCharles Givre
 
Get step-by-step instructions on implementing notifications in your apps.
Get step-by-step instructions on implementing notifications in your apps.Get step-by-step instructions on implementing notifications in your apps.
Get step-by-step instructions on implementing notifications in your apps.Jigar Maheshwari
 
Cross-platform mobile apps with Apache Cordova
Cross-platform mobile apps with Apache CordovaCross-platform mobile apps with Apache Cordova
Cross-platform mobile apps with Apache CordovaIvano Malavolta
 
Android Workshop 2013
Android Workshop 2013Android Workshop 2013
Android Workshop 2013Junda Ong
 
Introduction to Titanium and how to connect with a PHP backend
Introduction to Titanium and how to connect with a PHP backendIntroduction to Titanium and how to connect with a PHP backend
Introduction to Titanium and how to connect with a PHP backendJoseluis Laso
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with GroovyJames Williams
 
Android OS & SDK - Getting Started
Android OS & SDK - Getting StartedAndroid OS & SDK - Getting Started
Android OS & SDK - Getting StartedHemant Chhapoliya
 
Breaking Smart Speakers: We are Listening to You.
Breaking Smart Speakers: We are Listening to You.Breaking Smart Speakers: We are Listening to You.
Breaking Smart Speakers: We are Listening to You.Priyanka Aash
 
Android Things, from mobile apps to physical world
Android Things, from mobile apps to physical worldAndroid Things, from mobile apps to physical world
Android Things, from mobile apps to physical worldStefano Sanna
 
Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...
Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...
Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...Codemotion
 
Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...
Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...
Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...Codemotion
 
MNT2014: Mobile Hibrido com Phonegap
MNT2014: Mobile Hibrido com PhonegapMNT2014: Mobile Hibrido com Phonegap
MNT2014: Mobile Hibrido com PhonegapLoiane Groner
 

Similar to Android Direct Boot となにがなんでも鳴るアラームアプリ開発 (20)

DEFCON 18- These Aren't the Permissions You're Looking For
DEFCON 18- These Aren't the Permissions You're Looking ForDEFCON 18- These Aren't the Permissions You're Looking For
DEFCON 18- These Aren't the Permissions You're Looking For
 
Being Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentBeing Epic: Best Practices for Android Development
Being Epic: Best Practices for Android Development
 
Debugging webOS applications
Debugging webOS applicationsDebugging webOS applications
Debugging webOS applications
 
PUG Challenge 2016 - The nativescript pug app challenge
PUG Challenge 2016 -  The nativescript pug app challengePUG Challenge 2016 -  The nativescript pug app challenge
PUG Challenge 2016 - The nativescript pug app challenge
 
Android 5.0 internals and inferiority complex droidcon.de 2015
Android 5.0 internals and inferiority complex droidcon.de 2015Android 5.0 internals and inferiority complex droidcon.de 2015
Android 5.0 internals and inferiority complex droidcon.de 2015
 
Jollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-levelJollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-level
 
Mitigating data theft_in_android
Mitigating data theft_in_androidMitigating data theft_in_android
Mitigating data theft_in_android
 
Drilling Cyber Security Data With Apache Drill
Drilling Cyber Security Data With Apache DrillDrilling Cyber Security Data With Apache Drill
Drilling Cyber Security Data With Apache Drill
 
Get step-by-step instructions on implementing notifications in your apps.
Get step-by-step instructions on implementing notifications in your apps.Get step-by-step instructions on implementing notifications in your apps.
Get step-by-step instructions on implementing notifications in your apps.
 
Cross-platform mobile apps with Apache Cordova
Cross-platform mobile apps with Apache CordovaCross-platform mobile apps with Apache Cordova
Cross-platform mobile apps with Apache Cordova
 
Android Workshop 2013
Android Workshop 2013Android Workshop 2013
Android Workshop 2013
 
Introduction to Titanium and how to connect with a PHP backend
Introduction to Titanium and how to connect with a PHP backendIntroduction to Titanium and how to connect with a PHP backend
Introduction to Titanium and how to connect with a PHP backend
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with Groovy
 
Deep Inside Android Hacks
Deep Inside Android HacksDeep Inside Android Hacks
Deep Inside Android Hacks
 
Android OS & SDK - Getting Started
Android OS & SDK - Getting StartedAndroid OS & SDK - Getting Started
Android OS & SDK - Getting Started
 
Breaking Smart Speakers: We are Listening to You.
Breaking Smart Speakers: We are Listening to You.Breaking Smart Speakers: We are Listening to You.
Breaking Smart Speakers: We are Listening to You.
 
Android Things, from mobile apps to physical world
Android Things, from mobile apps to physical worldAndroid Things, from mobile apps to physical world
Android Things, from mobile apps to physical world
 
Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...
Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...
Android Things, from mobile apps to physical world - Stefano Sanna - Giovanni...
 
Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...
Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...
Android Things, from mobile apps to physical world by Giovanni Di Gialluca an...
 
MNT2014: Mobile Hibrido com Phonegap
MNT2014: Mobile Hibrido com PhonegapMNT2014: Mobile Hibrido com Phonegap
MNT2014: Mobile Hibrido com Phonegap
 

Recently uploaded

Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsChandrakantDivate1
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesChandrakantDivate1
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfCWS Technology
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsChandrakantDivate1
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...nishasame66
 

Recently uploaded (6)

Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdf
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 

Android Direct Boot となにがなんでも鳴るアラームアプリ開発

  • 2. Summary • About O:SLEEP • O:SLEEP Alarm • • Android AlarmManager • Android Doze Mode • Alarm • Alarm 1 ~ 3 • Android Direct Boot • • Foreground Service • Direct Boot + • Conclusion: Problems & Solutions
  • 3. About O:SLEEP • • Android / iOS • • https://play.google.com/store/apps/details?id=jp.oinc.osleep&hl=ja
  • 4. O:SLEEP Alarm • 2019/6/24 v1.3.0: • •
  • 6. • AlarmManager Intent • AlarmManager setAlarmClock() PendingIntent Broadcast Intent O:SLEEP Notification
 Manager
 MediaPlayer
 Vibrator
  • 7. AlarmManager • setExactAndAllowWhileIdle • API 23 (Android 6.0)~ • “it will not dispatch these alarms more than about every minute (at which point every such pending alarm is dispatched); when in low-power idle modes this duration may be significantly longer, such as 15 minutes.” • Exact 1 ( ) • → Doze Mode ( ) AlarmManagerCompat
  • 8. AlarmManager • setAlarmClock • Doze Mode ( ) • API 21 (Android 5.0) ~ • AlarmManagerCompat
  • 9. Doze Mode • • Android 6.0 Doze • • • • https://developer.android.com/training/monitoring-device-state/doze- standby?hl=JA Alarm Notification Job
  • 11. Alarm 1 • setAlarmClock() setAlarmClock() 7:00 GMT+09:00 -> 2019/07/11 07:00 +09:00 GMT+08:00 -> 2019/07/11 07:00 +08:00 ←1 ( ) <intent-filter> <action android:name="android.intent.action.TIME_SET"/> <action android:name=“android.intent.action.TIMEZONE_CHANGED"/> …
  • 12. Alarm 2 • AlarmManager • • System Locked Boot (Direct Boot, ) • System Boot (Locked Boot ) Locked Boot setAlarmClock() <intent-filter> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETED"/> … System Boot setAlarmClock()
  • 13. Alarm 3 • • (Broadcast) • • • setAlarmClock() <intent-filter> <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/> … setAlarmClock()
  • 14. merge <intent-filter> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/> <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/> <action android:name="android.intent.action.TIME_SET"/> <action android:name="android.intent.action.TIMEZONE_CHANGED"/> </intent-filter> Locked Boot System Boot
  • 16. Direct Boot • Context Context • createDeviceProtectedStorageContext Context Direct Boot • fun AlarmRoomDatabase(application: Application): AlarmRoomDatabase { // Android 7.0 Direct Boot Context val context = ContextCompat .createDeviceProtectedStorageContext(application) ?: application return Room.databaseBuilder( context, AlarmRoomDatabase::class.java, “AlarmRoomDatabase" ).build() }
  • 17. Direct Boot • LOCKED_BOOT_COMPLETED BroadcastReceiver • android:directBootAware=“true”: Direct Boot BroadcastReceiver Service <receiver android:name=".app.receiver.SystemEventBroadcastReceiver" android:directBootAware="true" tools:targetApi="n"> <intent-filter> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> … </receiver> <service android:name=".app.service.AlarmService" android:directBootAware="true" tools:targetApi="n"/>
  • 18. Direct Boot • Context Preferences Database Direct Boot Context Context OK
  • 19. • • AlarmSetting Room SQLite Database AlarmSchedule Room SQLite Database @Entity data class AlarmSetting( @PrimaryKey val id: String, @Embedded(prefix = "time_") val time: LocalTime, val repeatDayOfWeek: Set<DayOfWeek>, val enabled: Boolean, … @Entity data class AlarmSchedule( @PrimaryKey val id: String, val alarmSettingId: String, val time: DateTimeTz, … )
  • 20. Foreground Service • MediaPlayer • Android 8.0 • Foreground Service Android OS BroadcastReceiverOSLEEP ForegroundService ForegroundNotification
  • 21. Foreground Service • Notification Channel • ForegroundNotification @RequiresApi(Build.VERSION_CODES.O) private fun createNotificationChannel(channel: ChannelType) { notificationManager.createNotificationChannel( NotificationChannel( "alarm", " ", NotificationManager.IMPORTANCE_MAX ).apply { lockscreenVisibility = Notification.VISIBILITY_PUBLIC } ) } class AlarmForegroundService : DaggerService() { … override fun onCreate() { super.onCreate() startForeground(0, NotificationCompat.Builder(context, "") .setOngoing(true) // .setContentTitle(context.getString(R.string.title_alarm_notification)) .setContentText(context.getString(R.string.text_alarm_notification)) .setSmallIcon(R.drawable.ic_notification) .setCategory(Notification.CATEGORY_ALARM) .setPriority(PRIORITY_MAX) .setVisibility(VISIBILITY_PUBLIC) .setContentIntent( PendingIntent.getBroadcast(…) ).build()) } …
  • 22. Foreground Service • MediaPlayer private var _player: MediaPlayer? = null private val player: MediaPlayer get() { return _player ?: MediaPlayer().apply { setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK) }.also { _player = it } } override suspend fun playAlarm(soundUrl: String, repeat: Boolean) = suspendCoroutine<Unit> { continuation -> player.apply { reset() setDataSource(context, Uri.parse(soundUrl)) isLooping = repeat setAudioAttributes( AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_ALARM) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build() ) prepare() start() } continuation.resume(Unit) }
  • 23. Foreground Service • Vibrator private val vibrator by lazy { context.getSystemService<Vibrator>() ?: throw RuntimeException("Vibrator ") } override fun vibrateAlarmRepeat(vibrateTime: TimeSpan, pauseTime: TimeSpan) { // OFF 0, ON , OFF... list val pattern = listOf(0L, vibrateTime.millisecondsLong, pauseTime.millisecondsLong) if (Build.VERSION_CODES.O <= Build.VERSION.SDK_INT) { vibrator.vibrate( VibrationEffect.createWaveform( pattern.toLongArray(), 0 ), AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_ALARM) .build() ) } else { vibrator.vibrate( pattern.toLongArray(), 0, AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_ALARM) .build() ) } } TimeSpan https://github.com/korlibs/klock
  • 24. : Direct Boot + • Direct Boot Media Content Provider • File Path • MediaColumns.DATA File Path private fun getSystemAlarms(): List<AlarmSound> { return context.contentResolver.query( MediaStore.Audio.Media.INTERNAL_CONTENT_URI, null, "${MediaStore.Audio.Media.IS_ALARM} != 0", null, "${MediaStore.Audio.Media.TITLE} ASC" )?.use { cursor -> cursor.asSequence().map { AlarmSound( it.getString(it.getColumnIndex(MediaStore.Audio.Media.TITLE)), it.getString(it.getColumnIndex(MediaStore.MediaColumns.DATA)) ) }.toList() } ?: emptyList() } fun Cursor.asSequence(): Sequence<Cursor> { return generateSequence(seed = takeIf { it.moveToFirst() }) { takeIf { it.moveToNext() } } }
  • 25. Conclusion: Problems & Solutions • AlarmManager • → • Doze Mode • → setAlarmClock • Direct Boot • → createDeviceProtectedStorageContext • • → Foreground Service