Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Privacy Changes in Android Q

Privacy Changes in Android Q

I/O ’19 Extended in Korea Android
Android Q 부터 새로운 privacy 변경 사항 및 앱에 미치는 영향과 이를 어떻게 해결 하는지에 대해 알아봅니다.
- background app에 대한 새로운 제한사항
- 안드로이드 기기 고유 식별자 제한

David Ha

June 15, 2019
Tweet

More Decks by David Ha

Other Decks in Programming

Transcript

  1. "OESPJEIBTNBOZ
 QSJWBDZGFBUVSFT 4&-JOVY $POUFOU#BTFE1FSNJTTJPOT -PDLEPXO.PEF (VFTU.PEF 3VOUJNFQFSNJTTJPOT (PPHMF1MBZ1SPUFDU "QQMJDBUJPO4BOECPYJOH 'JMF#BTFE&ODSZQUJPO

    &ODSZQUFECBDLVQT )BSEXBSFQSPUFDUFE"1*T 3FTUSJDUFECBDLHSPVOEBDDFTTUPNJDDBNFSB4FOTPS.BOBHFS 4FDVSF%/4 5-4CZ%FGBVMU
  2. "OENBOZNPSFUP "OESPJE2 1FSNJTTJPO6TBHF 3FNJOEFS "DUJWJUZ3FDPHOJUJPO1FSNJTTJPO "QQ*DPO)BOEMJOH .BJOMJOF 'PSFHSPVOE4FSWJDF .PSF-PDBUJPO$POUSPM 1SJWBDZ"MFSUT

    -PDBUJPO3FNJOEFST 3PMFT $POUBDUT1SPWJEFS #BDLHSPVOE"QQ -BVODIJOH %FWJDF*%3FTUSJDUJPOT -PDBUJPO4FUUJOHT 4ZTUFN'JMF1JDLFS 1FSNJTTJPO4FUUJOHT 4DSFFO3FDPSEJOH ."$3BOEPNJ[BUJPO $BNFSB*OUFOUT "DDFTTJCJMJUZ
 6TBHF4FUUJOH "QQ4UPSBHF
  3. "OENBOZNPSFUP "OESPJE2 1FSNJTTJPO6TBHF 3FNJOEFS "DUJWJUZ3FDPHOJUJPO1FSNJTTJPO "QQ*DPO)BOEMJOH .BJOMJOF 'PSFHSPVOE4FSWJDF .PSF-PDBUJPO$POUSPM 1SJWBDZ"MFSUT

    -PDBUJPO3FNJOEFST 3PMFT $POUBDUT1SPWJEFS #BDLHSPVOE"QQ -BVODIJOH %FWJDF*%3FTUSJDUJPOT -PDBUJPO4FUUJOHT 4ZTUFN'JMF1JDLFS 1FSNJTTJPO4FUUJOHT 4DSFFO3FDPSEJOH ."$3BOEPNJ[BUJPO $BNFSB*OUFOUT "DDFTTJCJMJUZ
 6TBHF4FUUJOH "QQ4UPSBHF
  4. 4UBSU"DUJWJUZJOUIF#BDLHSPVOE override fun onMessageReceived(message: RemoteMessage?) { ... goLiveConsIncomingActivity(this) } fun

    goLiveConsIncomingActivity(context: Context) { val intent = Intent(context, LiveConsIncomingActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) }
  5. 4UBSU"DUJWJUZJOUIF#BDLHSPVOE override fun onMessageReceived(message: RemoteMessage?) { ... goLiveConsIncomingActivity(this) } fun

    goLiveConsIncomingActivity(context: Context) { val intent = Intent(context, LiveConsIncomingActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) }
  6. TFU'VMM4DSFFO*OUFOU private fun showIncomingCallNotification(channelId: String) { ... NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.noti_icon)

    ... .setContentIntent(getContentIntent()) .setFullScreenIntent(getContentIntent(), true) .build() ... } private fun getContentIntent(): PendingIntent { val intent = Intent(a, LiveConsIncomingActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK return PendingIntent.getActivity(this, REQUEST_CONTENT, intent, PendingIntent.FLAG_UPDATE_CURRENT) }
  7. TFU'VMM4DSFFO*OUFOU private fun showIncomingCallNotification(channelId: String) { ... NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.noti_icon)

    ... .setContentIntent(getContentIntent()) .setFullScreenIntent(getContentIntent(), true) .build() ... } private fun getContentIntent(): PendingIntent { val intent = Intent(a, LiveConsIncomingActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK return PendingIntent.getActivity(this, REQUEST_CONTENT, intent, PendingIntent.FLAG_UPDATE_CURRENT) }
  8. TFU'VMM4DSFFO*OUFOU private fun showIncomingCallNotification(channelId: String) { ... NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.noti_icon)

    ... .setContentIntent(getContentIntent()) .setFullScreenIntent(getContentIntent(), true) .build() ... } private fun getContentIntent(): PendingIntent { val intent = Intent(a, LiveConsIncomingActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK return PendingIntent.getActivity(this, REQUEST_CONTENT, intent, PendingIntent.FLAG_UPDATE_CURRENT) }
  9. TFU'VMM4DSFFO*OUFOU public Notification.Builder setFullScreenIntent (PendingIntent intent, boolean highPriority) ↟)FBETVQOPUJGJDBUJPOXJMMBQQFBSBOEXJMMOPUBVUPNBUJDBMMZEJTBQQFBS ↟JG/PUJGJDBUJPO$IBOOFMJNQPSUBODFJTOPUTFU

    )FBETVQOPUJGJDBUJPOEPOPUBQQFBS ↟"QQTUBSHFUJOH#VJME7&34*0/@$0%&42BOEBCPWFXJMMIBWFUPSFRVFTUBQFSNJTTJPO
 .BOJGFTUQFSNJTTJPO64&@'6--@4$3&&/@*/5&/5
  10. TFU'VMM4DSFFO*OUFOU public Notification.Builder setFullScreenIntent (PendingIntent intent, boolean highPriority) ↟)FBETVQOPUJGJDBUJPOXJMMBQQFBSBOEXJMMOPUBVUPNBUJDBMMZEJTBQQFBS ↟JG/PUJGJDBUJPO$IBOOFMJNQPSUBODFJTOPUTFU

    )FBETVQOPUJGJDBUJPOEPOPUBQQFBS ↟"QQTUBSHFUJOH#VJME7&34*0/@$0%&42BOEBCPWFXJMMIBWFUPSFRVFTUBQFSNJTTJPO
 .BOJGFTUQFSNJTTJPO64&@'6--@4$3&&/@*/5&/5
  11. $SFBUFBIJHIQSJPSJUZOPUJGJDBUJPO NotificationChannel("LIVE_CONS_FOR_USER", "Live ࢚׸", NotificationManager.IMPORTANCE_HIGH).apply { description = "Live ࢚׸

    ঌܿ" enableLights(true) enableVibration(true) lightColor = Color.RED vibrationPattern = longArrayOf(0, 400, 200, 400, 1000) lockscreenVisibility = Notification.VISIBILITY_PUBLIC }
  12. $SFBUFBIJHIQSJPSJUZOPUJGJDBUJPO NotificationChannel("LIVE_CONS_FOR_USER", "Live ࢚׸", NotificationManager.IMPORTANCE_HIGH).apply { description = "Live ࢚׸

    ঌܿ" enableLights(true) enableVibration(true) lightColor = Color.RED vibrationPattern = longArrayOf(0, 400, 200, 400, 1000) lockscreenVisibility = Notification.VISIBILITY_PUBLIC }
  13. TFU'VMM4DSFFO*OUFOU public Notification.Builder setFullScreenIntent (PendingIntent intent, boolean highPriority) ↟)FBETVQOPUJGJDBUJPOXJMMBQQFBSBOEXJMMOPUBVUPNBUJDBMMZEJTBQQFBS ↟JG/PUJGJDBUJPO$IBOOFMJNQPSUBODFJTOPUTFU

    )FBETVQOPUJGJDBUJPOEPOPUBQQFBS ↟"QQTUBSHFUJOH#VJME7&34*0/@$0%&42BOEBCPWFXJMMIBWFUPSFRVFTUBQFSNJTTJPO
 .BOJGFTUQFSNJTTJPO64&@'6--@4$3&&/@*/5&/5
  14. TFU'VMM4DSFFO*OUFOU public Notification.Builder setFullScreenIntent (PendingIntent intent, boolean highPriority) ↟)FBETVQOPUJGJDBUJPOXJMMBQQFBSBOEXJMMOPUBVUPNBUJDBMMZEJTBQQFBS ↟JG/PUJGJDBUJPO$IBOOFMJNQPSUBODFJTOPUTFU

    )FBETVQOPUJGJDBUJPOEPOPUBQQFBS ↟"QQTUBSHFUJOH#VJME7&34*0/@$0%&42BOEBCPWFXJMMIBWFUPSFRVFTUBQFSNJTTJPO
 .BOJGFTUQFSNJTTJPO64&@'6--@4$3&&/@*/5&/5
  15. $MJDLBDUJPOPG3FNPUF7JFXT private fun showIncomingCallNotification(channelId: String) { ... val remoteView =

    RemoteViews(packageName, R.layout.incoming_call_notification).apply { setOnClickPendingIntent(R.id.acceptBtn, getAcceptIntent(id)) ... } NotificationCompat.Builder(this, channelId) .setCustomBigContentView(remoteView) ... .build() ... } private fun getAcceptIntent(id: Long): PendingIntent { val intent = Intent(this, IncomingCallReceiver::class.java) ... return PendingIntent.getBroadcast(this, REQUEST_ACCEPT, 
 intent, PendingIntent.FLAG_UPDATE_CURRENT) }
  16. $MJDLBDUJPOPG3FNPUF7JFXT private fun showIncomingCallNotification(channelId: String) { ... val remoteView =

    RemoteViews(packageName, R.layout.incoming_call_notification).apply { setOnClickPendingIntent(R.id.acceptBtn, getAcceptIntent(id)) ... } NotificationCompat.Builder(this, channelId) .setCustomBigContentView(remoteView) ... .build() ... } private fun getAcceptIntent(id: Long): PendingIntent { val intent = Intent(this, IncomingCallReceiver::class.java) ... return PendingIntent.getBroadcast(this, REQUEST_ACCEPT, 
 intent, PendingIntent.FLAG_UPDATE_CURRENT) }
  17. $MJDLBDUJPOPG3FNPUF7JFXT private fun showIncomingCallNotification(channelId: String) { ... val remoteView =

    RemoteViews(packageName, R.layout.incoming_call_notification).apply { setOnClickPendingIntent(R.id.acceptBtn, getAcceptIntent(id)) ... } NotificationCompat.Builder(this, channelId) .setCustomBigContentView(remoteView) ... .build() ... } private fun getAcceptIntent(id: Long): PendingIntent { val intent = Intent(this, IncomingCallReceiver::class.java) ... return PendingIntent.getBroadcast(this, REQUEST_ACCEPT, 
 intent, PendingIntent.FLAG_UPDATE_CURRENT) }
  18. $MJDLBDUJPOPG3FNPUF7JFXT class IncomingCallReceiver : BroadcastReceiver() { override fun onReceive(context: Context,

    intent: Intent) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.cancel(FCMService.LIVECONS_FOR_USER) val acceptCall = intent.getBooleanExtra("acceptCall", false) val denyCall = intent.getBooleanExtra("denyCall", false) ... if (acceptCall) goLiveConsIncoming(context) } private fun goLiveConsIncoming(context: Context) { val intent = Intent(context, LiveConsIncomingActivity::class.java) ... PendingIntent.getActivity(context, REQUEST_ACCEPT, 
 intent, PendingIntent.FLAG_UPDATE_CURRENT).send() } }
  19. $MJDLBDUJPOPG3FNPUF7JFXT class IncomingCallReceiver : BroadcastReceiver() { override fun onReceive(context: Context,

    intent: Intent) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.cancel(FCMService.LIVECONS_FOR_USER) val acceptCall = intent.getBooleanExtra("acceptCall", false) val denyCall = intent.getBooleanExtra("denyCall", false) ... if (acceptCall) goLiveConsIncoming(context) } private fun goLiveConsIncoming(context: Context) { val intent = Intent(context, LiveConsIncomingActivity::class.java) ... PendingIntent.getActivity(context, REQUEST_ACCEPT, 
 intent, PendingIntent.FLAG_UPDATE_CURRENT).send() } }
  20. $MJDLBDUJPOPG3FNPUF7JFXT class IncomingCallReceiver : BroadcastReceiver() { override fun onReceive(context: Context,

    intent: Intent) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.cancel(FCMService.LIVECONS_FOR_USER) val acceptCall = intent.getBooleanExtra("acceptCall", false) val denyCall = intent.getBooleanExtra("denyCall", false) ... if (acceptCall) goLiveConsIncoming(context) } private fun goLiveConsIncoming(context: Context) { val intent = Intent(context, LiveConsIncomingActivity::class.java) ... PendingIntent.getActivity(context, REQUEST_ACCEPT, 
 intent, PendingIntent.FLAG_UPDATE_CURRENT).send() } }
  21. &YP1MBZFS66*% /** * UUID for the W3C */ val COMMON_PSSH_UUID

    = UUID(0x1077EFECC0B24D02L, -0x531cc3e1ad1d04b5L) /** * UUID for the ClearKey DRM scheme. * ClearKey is supported on Android devices running Android 5.0 (API Level 21) and up. */ val CLEARKEY_UUID = UUID(-0x1d8e62a7567a4c37L, 0x781AB030AF78D30EL) /** * UUID for the Widevine DRM scheme. * Widevine is supported on Android devices running Android 4.3 (API Level 18) and up. */ val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L) /** * UUID for the PlayReady DRM scheme. * PlayReady is supported on all AndroidTV devices. Note that most other Android devices do not */ val PLAYREADY_UUID = UUID(-0x65fb0f8667bfbd7aL, -0x546d19a41f77a06bL)
  22. &YP1MBZFS66*% /** * UUID for the W3C */ val COMMON_PSSH_UUID

    = UUID(0x1077EFECC0B24D02L, -0x531cc3e1ad1d04b5L) /** * UUID for the ClearKey DRM scheme. * ClearKey is supported on Android devices running Android 5.0 (API Level 21) and up. */ val CLEARKEY_UUID = UUID(-0x1d8e62a7567a4c37L, 0x781AB030AF78D30EL) /** * UUID for the Widevine DRM scheme. * Widevine is supported on Android devices running Android 4.3 (API Level 18) and up. */ val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L) /** * UUID for the PlayReady DRM scheme. * PlayReady is supported on all AndroidTV devices. Note that most other Android devices do not */ val PLAYREADY_UUID = UUID(-0x65fb0f8667bfbd7aL, -0x546d19a41f77a06bL)
  23. (FU8JEFWJOF*E val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L) fun getDeviceId(): String {

    var deviceId = "" if(isWidevineDRMAvailable()) { val id = MediaDrm(WIDEVINE_UUID)
 .getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID) deviceId = Base64.encodeToString(id, Base64.DEFAULT) } return deviceId } private fun isWidevineDRMAvailable(): Boolean { return MediaDrm.isCryptoSchemeSupported(WIDEVINE_UUID) }
  24. (FU8JEFWJOF*E val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L) fun getDeviceId(): String {

    var deviceId = "" if(isWidevineDRMAvailable()) { val id = MediaDrm(WIDEVINE_UUID)
 .getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID) deviceId = Base64.encodeToString(id, Base64.DEFAULT) } return deviceId } private fun isWidevineDRMAvailable(): Boolean { return MediaDrm.isCryptoSchemeSupported(WIDEVINE_UUID) }