Slide 1

Slide 1 text

GDG Managua Facundo Rodríguez Arceri @facundomr

Slide 2

Slide 2 text

GDG Managua So… what is new? What’s new about What’s New in Android? Android 11 Tools Libraries

Slide 3

Slide 3 text

GDG Managua UI

Slide 4

Slide 4 text

GDG Managua Window Insets ● More information about the multiple types of content being displayed APP Status Navigation IME

Slide 5

Slide 5 text

GDG Managua WindowInsets // get WindowInsets object from listener view.setOnApplyWindowInsetsListener { view, insets -> }

Slide 6

Slide 6 text

GDG Managua WindowInsets // get WindowInsets object from listener view.setOnApplyWindowInsetsListener { view, insets -> // See if the IME is visible val imeVisible = insets.isVisible((WindowInsets.Type.ime())) }

Slide 7

Slide 7 text

GDG Managua WindowInsets // get WindowInsets object from listener view.setOnApplyWindowInsetsListener { view, insets -> // See if the IME is visible val imeVisible = insets.isVisible((WindowInsets.Type.ime())) if (imeVisible) { val imeInsets = insets.getInsets(WindowInsets.Type.ime()) // ... } }

Slide 8

Slide 8 text

GDG Managua WindowInsets.Type

Slide 9

Slide 9 text

GDG Managua IME Animations ● Synchronize keyboard animations with app content changes ○ Listen for changes ■ AND/OR ○ Drive keyboard animation directly

Slide 10

Slide 10 text

GDG Managua IME Animations

Slide 11

Slide 11 text

GDG Managua editText.setWindowInsetsAnimationCallback(animCallback) val animCallback = object : WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) { override fun onProgress(p0: WindowInsets, p1: MutableList ): WindowInsets { ... } // Optional overrides override fun onPrepare(animation: WindowInsetsAnimation) { ... } override fun onEnd(animation: WindowInsetsAnimation) { ... } override fun onStart(animation: WindowInsetsAnimation, bounds: WindowInsetsAnimation.Bounds ): WindowInsetsAnimation.Bounds { ... } } IME Animations Listening for keyboard changes

Slide 12

Slide 12 text

GDG Managua IME Animations editText.windowInsetsController?. controlWindowInsetsAnimation( WindowInsets.Type.ime(), /* animate the keyboard */ -1, /* infinite duration */ linearInterpolator, /* linear motion */ cancellationSignal, /* allows cancellation */ animationControlListener /* ready/cancelled/finished */ ) Animating the keyboard directly

Slide 13

Slide 13 text

GDG Managua Conversations

Slide 14

Slide 14 text

GDG Managua Conversations // Create and post shortcut val person = Person.Builder().build()

Slide 15

Slide 15 text

GDG Managua Conversations // Create and post shortcut val person = Person.Builder().build() val shortcutInfo = ShortcutInfoCompat.Builder(this, "sampleShortcut"). setPerson(person). setLongLived(true). // ... build()

Slide 16

Slide 16 text

GDG Managua Conversations // Create and post shortcut val person = Person.Builder().build() val shortcutInfo = ShortcutInfoCompat.Builder(this, "sampleShortcut"). setPerson(person). setLongLived(true). // ... build() ShortcutManagerCompat.pushDynamicShortcut(shortcutInfo)

Slide 17

Slide 17 text

GDG Managua Conversations // Create and post shortcut val person = Person.Builder().build() val shortcutInfo = ShortcutInfoCompat.Builder(this, "sampleShortcut"). setPerson(person). setLongLived(true). // ... build() ShortcutManagerCompat.pushDynamicShortcut(shortcutInfo) // Create notification with shortcut val style = NotificationCompat.MessagingStyle(person). addMessage(...). // ...

Slide 18

Slide 18 text

GDG Managua Conversations // Create and post shortcut val person = Person.Builder().build() val shortcutInfo = ShortcutInfoCompat.Builder(this, "sampleShortcut"). setPerson(person). setLongLived(true). // ... build() ShortcutManagerCompat.pushDynamicShortcut(shortcutInfo) // Create notification with shortcut val style = NotificationCompat.MessagingStyle(person). addMessage(...). // ... NotificationCompat.Builder(this, "foo"). setShortcutId(shortcutInfo.id). // ... build()

Slide 19

Slide 19 text

GDG Managua Bubbles

Slide 20

Slide 20 text

GDG Managua Bubbles ● Notifications that can also show as bubbles ● Android 10: Developer option ○ Android 11: They’re here! ● Better than System Alert Window! ● Created with Notification API ○ with more metadata ○ and dedicated activity

Slide 21

Slide 21 text

GDG Managua Bubbles: Manifest Manifest:

Slide 22

Slide 22 text

GDG Managua Bubbles: Code // Create Intent to launch val intent = Intent(context, BubbleActivity::class.java) val bubbleIntent = PendingIntent.getActivity(context, 0, intent,...)

Slide 23

Slide 23 text

GDG Managua Bubbles: Code // Create Intent to launch val intent = Intent(context, BubbleActivity::class.java) val bubbleIntent = PendingIntent.getActivity(context, 0, intent,...) // Create metadata val shortcutInfo = ... /* probably already using for notifications */ val bubbleMetadata = Notification.BubbleMetadata.Builder(shortcutInfo.id)

Slide 24

Slide 24 text

GDG Managua Bubbles: Code // Create Intent to launch val intent = Intent(context, BubbleActivity::class.java) val bubbleIntent = PendingIntent.getActivity(context, 0, intent,...) // Create metadata val shortcutInfo = ... /* probably already using for notifications */ val bubbleMetadata = Notification.BubbleMetadata.Builder(shortcutInfo.id) // Create Notification with metadata val builder: Notification.Builder = Notification.Builder(context, CHANNEL_ID) // ... .setBubbleMetadata(bubbleMetadata) .setCategory(...) .setShortcutId(...)

Slide 25

Slide 25 text

GDG Managua Privacy Android 11 enables state of the art privacy and security features, protecting users and their data from access by malicious apps, while simultaneously making access of that data more transparent to the user.

Slide 26

Slide 26 text

GDG Managua Data Access Auditing • Listen for when user-permission-required data is accessed • Great for large apps or use of external libraries

Slide 27

Slide 27 text

GDG Managua ● Callbacks invoked when user-permission-required data is accessed Data Access Auditing

Slide 28

Slide 28 text

GDG Managua Data Access Auditing val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() { override fun onNoted(syncNotedAppOp: SyncNotedAppOp) { ... } override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) { ... } override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) { ... } }

