Android Q — is the 10th major release and the 17th version of the Android mobile operating system. The first Beta of Android Q was released on March 13, 2019, today we have the 4th version to test already. However, displeasing moments still take place like launcher crashing, problems with the camera or System UI process crash in case of the telephone being unblocked with a fingerprint sensor.
Anyway, Google Android Q Beta releases 5 and 6 are planned in July and approximately by the end of the quarter a stable release is expected. Let’s see what significant and interesting changes are going to take place and what innovations should the users and the developers expect in the new android version. I guess it would be better to divide the changes which concern UI and those in programming approach.
What Has Changed In The Display?
1) In the latest android version, the developers have received an opportunity to reflect communication interface settings right in the app without leaving it. There will not be a necessity anymore to open the system settings as a separate activity. By the way, it looks even more like the BottomSheet now, which allows switching mobile internet or Bluetooth on or connect to WiFi.
The developer also receives tem access to NFC settings, volume, and separate WiFi connectivity. To call the settings the user should make an intent and define what should be adjusted exactly.
Parameters possible: ACTION_INTERNET_CONNECTIVITY / ACTION_WIFI / ACTION_NFC
val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY) startActivityForResult(panelIntent, CONNECTIVITY_REQUEST_CODE)
2) Content sharing features have been extended as well. DirectShare API allows now not only to add the content to the preview but to indicate a certain category of the apps or users, to share this content with.
Below you can see an example of simple usage.
privatefun shareContent(imageUrl: Uri?=null){if(imageUrl ==null){ imagePicker?.choosePicture(false)}else{val sharingIntent = Intent(Intent.ACTION_SEND) sharingIntent.type="text/plain" sharingIntent.putExtra(Intent.EXTRA_TITLE, "Send message") sharingIntent.putExtra(Intent.EXTRA_TEXT, "Hello!") // (Optional) if you want a preview thumbnail, create a content URI and add it// The system only supports content URIsval thumbnail = getClipDataThumbnail(imageUrl)if(thumbnail !=null){ sharingIntent.clipData= thumbnail sharingIntent.flags= Intent.FLAG_GRANT_READ_URI_PERMISSION} startActivity(Intent.createChooser(sharingIntent, null))}} privatefun getClipDataThumbnail(imageUri: Uri): ClipData?{returntry{ ClipData.newUri( contentResolver, null, imageUri )}catch(e:FileNotFoundException){ e.printStackTrace()null}catch(e:IOException){ e.printStackTrace()null}}
A unique identifier to the media file is rendered as a parameter of the shareContent function. You can choose any file picker, but it’s essential that one of the parameters it returns was Uri.
4) A feature of floating windows in the form of the bubble was added. It is exactly like in the Facebook messenger. Now you do not have to create something from scratch or beat your head with something, at present, it’s a box solution. Moreover, there are several kinds of bubbles: simple ones, which appear on the screen and those opened automatically.
To receive such a result, we have to add parameters in the manifest to declare activity, which will open on clicking on the bubble
<activity android:name=".bubbles.BubbleActivity" android:allowembedded="true" android:documentlaunchmode="always" android:resizeableactivity="true"></activity>
and pass PendingIntent over to metadata of notification.
privatefun createNotificationChannel(){// Create the NotificationChannel, but only on API 26+ because// the NotificationChannel class is new and not in the support libraryif(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){val name ="BubbleBot"val importance = NotificationManager.IMPORTANCE_HIGHval channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance)// Register the channel with the system; you can't change the importance// or other notification behaviors after thisval notificationManager = getSystemService(NotificationManager::class.java) notificationManager?.createNotificationChannel(channel)}} @TargetApi(Build.VERSION_CODES.Q)privatefun showBubble(){val target = Intent(this, BubbleActivity::class.java)val bubbleIntent = PendingIntent.getActivity(this, 0, target, 0) // Create bubble metadataval bubbleData = Notification.BubbleMetadata.Builder() .setDesiredHeight(600) .setIcon(Icon.createWithResource(this, R.drawable.ic_launcher_foreground)) .setIntent(bubbleIntent) .build() val chatBot = Person.Builder() .setBot(true) .setName("BubbleBot") .setImportant(true) .build() val notification = Notification.Builder(this, NOTIFICATION_CHANNEL_ID) .setContentIntent(bubbleIntent) .setSmallIcon(R.drawable.ic_launcher_foreground) .setBubbleMetadata(bubbleData) .addPerson(chatBot) .build() val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)as NotificationManager notificationManager.notify(1, notification)}
Through metadata, one can also set the display of the bubble and the window, which will open. For example, we pass over the height of the window and the icon of the bubble. Besides metadata, we have the opportunity to pass useful information over, for instance, messages received through notifications.
5) The request for geolocation access has also undergone some changes. The user can now define the mode of its usage: the app can use geolocation only when launched or constantly. In other words, the user can now define if the app should use device coordinates when inactive.
@TargetApi(Build.VERSION_CODES.Q)privatefun checkBackgroundLocalePermission(){val permissionAccessCoarseLocationApproved = ActivityCompat .checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)== PackageManager.PERMISSION_GRANTED if(permissionAccessCoarseLocationApproved){val backgroundLocationPermissionApproved = ActivityCompat .checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)== PackageManager.PERMISSION_GRANTED if(backgroundLocationPermissionApproved){ Toast.makeText(this, "Location enable", Toast.LENGTH_SHORT).show()}else{ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), LOCALE_REQUEST_CODE )}}else{ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION), LOCALE_REQUEST_CODE )}}
What Has Changed Under The Hood?
1) First of all most of the changes concern the additional and folding screens support. Exactly like this, from now Android will support the unfolding screens from the box. As we have already mentioned above, the manifest has received a new directive android:resizeableActivity="true".
In such a case, when the screen of a smartphone is unfolded a callback will be called on onConfigurationChanged with the new parameters and the activity will be automatically spread to the whole screen.
By the way, the official papers say that if you do not indicate it in the manifest that the activity can change its scope, the new part of the screen will be looked at as an additional display. Then a user will be able to launch one more app on it.
The activities life cycle has experienced alterations as well. A new callback was added onTopResumedActivityChanged. It is caused by the necessity to launch 2 apps on separate screens sometimes. However, only one application has focus, on receiving a focus by another app, this callback will be called.
2) It’s important to mention a great number of changes to packages, inner libraries and the APT principle of work. dex2oat format, for instance, will not be supported anymore.
For more detailed information about android q update and new features, you can watch the preview page.