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

2018 DevFest - Update to Oreo & Pie

Hyeonji Jeong
November 19, 2018

2018 DevFest - Update to Oreo & Pie

2018 DevFest in Seoul presentation - android updates to oreo and pie.

Hyeonji Jeong

November 19, 2018
Tweet

More Decks by Hyeonji Jeong

Other Decks in Technology

Transcript

  1. - ੗߄৬ ௏ౣܽ੉ ഒਊغযઉ ੓णפ׮. - ҕध ޙࢲա ҕध ޙࢲܳ

    ߣ৉ೠ Ӗب ݆૑݅ ೠ ߣী ৘ઁ ௏٘ө૑ ࠅ ࣻ ੓ب۾ ೞҊ र঻णפ׮. - “਋ܻ ࢲ࠺झীח যڃ ӝמਸ সؘ੉౟ೞݶ જਸө?” OR - “੉ ࠗ࠙ਸ ԙ ഛੋ೧ ࠊঠ ೞѷҳա!" ۄҊ ׮द 
 ࢚ӝೞदѱ غח ҅ӝо غ঻ਵݶ જѷणפ׮.
  2. Android Oreo 변경 대응사항 - 모든 API를 타겟으로 하는 앱

    변경 사항 앱의 Target 버전이 26 미만인데도 영향을 받는 모든 API 레벨을 타겟으로 하는 앱 변경사항 - Android 8.0을 타겟으로 하는 앱 변경 사항 앱의 Target 버전이 26 이상에서만 영향을 받는 Android 8.0를 타겟으로 하는 앱 변경사항
  3. Android Pie 변경 대응사항 - Android Pie에서 실행되는 
 모든

    앱에 적용되는 변경사항 - Android Pie를 타겟으로 하는 앱 변경 사항
  4. 알림 ( Notification ) ! 각 채널에 대해 해당 채널의

    모든 알림에 적용되 는 view와 알림 소리, 진동 동작을 설정할 수 있 습니다. ! 알림 채널을 만들어 앱 사용자의 선택을 반영 : 메시징 앱에서 사용자가 만든 각 대화 그룹에 대 해 별도의 알림 채널을 설정할 수 있습니다. API 레벨 26부터 모든 알림을 채널에 할당
  5. 알림 ( Notification ) ! 2018년 1월 기준 - oreo

    8.0 버전 점유율 0.7% ! 현재 - oreo 8.0 버전이 약14.0 %, 8.1버전이 약 7.5% API 레벨 26부터 모든 알림을 채널에 할당
  6. 알림 ( Notification ) - Notification channel - Notification Badge

    - Notification Setting - Notification Remove - MessagingStyle Korea
  7. 알림 ( Notification ) - 사용자가 앱에대한 각채널별 알림 중요도나

    진동 설정등을 변경할 수 있도록 되어, 사용자의 설정에 맞추어 변경사항이 반영되도록 적 용하여야한다. - 노티피케이션의 중요도를 설정할 수 있고 채널의 아이디와 중요도를 넣어 설정합니다. 채널은 한번만 만들면 되기때문에 Notification이 올때마다 만들어줄 필요가 없다. - Korea
  8. Notification Channel if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Create the

    NotificationChannel val name = getString(R.string.channel_name) val descriptionText = getString(R.string.channel_description) val importance = NotificationManager.IMPORTANCE_DEFAULT val mChannel = NotificationChannel(CHANNEL_ID, name, importance) mChannel.description = descriptionText // Register the channel with the system; you can't change the importance // or other notification behaviors after this val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(mChannel) }
  9. Always on ?! - 말그대로 화면이 항상 켜져 있는 기능..

    - 노티피케이션 아이콘을 그대로 가져와서 보여줍 니다. - 우선순위가 적용되어 보여집니다. OS 기본기능 ?!
  10. PIP ( Picture-in-picture ) 주로 동영상 재생에 사용되는 특수한 유형의

    다중 창 모드. 이미 Android TV에서 제공. 다중 창 모드
  11. @Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration configuration) { super.onPictureInPictureModeChanged(isInPictureInPictureMode, configuration);

    if (isInPictureInPictureMode) { // Starts receiving events from action items in PiP mode. mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { /.../ // This is where we are called back from Picture-in-Picture action items. final int controlType = intent.getIntExtra(EXTRA_CONTROL_TYPE, 0); switch (controlType) { case CONTROL_TYPE_PLAY: mMovieView.play(); break; case CONTROL_TYPE_PAUSE: mMovieView.pause(); break; } } }; registerReceiver(mReceiver, new IntentFilter(ACTION_MEDIA_CONTROL)
  12. } else { // We are out of PiP mode.

    We can stop receiving events from it. unregisterReceiver(mReceiver); mReceiver = null; // Show the video controls if the video is not playing if (mMovieView != null && !mMovieView.isPlaying()) { mMovieView.showControls(); } } } Picture-in-Picture - https://developer.android.com/guide/topics/ui/picture-in-picture - https://github.com/googlesamples/android-PictureInPicture
  13. Autosizing Textviews TextView 크기에 따라 텍스트의 크기를 자동으로 늘리거 나

    줄일 수 있습니다. 다시 말해, 다양한 화면에서 또는 동적 콘텐츠로 텍스트 크 기를 더 쉽게 최적화할 수 있습니다.
  14. --- XML <TextView app:autoSizeTextType="uniform" /> <!-- enabled --> <TextView app:autoSizeTextType="none"

    /> <!-- disabled --> --- code TextViewCompat.setAutoSizeTextTypeWithDefaults(textView, autoSizeTextType) ———————————————————————————————————————————————————————————————————————————————— --- XML <TextView app:autoSizeTextType="uniform" app:autoSizeMinTextSize="16sp" app:autoSizeMaxTextSize="100sp" app:autoSizeStepGranularity="1sp" /> --- code TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(16, 100, 1, unit) 1 2 XML or Code
  15. --- res / values / arrays.xml <resources> <array name="auto_size_text_sizes"> <item>16sp</item>

    <item>20sp</item> <item>48sp</item> <item>100sp</item> </array> </resources> --- XML <TextView app:autoSizeTextType="uniform" app:autoSizePresetSizes="@array/auto_size_text_sizes" /> ———————————————————————————————————————————————————————————————————————————————— --- code TextViewCompat .setAutoSizeTextTypeUniformWithPresetSizes ( textView , arrayOf (16, 20, 48, 100), unit ) 3
  16. WebView API - WebView api update - Version API -

    Google SafeBrowsing API - Termination Handle API - Renderer Importance API Korea
  17. WebView - https://developer.android.com/guide/webapps/managing-webview#safe-browsing private lateinit var mSuperSafeWebView: WebView private var

    mSafeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mSuperSafeWebView = WebView(this) mSuperSafeWebView.webViewClient = MyWebViewClient() mSafeBrowsingIsInitialized = false mSuperSafeWebView.startSafeBrowsing(this, ValueCallback<Boolean> { success -> mSafeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", “উ੹ೠ ࠳ۄ਋૚ਸ ୡӝച ೡ ࣻ হणפ׮!") } }) }
  18. 권한 Korea - 앱에는 명시적으로 요청한 권한만 허용 - 런타임

    권한 실행 시,
 같은 그룹의 다른 퍼미션도 같이 허용을 하도록 변경해야함. - 사용자가 앱에 권한을 허용하고 나면 해당 권한 그룹에서 
 권한에 대한 이후의 모든 요청이 자동으로 허용된다.

  19. 백그라운드 서비스 실행 제한
 사용자가 직접 설정 가능 ! 안드로이드

    O에서는 앱이 유휴 상태인 경우 백그라운 드 서비스의 사용이 제한되고, 이 기능은 사용자에게 잘 보이는 포그라운드 서비스에는 적용되지 않는다 ! 기본적으로, 이 제한은 O를 대상으로 하는 앱에만 적용 된다. 그러나 앱이 O를 대상으로 하지 않더라도 이미지 에서 보시는 것과 같이 사용자가 따로 설정 가능. ! 앱이 포그라운드에 있는 동안에는 이 앱이 포그라운드 및 백그라운드 서비스를 자유롭게 생성하고 실행할 수 있음. 

  20. 백그라운드 서비스 실행 제한 ! 액티비티가 시작되거나 일시 중지되거나 상관없이

    보이는 액티비티 가 있는 경우 ! 포그라운드 서비스가 있는 경우 ! 다음항목에 바인드 되어있는 경우 ◦ 배경화면 서비스 ◦ 알림 리스너 ◦ 음성 또는 텍스트 서비스
 
 Korea
  21. Job Scheduler update ! 작업의 큐에 작업 항목을 추가하려면 JobScheduler.enqueue()를

    호출. 이 기능은 이전에는 백그라운드 서비스를 시작하기 위해 호출 했던 다수의 사용 사례, 특히 IntentService를 구현하는 서비스를 처리합니다. ! JobInfo.Builder.setClipData()를 호출하여 ClipData를 작업과 연결. 이 옵션을 사용하면 URI 권한을 Context.startService()로 전 달할 수 있는 방법과 유사하게 이런 권한 허용을 작업과 연결할 수 있 습니다. Korea
  22. private static final int JOB_ID_UPDATE = 0x1000; static void setUpdateJob(Context

    context) { // ੸੿ ઑѤ ࢸ੿ JobInfo job = new JobInfo.Builder( JOB_ID_UPDATE, // ઑѤ ݅઒ - UpdateDataByWiFiServiceо प೯ new ComponentName(this, SyncJobService.class) ) // ੷੢ ҕр ഛੋ .setRequiresStorageNotLow(true) // WiFi ࢎਊ ઺ .setRequiredNetworksCapabilities(JobInfo.NETWORK_TYPE_UNMETERED) // ୽੹ ઺ ੋ૑ .setRequiresCharging(true) .build(); // JobScheduler ࢲ࠺झ JobService mJobService = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); // Jobਸ ١۾ mJobService.scheduleJob(job); } 1 2
  23. Job Scheduler update ! 안드로이드 N 이하 - 백그라운드 서비스가

    시작하며 적재된 작업 
 순차적 실행 ! 안드로이드 O 이상 - JobScheculer를 통해 적재된 작업을 
 순차적 실행 - Wakelock을 알아서 관리 Korea 안드로이드 N 이하의 디바이스에서는 즉시 백그라운드 서비스가 시작하며 적재된 작업이 순차적으로 실행 됩니다. 이를 통해 동일 코드로 하위호환성을 유지할 수 있음. 안드로이드 O 이상의 디바이스에서는 JobScheduler를 통해 적재된 작업을 순차적으로 실행. Wakelock을 알아서 관리해주기 때문에 하위 버전의 플랫폼에서 동작할 때 WakefulBroadcastReceiver 를 사용할 필요가 없다. 이는 실수로 인한 배터리 소모 등의 이슈를 원천적으로 해결해 준다.
  24. Korea 암시적 브로드캐스트 인텐트 제한
 특정 앱을 대상으로 하지 않는

    암시적 브로드캐스트 인텐트 (Implicit Broadcast Intent) 암시적 브로드케스트 인텐트는 AndroidManifest.xml에 이를 기술하고 있는 모 든 Receiver나 Service를 깨울 수 있다. 비활성되어 있는 앱 컴포넌트는 처리를 위해 로딩되어야 하고 실행되어야 하며, 이는 분명히 리소스를 소모하는 동작이므로 문제가 될 수 있다.
 
 안드로이드 N에서는 이를 줄이기 위해 특정 인텐트들에 대한 동작을 제한하는 기 능을 소개. 안드로이드 O는 앱 매니페스트에 있는 암시적 브로드캐스트 수신자를 등록할 수 없도록 하는 더 적극적인 제한을 통해 리소스의 사용을 제한한다.
  25. Android 백그라운드 위치 제한
 ! FLP(Fused Location Provider) ! Geofencing

    ! GNSS Measurements ! Location Manager ! Wi-Fi Manage
 
 Korea Android 8.0는 소비전력 절감을 위해 앱의 대상 SDK 버전에 상관없이 백그라운드 앱이 사용자의 현재 위치를 검 색할 수 있는 빈도를 제한. 위치 검색 동작은 앱이 백그라운드에서 실행 중인 상태에서 실시간 경고나 모션 감지에 의존하는 경우 특히 유념해야 한다.. 1. 액티비티가 시작되든 일시 중지되든 상관없이, 보이는 액티비티가 있는 경우
 2. 포그라운드 서비스가 있는 경우
 3. 앱의 서비스 중 하나에 바인드하거나 앱의 콘텐츠 제공자 중 하나를 사용하여 앱에 또 다른 포그라운드 앱이 연결 된 경우에 제한.
  26. 전원 관리 ! 앱 대기 버킷
 시스템은 CPU 또는 배터리와

    같은 기기 리소스에 대한 앱 액세스를 사용자의 사용 패턴에 따라 제한합니다. ! 배터리 세이버 개선
 배터리 세이버가 켜지면 시스템이 모든 앱에 제한을 적용합니다. Korea
  27. <!-- ScreenService —> @Override public void onStartCommand(final Intent intent, int

    flags, int startId) { if (intent != null) { if (intent.hasExtra(EXTRA_IS_FOREGROUND) && !intent.getBooleanExtra(EXTRA_IS_FOREGROUND, true)) { if (foregroundEnable) { stopForeground(); foregroundEnable = false; } } if (intent != null && intent.getAction() != null) { final Bundle params = intent.getExtras(); if (!intent.getAction().equals(ACTION_FORWARD_BROADCAST)) { params.putString("action", intent.getAction()); } //… / } } }
  28. Korea 배터리 세이버 1. 시스템은 앱이 유휴 상태가 되기를 기다리는

    대신 보다 적극적으로 앱을 앱 대기 모드에 둡니다. 2. 백그라운드 실행 제한은 대상 API 레벨에 상관없이 
 모든 앱에 적용됩니다. 3. 화면이 꺼지면 위치 서비스가 비활성화될 수도 있습니다. 4. 백그라운드 앱에는 네트워크 액세스 권한이 없습니다.
  29. Pie 백그라운드에서 센서 엑세스 제한 
 - 앱이 마이크나 카메라에

    엑세스할 수 없음 - 가속도계, 자이로스코프를 사용하는 센서는 이벤트 수신 불가 Korea
  30. 통화 로그 / 전화번호 엑세스 제한 Korea - CALL_LOG 권한

    그룹 도입 - READ_CALL_LOG - WRITE_CALL_LOG - PROCESS_OUTGOING_CALLS
  31. 전화번호 엑세스 제한 <!-- Permissions --> <uses-permission android:name="android.permission.READ_CALL_LOG" /> ---

    // onCallStateChanged() // added in API level 1 public void onCallStateChanged (int state, String phoneNumber)
  32. Wi-Fi 엑세스 제한 Korea - WifiManager의 getScanResults() 와 getConnectionInfo() -

    WifiP2pManager의 discoverServices() 와 addServiceRequest() - NETWORK_STATE_CHANGED_ACTION 브로드캐스트.
  33. Wi-Fi - SSID 구하기 <!-- Permissions —> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> ---

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if (info != null && info.isConnected()) { String ssid = info.getExtraInfo(); Log.d(TAG, "WiFi SSID: " + ssid); } }
  34. FLAG_ACTIVITY_NEW_TASK 요구사항이 적용 Korea - 인텐트 플래그 FLAG_ACTIVITY_NEW_TASK를 전달하지 않을

    경우 비 액티비티 컨텍스트에서 액티비티를 시작할 수 없습니다. - 이 플래그를 전달하지 않고 액티비티를 시작하려고 하면 액 티비티가 시작되지 않고, 시스템이 로그에 메시지를 출력합 니다.
  35. 비 SDK 인터페이스 사용 제한 - 앱 안정성과 호환성을 보장하기

    위해 플랫폼에서는 일부 비 SDK 메 서드와 필드의 사용을 제한 - ૒੽੸ੋ Reflection ߂ JNIܳ ాೠ ࠺ SDK ੋఠಕ੉झ੄ ࢎਊ੉ ݽ ف ઁೠ Korea
  36. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { StrictMode.setVmPolicy( StrictMode.VmPolicy .Builder() .detectNonSdkApiUsage() .build())

    } —- Log result - Accessing hidden method Landroid/gesture/Gesture;->setID(J)V (blacklist, reflection)
  37. 알림 ( Notification ) + - 향상된 메세지 환경 -

    API 레벨 28 이상을 대상으로 개발하는 개발자는 이 모든 향상된 기 능을 사용할 수 있습니다. Korea
  38. 이미지 지원 이제 Android 9은 전화의 메시지 알림에 이미지를 표시합니다.

    메시지에 setData()를 사용하여 이미지 를 표시할 수 있습니다. 다음 코드 스니펫은 Person 과 이미지 포함 메시지를 생성하는 방법을 보여줍니 다. 사용자 Person class지원
  39. // Create new Person. val sender = Person() .setName(name) .setUri(uri)

    .setIcon(null) .build() // Create image message. val message = Message("Picture", time, sender) .setData("image/", imageUri) val style = Notification.MessagingStyle(getUser()) .addMessage("Check this out!", 0, sender) .addMessage(message)
  40. MessagingStyle - 회신 초안 저장 - 대화가 그룹 대화인지 여부를

    식별 - Smart Reply 회신과 대화가 있는 MessagingStyle
  41. Smart Reply <string-array name=”reply_choices”> <item>উ֞?</item> <item>Ҋ݃ਕ</item> <item>ஂࣗп</item> </string-array> --- String

    replyLabel = getResources().getString(R.string.reply_label); String[] replyChoices = getResources().getStringArray(R.array.reply_choices); RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY) .setLabel(replyLabel) .setChoices(replyChoices) .build();
  42. 디스플레이 컷아웃 지원 ! 컷 아웃 지원은 애플리케이션의 매끄러운 작동

    을 지원하고, 상태 표시줄 높이를 조절할 수 있습 니다. 화제의 Notch, Cutout ! 핵심적인 몰입 콘텐츠의 경우에는 새로운 API를 통해 컷아웃 모양을 확인하고 전체 화면 레이아 웃을 요청할 수 있습니다.
  43. val params = window.attributes params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER --- LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT :

    ೙ਃী ٮۄ Cutoutਸ ঌইࢲ ࢎਊೠ׮. LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES : Cutoutীࢲب ؘ੉ఠܳ ಴दೠ׮. LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER : Cutout ৔৉ਸ ࢎਊೞ૑ ঋח׮. Display cutout 1
  44. 디스플레이 컷아웃 지원 ! None : 적용하지 않음 ! Corner

    display cutout : 오른쪽 코너에 적용 ! Double display cutout : 상/하단에 대한 Cutout 적용 ! Tall display cutout : 상단에 Cutout 적용
  45. 디스플레이 컷아웃 지원 ! None : 적용하지 않음 ! Corner

    display cutout : 코너에 적용 ! Double display cutout : 상/하단에 대한 Cutout 적용 ! Tall display cutout : 상단에 Cutout 적용
  46. 디스플레이 컷아웃 지원 ! None : 적용하지 않음 ! Corner

    display cutout : 코너에 적용 ! Double display cutout : 상/하단에 대한 Cutout 적용 ! Tall display cutout : 상단에 Cutout 적용
  47. 디스플레이 컷아웃 지원 ! None : 적용하지 않음 ! Corner

    display cutout : 오른쪽 코너에 적용 ! Double display cutout : 상/하단에 대한 Cutout 적용 ! Tall display cutout : 상단에 Cutout 적용
  48. Drawable 및 비트맵용 ImageDecoder 이미지 디코딩에 대한 최신 접근방식을 제공하는

    클래스 도입 - BitmapFactory 및 BitmapFactory.Options API 대신 이 클래스 를 사용하세요! Korea
  49. private void oldImageLoad() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds

    = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType; }
  50. ImageDecoder 코드 private void testImage () { File file =

    new File("/sample_Image.png"); ImageDecoder.Source source = ImageDecoder.createSource(file); Drawable drawable = ImageDecoder.decodeDrawable(source); // ӝࠄ ࢸ੿ ߸҃ - ੉޷૑੄ ಩җ ֫੉ܳ ߈ਵ۽ ઴ੋ׮. OnHeaderDecodedListener listener = new OnHeaderDecodedListener() { public void onHeaderDecoded(ImageDecoder decoder, ImageInfo info, Source source) { decoder.setTargetSampleSize(2); } }; drawable = ImageDecoder.decodeDrawable(source, listener); }
  51. Drawable 및 비트맵용 ImageDecoder GIF와 WEBP - Android P GIF

    및 WEBP가 직접 지원되지 않는다. 애니메이션 파 일에서 BitmapFactory.decode...()또는 Drawable.create...()메 서드를 사용 하면 애니메이션의 첫 번째 프레임으로 만 정적 이미지 를 만들 수 있다. - 인코딩된 이미지가 애니메이션 GIF 또는 WebP인 경우, Drawable 은 AnimatedImageDrawable의 인스턴스가 됩니다. - 단계는 동일
 1. 애니메이션 파일 (또는 ByteArray, URI 등)에서 소스 객체 만들기
 2. 소스 객체를 드로어블로 디코드로 나타내기 Korea
  52. ImageDecoder - AnimatedImageDrawable fun testGif() { val assets = contex.assets

    val assetFileName = "cat.gif" val source = ImageDecoder.createSource(assets, assetFileName) val drawable = ImageDecoder.decodeDrawable(source) imageView.setImageDrawable(drawable) if (drawable is AnimatedImageDrawable) { drawable.start() } }
  53. 최적화된 Kotlin - 컴파일러 최적화 - 코틀린으로 생성된 코드 최적화

    ( 스튜디오 최신 버전 필요 ) - 컴파일러 최적화(특히, 루프 최적화) 개선 - SDK 구현에 가장 자주 사용하는 일부 API의 Null 허용 여부를 표시 하는 주석(Annotation)이 포함
 Korea