Slide 29

Slide 29 text

GDG Managua Data Access Auditing val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() { override fun onNoted(syncNotedAppOp: SyncNotedAppOp) { ... } override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) { ... } override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) { ... } } val appOpsManager = getSystemService(AppOpsManager::class.java) as AppOpsManager appOpsManager.setOnOpNotedCallback(mainExecutor, appOpsCallback)

Slide 30

Slide 30 text

GDG Managua One-Time Permissions

Slide 31

Slide 31 text

GDG Managua ● More restrictive in Android 11 ● First, request foreground permission ● Then request background permission ○ Takes user to Settings Background Location

Slide 32

Slide 32 text

GDG Managua Background Location

Slide 33

Slide 33 text

GDG Managua • Android 10 required manifest attribute for Location • Android 11 adds ○ Camera ○ Microphone Foreground Services

Slide 34

Slide 34 text

GDG Managua Foreground Service Type ... ...

Slide 35

Slide 35 text

GDG Managua But Wait, There’s More! ● Package visibility restrictions ● Scoped storage ● Device controls ● Auto-reset permissions

Slide 36

Slide 36 text

GDG Managua Developer Goodies

Slide 37

Slide 37 text

GDG Managua Wi-Fi Debugging Because there are never enough USB ports

Slide 38

Slide 38 text

GDG Managua Wi-Fi Debugging Because there are never enough USB ports

Slide 39

Slide 39 text

GDG Managua Nullability Annotations ● @RecentlyNullable, @RecentlyNonNull ○ Warnings ● @Nullable, @NonNull ○ Errors

Slide 40

Slide 40 text

GDG Managua Crash Reasons Reporting ● API to query why your app crashed ○ Upload reports

Slide 41

Slide 41 text

GDG Managua Crash Reasons Querying // Returns List of ApplicationExitInfo val reasonsList = activityManager.getHistoricalProcessExitReasons( packageName, pid /* 0 for all matches */, max /* 0 for all */)

Slide 42

Slide 42 text

GDG Managua Crash Reasons Querying // Returns List of ApplicationExitInfo val reasonsList = activityManager.getHistoricalProcessExitReasons( packageName, pid /* 0 for all matches */, max /* 0 for all */) for (info in reasonsList) { // Log/store/upload info.reason // REASON_LOW_MEMORY, REASON_CRASH, REASON_ANR, etc. }

Slide 43

Slide 43 text

GDG Managua ADB Incremental ● Faster installs via command-line ● For huge APKs (think: games) ● Up to 10x faster

Slide 44

Slide 44 text

GDG Managua ADB Incremental ● Faster installs via command-line ● For huge APKs (think: games) ● Up to 10x faster adb adb incremental playable Avg time (in seconds) 68.8 s 0.29 s Unity Megacity demo 3.5 GB, Pixel 4, USB 3.0 adb incremental fully installed 7.6 s Source: Google data

Slide 45

Slide 45 text

GDG Managua ADB Incremental // First: sign APK, create APK Signature Scheme v4 file // Then, run ADB incremental $ adb install --incremental

Slide 46

Slide 46 text

GDG Managua Behavior Changes ● Most changes limited to targetSdk R ● Test changes with behavior toggles ○ Command-line ○ New Developer Options panel

Slide 47

Slide 47 text

GDG Managua Toggling Behavior Changes // adb shell am compat (enable|disable) (CHANGE_ID|CHANGE_NAME) \ PACKAGE_NAME $ adb shell am compat disable DEFAULT_SCOPED_STORAGE \ com.android.samples.android11playground

