- 5 tips for preparing for Multi-Window in Android N
- Pro-tip 1: Use the right Context
- Pro-tip 2: Handle configuration changes correctly
- Pro-tip 3: Handle all orientations
- Pro-tip 4: Build a responsive UI for all screen sizes
- Pro-tip 5: Activities started by other apps must always support multi-window
- Test all the things!
- How to enable multi-window in Android O and P
- Multi-Window in Android N: What Devs Need to Know to Make the Best of It
- Introduction
- Adding Multi-Window Support
- System behavioral changes
- Understanding the Activity lifecycle
- Handling Runtime Changes
- Disabled Features in Multi-Window Mode
- New API Additions
- Starting Activities in Multi-Window Mode
- Drag and Drop
- Other Notable Additions
- UX Best Practices:
- Useful Resources
5 tips for preparing for Multi-Window in Android N
If you’ve been digging through What’s New in Android N, you probably stumbled across multi-window support.
With split-screen multi-window, two apps will be visible side-by-side. Excited to see how this works, I know I immediately scanned through the documentation, looking for what new APIs made this sorcery work.
Turns out, there aren’t many new APIs. A few XML attributes for customizing whether you support multi-window at all and a few Activity methods to check whether you are currently in multi-window mode. So where’s the magic? The magic has been there all along.
And by magic, we mean Android’s resource system. One of the most powerful parts of the resource system is the ability to provide alternate resources — change dimensions, layouts, drawables, menus, etc. based on different qualifiers.
Multi-window takes advantage of the resource system by adjusting the configuration based on the size of your window — screen size is the obvious one, but the smallest width (i.e., the minimum of the width or height) and the orientation are also updated when resizing.
This takes us to the first tip.
Pro-tip 1: Use the right Context
Loading the proper resources requires the proper Context. If you’re using the Activity context for inflating your layouts, retrieving resources, etc, then you’re good to go.
However, if you’re using your Application context for anything UI related, you’ll find that the resources that are loaded are blissfully unaware of multi-window. Besides issues with not using your Activity’s theme, you may be loading the wrong resources entirely! Best to keep your UI stuff with the Activity Context.
Pro-tip 2: Handle configuration changes correctly
With the correct context in hand, you’ll be sure to get the right resources given the size of your window (whether it is full screen as before or split between your app and another). The process for reloading those resources is based on how you handle runtime changes.
The default case is that your whole activity is destroyed and recreated, restoring any state you saved in onSaveInstanceState() and reloading all of the resources/layouts. This has the nice property that you know everything is consistent with the new configuration and that every type of configuration is handled.
It should go without saying that each configuration change should be fast and seamless. Make sure you aren’t doing a lot of work in onResume() and consider using loaders to ensure your data survives configuration changes.
You can still handle the configuration change yourself in which case your Activity (and Fragments) will receive a callback to onConfigurationChanged() instead of being destroyed and recreated and you will need to manually update your views, reload resources, etc.
To catch the multi-window related configuration changes, you’d need to add an android:configChanges attribute to your manifest with at least these values:
Make sure you’re handling every resource that might be changing (as is your responsibility when you take on handling configuration changes yourself).
This includes reloading resources that might have been considered a constant before. Consider the case where you had a dimension in values and in values-sw600dp. In the non-multi-window world, you’d never switch between these two at runtime as the smallest width would never change (it would always be the smallest width of your device). However, with multi-window, you can and will have to switch between these resources as your app resizes.
Pro-tip 3: Handle all orientations
Remember way back in the intro where we talked about the orientation changing while the window resizes? That’s right: even if the device is in landscape, your app might be in ‘portrait’ orientation.
Turns out: “portrait” really just means the height is greater than the width and “landscape” means the width is greater than the height. So it certainly makes sense, with that definition in mind, that your app could transition from one to the other while being resized.
That also means that transitions between orientations should be as smooth as possible. Quoting the split screen material design specs:
Changing a device’s orientation should not cause the UI to change unexpectedly. For example, an app displaying a video in one of the split screens (in portrait mode) should not begin playback in full-screen if the device rotates to landscape mode.
Note: if you’d still want this type of functionality when your app is fullscreen, you’ll be able to use the inMultiWindowMode() method to check exactly which case you’re in.
Locking your screen orientation by using android:screenOrientation is also affected by multi-window. For apps not targeting Android N, adding android:screenOrientation means you will not support multi-window at all — you’ll always force the user out of multi-window mode. Things change a little when you target N — instead of not supporting multi-window at all, any orientation you set via android:screenOrientation is ignored when in multi-window mode.
Keep in mind that locking your orientation at runtime using setRequestedOrientation() will have no effect in multi-window mode, whether you target N or not.
Adding the android:immersive attribute to your Activity’s manifest also disables multi-window on apps not targeting N, with the same rules as android:screenOrientation above.
Pro-tip 4: Build a responsive UI for all screen sizes
Orientation isn’t the only thing that goes into designing for split screen. Multi-window is the first time your tablet UI (you have a tablet UI right? After all, 12.5% of 1.4 billion devices is a lot of devices…) is going to be shrunk down to a miniature size.
If you’ve been building a responsive UI that reacts to the available space and has relatively similar phone and tablet layouts, you’ll find you’ll be well prepared for multi-window. As suggested, scaling the UI down to 220dp wide/tall and building up from that size to the fullscreen size is a something you can do now.
However, if your mobile and tablet UIs are vastly different, don’t overwhelm users by switching between the two — stick with the tablet UI and work on scaling it down. There’s a number of responsive UI patterns you might consider employing to make resizing a seamless experience for your users — again, no N APIs needed.
Pro-tip 5: Activities started by other apps must always support multi-window
In the multi-window world, your whole task is represented by a single window. That’s why if you want to launch an adjacent activity you need to start a new task — new task, new window.
It also means the reverse is true, quoting that same page:
If you launch an activity within a task stack, the activity replaces the activity on the screen, inheriting all of its multi-window properties.
That means if you have an Activity that can be started by other apps, your activity will inherit the same multi-window properties as the calling Activity. This includes attributes such as minimal size. In cases of startActivityForResult(), your Activity must be part of the same task stack and even in the case of an implicit intent, you can’t guarantee that they’ll also include a FLAG_ACTIVITY_NEW_TASK.
Therefore every one of those activities (and any activities started by that Activity) must support multi-window, all the way down the smallest size. Test thoroughly!
Test all the things!
The best way to prepare for multi-window is to test your app. Even without any code changes or going through the process of setting up the Android N SDK, installing your existing app on an Android N device or emulator is a fantastic first step and an easy way to catch low hanging fruit and #BuildBetterApps.
Источник
How to enable multi-window in Android O and P
Android N introduced a hidden feature called multi-window. In Android N, this feature was easily enabled through the developer settings. Multi-window carried over to Android O and P, but Google hid it behind special permission access, thus making it more difficult to unlock.
Please note that this is only for Sentio Desktop and not for Andromium OS.
This guide will teach you how to grant special permission access and unlock multi-window on Android O and P.
This guide assumes that you are not a developer and do not already have the Android Device Bridge (ADB) installed. If you have ADB installed, open Terminal and skip to step 7.
On your laptop or desktop (not a mobile device), open Chrome and install the ADB for Chrome extension.
Ensure that your mobile device has Developer Options enabled. If you do not have it enabled, you will need to enable it by following these steps. Make sure to plug your phone into your computer after this has been enabled but not before.
- Open “Android Settings” on your mobile device.
- Scroll to find “About Phone” or “About Device”. Click it.
- Scroll to find the “Build number”. Note that it might be under the system tab.
- Click “Build number” 7 times until it tells you that “Developer options” are now available.
- Developer Options should now appear in the first Settings screen.
Источник
Multi-Window in Android N: What Devs Need to Know to Make the Best of It
Multi-window support is a neat feature we’re waiting for in Android N, and one we’ve wanted to be available on all devices for a long time. For it to be an enjoyable experience, though, developers may have to make some changes in their apps to support it correctly.
One of the Google I/O sessions was for developers to learn about the new APIs and system behavioral changes multi-window support brings.
The session was presented by Wale Ogunwale, the Technical Lead Manager for the Android ActivityManager and WindowManager framework components — he and his team are the ones responsible for multi-window on Android.
You can watch the Multi-Window mode session on YouTube, but we also provide an overview of the session here.
Introduction
N introduces three different multi-window modes:
- Split-screen mode: this is the mode that’s available by default. As the name implies, it allows you to open two applications side-by-side.
- Freeform mode: manufacturers can enable this on larger devices, which allows users to freely resize activities in addition to the split-screen mode.
- Picture-in-picture mode: aimed at Android TV devices, this mode is intended for video players to run in a pinned window while the user interacts with other applications.
It’s worth noting that we’ve covered multi-window on N before and offered some criticism of the current system. With that in mind, we hope that the freeform mode moves a bit closer to the picture-in-picture mode, as that would have useful applications on all devices.
Adding Multi-Window Support
Enabling multi-window support in your apps is simple: you don’t need to do anything if you’re already targeting N.
Should you choose to disable multi-window, you can do so by setting the android:resizeableActivity activity attribute in your manifest to false . This should only be done if truly justified, as it makes your app stand out in a bad way by always launching in fullscreen mode even if the user (or another app) tries to launch it in multi-window mode.
It’s important to note that a root activity’s attributes apply to all activities within its task stack. In other words, if you have an activity that can be started by other apps, make sure it supports multi-window mode as you can’t guarantee other apps will launch your activity in a new task using Intent#FLAG_ACTIVITY_NEW_TASK .
Picture-in-picture mode support must be declared explicitly via the android:supportsPictureInPicture attribute. Note that this attribute is ignored if android:resizeableActivity is false .
Layout attributes can be used to set default dimensions and placement for freeform windows, or to specify a minimal width or height both for freeform and split-screen modes:
- android:defaultWidth / android:defaultHeight : the default dimensions of the activity (freeform mode).
- android:gravity : the initial position of the activity (freeform mode).
- android:minimalWidth / android:minimalHeight : the minimal dimensions of the activity (freeform and split-screen modes)
System behavioral changes
With the introduction of multi-window support, you might need to double check a few things in your apps to make sure they operate correctly.
Understanding the Activity lifecycle
The activity lifecycle is unchanged in multi-window mode:
That being said, some subtle differences between the activity states may result in unintended behavior you wouldn’t normally notice before N. It’s important to know that Activity#onResume() and Activity#onPause() are called when your app gains or loses focus, but not necessarily when it starts or stops being visible. (Remember that only one app may have focus at any given time.)
For apps that update the content constantly (e.g. video playback), make sure to handle starting and stopping content updates in Activity#onStart() and Activity#onStop() instead. Not doing so for video apps, for instance, will mean that playback will only occur if the app is focused, which defeats the purpose of multi-window mode. The official YouTube app had a similar problem when the Android N Developer Preview first launched.
Handling Runtime Changes
When an app is put into multi-window mode, some device configurations will change. You can either allow your activity to restart (in which case retaining Fragments might be a good idea, if your activity must perform an intensive operation on startup), or choose to handle the configuration changes explicitly instead.
Four device configurations may change when entering or inside multi-window mode: screenSize , smallestScreenSize , screenLayout and orientation . Refer to the Android Developers documentation for more info about each attribute, but note that orientation no longer refers to the device’s orientation in this case. Instead, it merely indicates whether your activity’s width is larger than its height (landscape) or not (portrait).
Declaring that your activity will handle these changes can be done from the manifest:
Keep in mind this means you’ll actually need to handle these changes in Activity#onConfigurationChanged() , by manually updating views or reloading some resources.
Disabled Features in Multi-Window Mode
Some system features won’t be affected by your activities while in multi-window mode:
- Status bar and navigation bar changes, such as dimming/hiding the system bars or using immersive mode, will have no effect. This makes sense since your activity only occupies part of the screen.
- The android:screenOrientation activity attribute also has no effect in multi-window mode: since your activity will be resizeable, it no longer makes sense for it to have a fixed orientation.
New API Additions
New callbacks have been added for multi-window events, as well as methods to query the current state.
- Activity#onMultiWindowModeChanged(boolean inMultiWindow) : called when activity state changes from fullscreen to multi-window and vice versa.
- Activity#onPictureInPictureModeChanged(boolean inPictureOnPicture) : called when activity state changes to/from PIP mode.
- Activity#isInMultiWindowMode() / Activity#isInPictureInPictureMode() : return whether the activity is in multi-window/picture-in-picture mode or not.
- Activity#overlayWithDecorCaption(boolean overlay) : for freeform windows, this method can be used to make the caption (the bar used to drag the window around) overlay the content instead of pushing it down.
PS. Except for Activity#overlayWithDecorCaption() , these methods are also provided by the Fragment class.
Starting Activities in Multi-Window Mode
- Activity#enterPictureInPictureMode() can be used to put an activity in picture-in-picture mode. Note that activities in PiP mode don’t get notified about input events — use MediaSession#setMediaButtonReceiver() if you want to handle such events. Also make sure to check the Android Developers website if you’re interested in Picture-in-picture on Android N.
- If the device is in split-screen mode, you can tell the system to launch another activity next to yours by using the Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT flag. The flag has no effect if not in split-screen mode.
- If the device is in freeform mode, ActivityOptions#setLaunchBounds() can be used to specify the new activity’s dimensions and location on the screen.
For code examples, check out the Multi-Window Playground sample app: adjacent activity example, launch bounds example.
Drag and Drop
While drag and drop support has been around since Honeycomb, it was previously only possible within the same activity. It’s now supported in multi-window as well.
Implementing this seems to be mostly the same as before, with a few additions for cross-activity drag and drop:
- View#startDragAndDrop()
- New alias for View#startDrag() .
- To enable cross-activity drag and drop, pass the new flag View#DRAG_FLAG_GLOBAL .
- If you need to give URI permissions to the recipient activity, pass the new flags View#DRAG_FLAG_GLOBAL_URI_READ or View#DRAG_FLAG_GLOBAL_URI_WRITE , as appropriate.
- View#updateDragShadow()
- Replaces the drag shadow for a drag operation currently in progress. Can only be called by the app that originated the drag operation.
- View#cancelDragAndDrop()
- Cancels a drag operation currently in progress. Can only be called by the app that originated the drag operation.
Other Notable Additions
- Checking if a device supports freeform or picture-in-picture modes is possible via PackageManager#hasSystemFeature() , using PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT and PackageManager#FEATURE_FREEFORM_PICTURE_IN_PICTURE respectively.
- The android:windowBackground attribute can be used as the background drawable, if the activity is being resized and its rendering is lagging behind. If android:windowBackground is unset, android:windowBackgroundFallback is used instead. Refer to the Multi-Window Playground sample app for an example.
UX Best Practices:
Wale offered some best practices to make sure your users have the best experience possible:
- Handle mode changes elegantly:
- Maintain UI consistency regardless of orientation. Don’t have elements change positions to allow for smooth transitions.
- Expanding on the above, don’t switch between very different layouts for phone/tablet layouts. Instead, adapt the tablet layout for smaller sizes for consistency.
- Make sure your activities adapt to small sizes by following the Material Design patterns.
- Use FLAG_ACTIVITY_LAUNCH_ADJACENT when it makes sense to make for a more enjoyable experience in split-screen mode.
- Only declare resizing incompatibility when justified. As we discussed above, it makes your app stand out in a bad way otherwise.
Useful Resources
Wale ended the session by offering some additional useful resources:
Источник