Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

What's new in Android Google IO 22

What's new in Android Google IO 22

GDSC HUFS Google I/O 22 Extended 발표자료 입니다.

Jaesung Lee

August 15, 2022
Tweet

More Decks by Jaesung Lee

Other Decks in Programming

Transcript

  1. Beta 3 User now has a choice to make app

    icons inherit the theme color Themed App Icons
  2. Beta 3 Must provide a monochromatic app icons https://developer.android.com/about/versions/13/features Should

    be VectorDrawable 44 x 44dp area inside a 108 x 108 dp container Can be a maximum of 72 x 72dp if needs larger
  3. // Add on res/mipmap-anydpi-v26/ic_launcher.xml <adaptive-icon > <background android:drawable="..." /> <foreground

    android:drawable="..." /> <monochrome android:drawable="@drawable/myicon" /> </adaptive-icon> // In your AndroidManifest.xml <application … android:icon="@mipmap/ic_launcher" … > </application> https://developer.android.com/about/versions/13/features
  4. Beta 3 Built in photo picker in OS. Using the

    picker doesn’t require READ_STORAGE permission. Photo Picker
  5. Beta 3 Android 13 support for a new photo picker

    tool. https://developer.android.com/about/versions/13/features Provides a safe, built-in ways for select media files No need to grant access permission
  6. // Launches photo picker in single-select mode. val intent =

    Intent(MediaStore.ACTION_PICK_IMAGES) startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE) // Launches photo picker in multi-select mode. val maxNumPhotosAndVideos = 10 val intent = Intent(MediaStore.ACTION_PICK_IMAGES) intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos) startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE) https://developer.android.com/about/versions/13/features
  7. // Launches photo picker in single-select mode. val intent =

    Intent(MediaStore.ACTION_PICK_IMAGES) startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE) // Launches photo picker in multi-select mode. val maxNumPhotosAndVideos = 10 val intent = Intent(MediaStore.ACTION_PICK_IMAGES) intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos) startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE) https://developer.android.com/about/versions/13/features
  8. // handle multiple-select images private val registerImagePickerIntent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {

    result -> if (result.resultCode != Activity.RESULT_OK) { // Handle error return } val imageUrls = mutableListOf<Uri>() repeat(result.data?.clipData?.itemCount ?: 0){ imageUrls.add(result.data?.clipData?.getItemAt(it)?.uri ?: return) } // handle Images } registerImagePicker.launch() https://developer.android.com/about/versions/13/features
  9. // handle multiple-select images private val registerImagePickerIntent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {

    result -> if (result.resultCode != Activity.RESULT_OK) { // Handle error return } val imageUrls = mutableListOf<Uri>() repeat(result.data?.clipData?.itemCount ?: 0){ imageUrls.add(result.data?.clipData?.getItemAt(it)?.uri ?: return) } // handle Images } registerImagePicker.launch() https://developer.android.com/about/versions/13/features
  10. // Launches photo picker for videos only in single select

    mode. val intent = Intent(MediaStore.ACTION_PICK_IMAGES) intent.type = "video/*" startActivityForResult(intent, PHOTO_PICKER_VIDEO_SINGLE_SELECT_REQUEST_CODE) https://developer.android.com/about/versions/13/features
  11. Beta 3 Support multilingual users to select other languages for

    specific apps, such as Dutch, Chinese, or Hindi. Per-app language preferences
  12. // Create file called res/xml/locale_config.xml <?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android">

    <locale android:name="ja"/> <locale android:name="fr"/> <locale android:name="en"/> </locale-config> // Add a localeConfig on AndroidManifest.XML <manifest ... <application ... android:localeConfig="@xml/locales_config"> </application> </manifest> https://developer.android.com/about/versions/13/features/app-languages
  13. val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY") // Call this on the

    main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale) https://developer.android.com/about/versions/13/features/app-languages#androidx-impl
  14. Beta 3 Notification will be opted-out by default. Apps need

    to request permission to send notification. Notification Permission
  15. Beta 3 On newly installed app https://developer.android.com/about/versions/13/changes/notification-permission Must ask permission

    explicitly if the app targets Android 13 System will ask permission when first notification channel is created if the app targets Android 12 and lower On existing app The grant lasts until user launches the app if the app targets Android 13 The grant lasts until user select an option from permission prompt if the app targets Android 12 and lower
  16. // Add on AndroidManifest.XML <manifest ...> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <application ...>

    ... </application> </manifest> https://developer.android.com/about/versions/13/features/app-languages
  17. JankStats Alpha Compatible down to API Level 16 Identifies performance

    issues using internal heuristics Provides UI context to attribute data to user states and actions Reports results on every frame via a listener androidx.metrics:metrics-performance:1.0.0-alpha01 https://developer.android.com/topic/performance/jankstats
  18. androidx.profilesinstaller:profileinstaller:1.1.0 Baseline Profiles Stable Create profiles for your app that

    prepopulate ahead of time compilation tracest to reduce startup times and reduce jank
  19. Baseline Profiles Stable Provide custom profile rules in apps and

    libraries Startup and jank performance improvements Profiles added to popular Jetpack libraries androidx.profileinstaller:profileinstaller:1.1.0 https://developer.android.com/jetpack/androidx/releases/navigation#2.4.0
  20. Room Stable Auto Migrations Support for Kotlin 1.6 Room written

    in Kotlin starting from 2.5.0 Performance Improvements with KSP in 2.4.0 Room-Paging Support (Paging 3.0) Relational Query Methods androidx.room:room:2.4.2 https://developer.android.com/jetpack/androidx/releases/room#2.4.0
  21. // Auto Migrations @Database( version = 2, entities = [User::class],

    autoMigrations = [ AutoMigration ( from = 1, to = 2, spec = AppDatabase.MyAutoMigration::class ) ] ) abstract class AppDatabase : RoomDatabase() { @RenameTable(fromTableName = "User", toTableName = "AppUser") class MyAutoMigration : AutoMigrationSpec } https://developer.android.com/training/data-storage/room/migrating-db-versions#automated
  22. // Supports multimap return types // like Map, SparseArray, LongSparseArray,

    etc. // 1:1 Relation Map @Query("SELECT * FROM Song JOIN Artist ON Song.artistId = Artist.artistId") fun getSongAndArtist(): Map<Song, Artist> // 1:N Relation Map @Query("SELECT * FROM Artist JOIN Album ON Artist.id = Album.artistId") fun getArtistAndAlbums(): Map<Artist, List<Album>> https://developer.android.com/training/data-storage/room/accessing-data#multimap
  23. Unbundled Library Fragment Added in Honeycomb, unbundled in Ice Cream

    Sandwich 01 Consistent experience across all SDK levels 02 https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  24. Mini Activity Fragment View Lifecycle SavedInstanceState onConfigurationChanged onActivityResult Loaders Fragment

    https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  25. Fragment Today Fragment View The View is all your fragment

    needs by default Lifecycle Fragment Result ViewModelStore ActivityResultCaller SavedStateRegistry MenuProvider https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  26. Good Fragment APIs? Not in androidx.fragment 01 You should be

    using the other components that Fragments now have access to 02 https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  27. override fun onViewCreted(view: View, savedInstanceState: Bundle?) { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(RESUMED)

    { viewModel.locationFlow.collect { // handle flow } } } } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  28. @HiltViewModel class HomeViewModel @Inject constructor( val newsRepository: NewsRepository ): ViewModel

    { val news: Flow<List<Article>> = newsRepository.getNews() ... } @AndroidEntryPoint class HomeFragement : Fragment() { // Use fragment-ktx extension to get a ViewModel private val viewModel: HomeViewModel by viewModels() } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  29. class PageFragment : Fragment() { // Scope the fragment to

    the parent fragment private val sharedViewModel: PagerViewModel by viewModels(ownerProducer = { requireParentFragment() }) // Or scope the fragment to an Activity private val activityViewModel: mainViewModel by activityViewModels() // Or scope the fragment to a Navigation Graph private val graphViewModel: WelcomeGraphViewModel by navGraphViewModels("welcome") } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  30. class PageFragment : Fragment() { // Scope the fragment to

    the parent fragment private val sharedViewModel: PagerViewModel by viewModels(ownerProducer = { requireParentFragment() }) // Or scope the fragment to an Activity private val activityViewModel: mainViewModel by activityViewModels() // Or scope the fragment to a Navigation Graph private val graphViewModel: WelcomeGraphViewModel by navGraphViewModels("welcome") } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  31. class PageFragment : Fragment() { // Scope the fragment to

    the parent fragment private val sharedViewModel: PagerViewModel by viewModels(ownerProducer = { requireParentFragment() }) // Or scope the fragment to an Activity private val activityViewModel: mainViewModel by activityViewModels() // Or scope the fragment to a Navigation Graph private val graphViewModel: WelcomeGraphViewModel by navGraphViewModels("welcome") } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  32. // In Fragment B binding.submitBtn.setOnClickListener { val result = "result"

    // Use Kotlin extension in fragment-ktx artifact setFragmentResult("requestKey", bundleof("bundleKey" to result)) } // In Fragment A setFragmentResultListener("requestKey") { _, bundle -> // Any type can be put in a bundle is supported val result = bundle.getString("bundleKey") // Do something by result } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  33. // In Fragment B binding.submitBtn.setOnClickListener { val result = "result"

    // Use Kotlin extension in fragment-ktx artifact setFragmentResult("requestKey", bundleof("bundleKey" to result)) } // In Fragment A setFragmentResultListener("requestKey") { _, bundle -> // Any type can be put in a bundle is supported val result = bundle.getString("bundleKey") // Do something by result } https://io.google/2022/program/c9085b18-4e8e-4183-b303-1d1716b0c070/intl/ko/
  34. class FlowersAdapter(private val onClick: (Flower) -> Unit) : ListAdapter<Flower, FlowersAdapter.FlowerViewHolder>(FlowerDiffCallback)

    { class FlowerViewHolder( itemView: View, val onClick: (Flower) -> Unit ) : RecyclerView.ViewHolder(itemView) { private val flowerTextView: TextView = itemView.findViewById(R.id.flower_text) ... fun bind(flower: Flower) { ... } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FlowerViewHolder { ... } override fun onBindViewHolder(holder: FlowerViewHolder, position: Int) { ... } } https://io.google/2022/program/14bb63ef-2dd1-460a-9871-5f51ec1afec9/intl/ko/
  35. <androidx.recyclerview.widget.recyclerview android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutManager="LinearLayoutManager" /> https://io.google/2022/program/14bb63ef-2dd1-460a-9871-5f51ec1afec9/intl/ko/ <LinearLayout ...> <ImageView

    android:id="@+id/flower_image" android:layout_width="48dp" android:layout_height="48dp" ... /> <TextView android:id="@+id/flower_text" android:layout_width="wrap_content" android:layout_height="wrap_content" ... /> </LinearLayout>
  36. <androidx.recyclerview.widget.recyclerview android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutManager="LinearLayoutManager" /> https://io.google/2022/program/14bb63ef-2dd1-460a-9871-5f51ec1afec9/intl/ko/ <LinearLayout ...> <ImageView

    android:id="@+id/flower_image" android:layout_width="48dp" android:layout_height="48dp" ... /> <TextView android:id="@+id/flower_text" android:layout_width="wrap_content" android:layout_height="wrap_content" ... /> </LinearLayout>
  37. https://io.google/2022/program/14bb63ef-2dd1-460a-9871-5f51ec1afec9/intl/ko/ class FlowerListActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val flowersAdapter = FlowersAdapter { flower -> adapterOnClick(flower) } val recyclerView: RecyclerView = findViewById(R.id.recycler_view) recyclerView.apply { adapter = flowersAdapter ... } } }
  38. @Composable fun FlowerList(flowers: List<Flower>) { LazyColumn { items(flowers) { flower

    -> FlowerItem(flower) } } } @Composable fun FlowerItem(flower: Flower) { Column { Image(flower.image) Text(flower.name) } } https://io.google/2022/program/14bb63ef-2dd1-460a-9871-5f51ec1afec9/intl/ko/
  39. Adobe Stock#243026154 LazyColumn { // LazyListScope block item { Text(header)

    } itemsIndexed(data) { index, item -> Item(item, index) } } 3 2 5 4 6 1
  40. Quality matters Large Screens Material guidelines https://goo.gle/large-screens-guidelines App quality guidelines

    https://goo.gle/ls-app-quality Compatibility checklist https://goo.gle/ls-checklist https://io.google/2022/program/eb6e6fb3-b24d-4baf-a1d9-f176198fc595/intl/ko/
  41. Adobe Stock#243026154 Large Screens Large Screens made easy Jetpack WindowManager

    1.0 released! Window size classes Activity embedding SlidingPaneLayout Jetpack DragAndDrop and more.. https://io.google/2022/program/eb6e6fb3-b24d-4baf-a1d9-f176198fc595/intl/ko/
  42. Adobe Stock#243026154 Large Screens WindowMetrics Building Android UIs for any

    screen size https://io.google/2022/program/eb6e6fb3-b24d-4baf-a1d9-f176198fc595/intl/ko/
  43. class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) val windowMetrics = WindowMetricsCalculator.getOrCreate() .computeCurrentWindowMetrics(this) val maxMetrics = WindowMetricsCalculator.getOrCreate() .computeMaximumWindowMetrics(this) } } https://io.google/2022/program/eb6e6fb3-b24d-4baf-a1d9-f176198fc595/intl/ko/
  44. class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) val windowMetrics = WindowMetricsCalculator.getOrCreate() .computeCurrentWindowMetrics(this) val maxMetrics = WindowMetricsCalculator.getOrCreate() .computeMaximumWindowMetrics(this) } } https://io.google/2022/program/eb6e6fb3-b24d-4baf-a1d9-f176198fc595/intl/ko/
  45. Learning how to update your app for the large screen

    Recommended https://io.google/2022/program/eb6e6fb3-b24d-4baf-a1d9-f176198fc595/intl/ko/
  46. Understanding the Full Stack Camera Consistency and quality is becoming

    part of core architecture xTS : OEM testing suites Performance Class Metadata : device capabilities beyond baseline CameraXlab : Google testing https://io.google/2022/program/f4726bbd-d230-4574-abc6-211baa6aec35/intl/ko/
  47. CameraX Camera Perfect place for apps to get the best

    out of the Android Camera stack. 1. Built on top of Camera2 performance; CameraX is faster to use for development. 2. CameraX lab for daily testing; To reach consistency on devices 3. As a Jetpack library has faster launches, to address ad-hoc or planned needs and more. https://io.google/2022/program/f4726bbd-d230-4574-abc6-211baa6aec35/intl/ko/
  48. Stable A viewfinder that enables getting the preview on the

    screen. Preview 01 To access the output buffer seamlessly for use with algorithms such as the ones in ML Kit. Image Analysis 02 Used to save high-quality images. Image Capture 03 CameraX 1.0.0 Use Cases https://io.google/2022/program/f4726bbd-d230-4574-abc6-211baa6aec35/intl/ko/
  49. Android Studio 2021.2.1 Stable Patch 1 Chipmunk 01 2021.3.1 Beta

    2 Dolphin 02 2022.1.1 Canary 3 Electric Eel 03 https://io.google/2022/program/8215c766-f097-4b18-bc97-5085d77c4dad/intl/ko/
  50. https://io.google/2022/program/8215c766-f097-4b18-bc97-5085d77c4dad/intl/ko/ Janky Frames No Jank detected 01 Sending frames to

    the system before the previous frame is displayed Previous frame was janked 02 App process running longer than expected Frames considered jank because they crossed the Deadline criterion 03
  51. https://io.google/2022/program/8215c766-f097-4b18-bc97-5085d77c4dad/intl/ko/ Dolphin Electric Eel Logcat v2 SDK Index Integration Gradle

    Managed Devices Compose Animation Coordination Preview and more.. Live Edit (Jetpack Compose) Visual Lint for Compose Compose Multi-Preview Device Mirroring and more..
  52. Thank you! Resources Jaesung Lee https://io.google/2022/program/intl /ko/ https://www.youtube.com/watch?v =Z6iFhczA3NY Android

    Developer / GDSC HUFS HUFS I.C.E @jdoongxx @JaesungLeee https://speakerdeck.com/jaesungleee/whats-new-in-android-2022