Adapting to Android P Behavior Changes (Part 1)
The guide’s first part explains Android P’s major behavior changes—official notch detection, restrictions on hidden APIs, new App Standby Buckets and foreground‑service rules, removal of the legacy Apache HTTP client, privacy updates, HEIF image support, and the ImageDecoder API with practical code examples.
Android P introduces many behavior changes that require developers to adapt their apps. This article (Part 1) details the main changes and provides practical code examples.
1. Full‑screen (notch) detection
Before Android P, manufacturers implemented their own notch‑detection logic. Android P provides an official API. The following code shows a common but problematic implementation that may cause the navigation bar to become transparent on some devices:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@RequiresApi(api = 28)
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
if (windowInsets != null) {
DisplayCutout cutout = windowInsets.getDisplayCutoff();
if (cutout != null) {
List<Rect> rects = cutout.getBoundingRects();
// Determine notch screen by checking rects
if (rects != null && rects.size() > 0) {
isNotchScreen = true;
}
}
}
return windowInsets;
}
});
}This code works for detection but may affect system UI. The recommended implementation uses decorView.getRootWindowInsets() :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowInsets windowInsets = decorView.getRootWindowInsets();
if (windowInsets != null) {
DisplayCutout displayCutout = windowInsets.getDisplayCutout();
if (displayCutout != null) {
List<Rect> rects = displayCutout.getBoundingRects();
if (rects != null && rects.size() > 0) {
isNotchScreen = true;
}
}
}
}2. Non‑SDK API adaptation
Android P restricts the use of hidden (non‑SDK) APIs. The APIs are divided into three lists: light‑grey, dark‑grey, and black. Developers should avoid dark‑grey and black‑list APIs.
Google provides a scanning tool to locate such calls in an APK:
#1: Linking dark greylist Landroid/os/SystemProperties;->get(Ljava/lang/String;)Ljava/lang/String; use(s):
Ltmsdkobf/gv;->a(Ljava/lang/String;)Ljava/lang/String;
#2: Linking dark greylist Landroid/os/SystemProperties;->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; use(s):
Ltmsdkobf/gp;->b(Landroid/content/Context;)Ljava/lang/String;
...After locating the calls, developers should replace them with public APIs, request Google to move needed APIs to the light‑grey list, or add runtime guards:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// Android P or above
} else {
// below Android P
}3. Power‑management improvements
Android P introduces App Standby Buckets (Active, Working Set, Frequent, Rare, Never Used) that affect background execution, alarms, and network access. Apps can query their bucket via UsageStatsManager.getAppStandbyBucket() . Background execution limits apply to all apps, and foreground services must use startForegroundService or JobIntentService when the app moves to background.
4. Apache HTTP client removal
When compiling with compileSdkVersion 28 , the legacy Apache HTTP client classes are no longer available. To keep using them, add the following line to the manifest:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>Alternatively, keep the module that uses Apache HTTP client compiled with compileSdkVersion below 28.
5. Other adaptations
Foreground services now require the FOREGROUND_SERVICE permission. Privacy changes include the deprecation of Build.SERIAL (now returns UNKNOWN ) and restrictions on multi‑process WebView data sharing.
6. New features – HEIF support
Android P adds full support for the HEIF image format. HEIF offers higher compression (≈2.4× JPEG) and supports animation, transparency, and thumbnails. Support can be checked with:
fun supportHEIF() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.PDecoding HEIF to Bitmap or Drawable is straightforward:
@TargetApi(28)
fun decodeHEIFDrawable(filePath: String): Drawable? {
if (!supportHEIF()) return null
val source = ImageDecoder.createSource(File(filePath))
return ImageDecoder.decodeDrawable(source)
}
@RequiresApi(28)
fun decodeHEIFBitmap(filePath: String): Bitmap? {
if (!supportHEIF()) return null
val source = ImageDecoder.createSource(File(filePath))
return ImageDecoder.decodeBitmap(source)
}When uploading HEIF images, developers must consider devices that cannot decode HEIF and either convert to JPEG on the client or provide both formats from the server.
7. New features – ImageDecoder
ImageDecoder replaces BitmapFactory and can decode PNG, JPEG, WEBP, GIF, and HEIF. It also supports animated images via AnimatedImageDrawable . Basic usage:
var drawable: Drawable = ImageDecoder.decodeDrawable(source)
if (drawable is AnimatedImageDrawable) {
image.setImageDrawable(drawable)
drawable.start()
}Developers can set a header listener to obtain image dimensions and adjust sampling:
val listener = object : OnHeaderDecodedListener {
fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source: Source) {
decoder.setTargetSampleSize(2)
}
}
val drawable = ImageDecoder.decodeDrawable(source, listener)Custom post‑processing (e.g., rounded corners) is possible via setPostProcessor :
var drawable = ImageDecoder.decodeDrawable(source) { decoder, info, src ->
decoder.setPostProcessor { canvas ->
val path = Path()
path.setFillType(Path.FillType.INVERSE_EVEN_ODD)
val width = canvas.getWidth()
val height = canvas.getHeight()
path.addRoundRect(0, 0, width, height, 20, 20, Path.Direction.CW)
val paint = Paint()
paint.isAntiAlias = true
paint.color = Color.TRANSPARENT
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
canvas.drawPath(path, paint)
PixelFormat.TRANSLUCENT
}
}If decoding fails partially, setOnPartialImageListener can allow the partially decoded image to be displayed instead of throwing a DecodeException :
var drawable = ImageDecoder.decodeDrawable(source) { decoder, info, src ->
decoder.setOnPartialImageListener { e -> true }
}References
https://developer.android.google.cn/about/versions/pie/android-9.0 https://mp.weixin.qq.com/s?__biz=MzI0MjgxMjU0Mg==&mid=2247486857&idx=1&sn=bb7777b6f69cba31ce9d68ffee9c8f47&scene=21#wechat_redirect https://blog.csdn.net/GenlanFeng/article/details/79496359 https://developer.android.com/about/versions/pie/power https://segmentfault.com/a/1190000015947004
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.