Slide 48

Slide 48 text

GDG Managua Graphics & Media

Slide 49

Slide 49 text

GDG Managua NDK Image Decoders ● All decoders available from native code ○ JPEG, GIF, PNG, WebP, … ● No more ○ JNI up-calling ○ Bundling decoder libraries ○ Bulking APK size

Slide 50

Slide 50 text

GDG Managua Animated HEIF ● Load animated images from HEIF files ● Loaded as AnimatedImageDrawable ○ Like animated GIFs ○ But smaller!

Slide 51

Slide 51 text

GDG Managua Animated HEIFs val file = File("someHeifFile") val source = ImageDecoder.createSource(file)

Slide 52

Slide 52 text

GDG Managua Animated HEIFs val file = File(“someHeifFile”) val source = ImageDecoder.createSource(file) // Perform off main thread val drawable = ImageDecoder.decodeDrawable(source); if (drawable is AnimatedImageDrawable) { drawable.start() }

Slide 53

Slide 53 text

GDG Managua NDK: OpenSL ES @Deprecated ● Oboe for the win! ● Unbundled C++ library ○ High-performance audio ○ Works back to API 16 ○ Open source github.com/google/oboe

Slide 54

Slide 54 text

GDG Managua Variable refresh rate ● For apps with their own rendering loop ○ e.g., games ● 60 frames per second used to be a given ○ Now some devices support 90, 120 Hz ○ Enables more flexible backoff rates ● Surface.setFrameRate() 120 fps 60

Slide 55

Slide 55 text

GDG Managua But Wait, There’s More!

Slide 56

Slide 56 text

GDG Managua 5G ● APIs to optimize 5G experience ○ Metered network state ○ Bandwidth estimates

Slide 57

Slide 57 text

GDG Managua 5G val manager = getSystemService(ConnectivityManager::class.java) manager.registerDefaultNetworkCallback(object: ConnectivityManager.NetworkCallback() { override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) { if (capabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {...} ... if (capabilities.linkDownstreamBandwidthKbps > FAST_NETWORK) {...} } })

Slide 58

Slide 58 text

GDG Managua Biometric authenticator strength

Slide 59

Slide 59 text

GDG Managua Biometric authenticator strength val manager: BiometricManager? = getSystemService(BiometricManager::class.java) val strength = BiometricManager.Authenticators.BIOMETRIC_STRONG if (manager?.canAuthenticate(strength) != BiometricManager.BIOMETRIC_SUCCESS) { // Takes user to enroll biometrics security. val intent = Intent(Settings.ACTION_BIOMETRIC_ENROLL) intent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, strength) startActivity(intent) } else { // Authenticate user! }

Slide 60

Slide 60 text

GDG Managua BiometricManager.Authenticators

Slide 61

Slide 61 text

GDG Managua Autofill/Keyboard Integration ● Autofill content in keyboards, not just drop-down ○ Keyboards ○ Password apps ● Secure - keyboards get UI to present data, not data itself

Slide 62

Slide 62 text

GDG Managua Autofill

Slide 63

Slide 63 text

GDG Managua Non-Platform

Slide 64

Slide 64 text

GDG Managua Jetpack ● 70+ libraries, releases every two weeks ● New/Recent ○ Hilt: Dependency injection, built on Dagger ○ Paging 3.0: All-Kotlin, with coroutines ○ CameraX Beta ○ … and more!

Slide 65

Slide 65 text

GDG Managua Jetpack Compose ● New UI Toolkit for Android ● Reactive, Kotlin-based ● Pre-alpha, developed in the open

Slide 66

Slide 66 text

GDG Managua Jetpack Compose

Slide 67

Slide 67 text

GDG Managua Android Studio ● 4.0: Stable ○ Motion Editor ○ LayoutInspector ● 4.1: Beta ○ Database Inspector (Room, SQLite) ● 4.2: Canary ○ Wireless debugging with Android 11 ○ Jetpack Compose development

Slide 68

Slide 68 text

GDG Managua Google Play ● New Play console: complete redesign ○ clearer, easier to use ○ policy status section ○ acquisition reports ○ team management ● Now in Beta ○ play.google.com/console

Slide 69

Slide 69 text

GDG Managua For More Information Launch videos goo.gle/android11

Slide 70

Slide 70 text

GDG Managua For More Information Launch videos 11 Weeks of Android goo.gle/android11 d.android.com/11weeksofandroid

Slide 71

Slide 71 text

GDG Managua For More Information Launch videos 11 Weeks of Android Android 11 Meetups goo.gle/android11 d.android.com/11weeksofandroid d.android.com/android11/meetups

Slide 72

Slide 72 text

GDG Managua For More Information Launch videos 11 Weeks of Android Android 11 Meetups Now in Android goo.gle/android11 d.android.com/11weeksofandroid d.android.com/android11/meetups articles: medium.com/androiddevelopers/tagged/now-in-android videos: youtube.com/androiddevelopers podcast: nowinandroid.googledevelopers.libsynpro.com

Slide 73

Slide 73 text

Thank you!