关于Android9.0适配(SDK28)

关于Android9.0适配(SDK28),第1张

概述##Android9Pie重要功能1、Android9Pie是Android的一次重大更新,首先Pie带来了一个全新的Android仪表板,可以让用户知道其在设备上花费的时间,这与Apple的屏幕时间功能类似。应用程序屏幕被重新设计,支持iPhoneX等带有刘海的显示器设备。Pie也使用了一种新的基

##AndroID 9 PIE重要功能

1、AndroID 9 PIE 是 AndroID 的一次重大更新,首先 PIE 带来了一个全新的 AndroID 仪表板,可以让用户知道其在设备上花费的时间,这与 Apple 的屏幕时间功能类似。应用程序屏幕被重新设计,支持 iPhone X 等带有刘海的显示器设备。PIE 也使用了一种新的基于手势的系统界面,具有类似 iPhone 的滑动功能,可以在 *** 作系统中导航。名为 Shush 的勿扰功能在手机屏幕朝下放置时会使 AndroID 设备静音,而 Wind Down 功能可让手机界面变为灰色,以减少 AndroID 用户在特定睡眠时间使用手机的可能性。

2、AndroID 9 PIE 还带来 AI 驱动的 Adaptive Battery,可通过优先处理用户最有可能使用的应用程序来优化电池电量,利用机器学习技术对系统资源进行有效分配,更专注于用户最常用的应用。如果用户已经针对低耗电模式、应用待机模式以及后台限制对您的应用进行过相关优化,那么它就应该已经能够和动态电量管理特性完美配合。

3、与其它版本的 AndroID 一样,AndroID 9 PIE 仅限于部分手机升级使用,每个手机厂商都需要经过定制才能对用户推出相应的版本更新。目前的情况是 AndroID PIE 已经面向 Pixel 手机推出,接下来几个月内将更新包括 Sony Mobile、Xiaomi、Oppo、Vivo、OnePlus 和 Essential 等厂商的最新设备。此外,适用于 Pixel 设备的系统映像现可供下载,支持手动刷机。

4、请前往 AndroID开源项目库 资源库中的 AndroID 9 板块,获取更多 AndroID 9 的相关资源。

##简要说明AndroID 9 PIE重要功能

1、手势:AndroID PIE中加入全新的全面屏 *** 作手势,与iPhone X的 *** 作类似,但屏幕底部依然有导航键,不过只剩返回主菜单和后退。

2、AndroID Dashboard:这是一种查看APP使用时间的软件,这一点与iOS 12的屏幕使用时间功能类似。

3、Wind Down:在夜间使用手机时能将界面调整为灰色,也就是夜间模式。

4、Adaptive Battery(自适应电池用量):对用户常用的软件进行优化,控制cpu资源占用。

5、Shush勿扰功能:开启该功能后,当手机屏幕朝下,设备可以自动静音。

6、Actions和Slices:这两项功能是为了节省用户 *** 作,比如Actions,检测到手机插入耳机后,会自动跳出音乐相关的App,方便用户选择;而Slices则能在App里节省用户 *** 作,比如搜索打车软件,会自动跳选出叫车回家、目的地等。这类似于Smartisan OS的“一步”、Miui的“传送门”,主要目的是为了简化用户对手机的 *** 作。

7、界面调整:通知栏、顶部图标等一些功能也有着改变。

##Channel settings, broadcasts, and Do Not disturb
AndroID 8.0 引入了通知渠道,允许您为要显示的每种通知类型创建可由用户自定义的渠道。 AndroID 9 通过下列变更简化通知渠道设置:

屏蔽渠道组:现在,用户可以针对某个应用在通知设置中屏蔽整个渠道组。 您可以使用 isBlocked()函数确定何时屏蔽一个渠道组,从而不会向该组中的渠道发送任何通知。
此外,您的应用可以使用全新的 getNotificationChannelGroup()函数查询当前渠道组设置。

全新的广播 Intent 类型:现在,当通知渠道和渠道组的屏蔽状态发生变更时,AndroID 系统将发送广播 Intent。 拥有已屏蔽的渠道或渠道组的应用可以侦听这些 Intent 并做出相应的回应。 有关这些 Intent *** 作和 extra 的更多信息,请参阅 notificationmanager 参考中更新的常量列表。 有关响应广播 Intent 的信息,请参阅广播。

notificationmanager.Policy 有 3 种新的“请勿打扰”优先级类别:

PRIORITY_category_ALARMS优先处理警报。

PRIORITY_category_MEDIA优先处理媒体源的声音,如媒体和语音导航。

PRIORITY_category_SYstem优先处理系统声音。

notificationmanager.Policy 还有 7 种新的“请勿打扰”常量,可以用来抑制视觉中断:

SUPpressed_EFFECT_FulL_SCREEN_INTENT防止通知启动全屏 Activity。

SUPpressed_EFFECT_liGHTS屏蔽通知灯。

SUPpressed_EFFECT_PEEK防止通知短暂进入视图(“滑出”)。

SUPpressed_EFFECT_STATUS_bar防止通知显示在支持状态栏的设备的状态栏中。

SUPpressed_EFFECT_BADGE在支持标志的设备上屏蔽标志。 如需了解详细信息,请参阅修改通知标志。

SUPpressed_EFFECT_AMBIENT在支持微光显示的设备上屏蔽通知。

SUPpressed_EFFECT_NOTIFICATION_List防止通知显示在支持列表视图(如通知栏或锁屏)的设备的列表视图中。

##隐私权变更-现在收的原来越紧,安卓也越来越规范
为了增强用户隐私,AndroID 9 引入了若干行为变更,如限制后台应用访问设备传感器、限制通过 Wi-Fi 扫描检索到的信息,以及与通话、手机状态和 Wi-Fi 扫描相关的新权限规则和权限组。

无论采用哪一种目标 SDK 版本,这些变更都会影响运行于 AndroID 9 上的所有应用。

##后台对传感器的访问受限
AndroID 9 限制后台应用访问用户输入和传感器数据的能力。 如果您的应用在运行 AndroID 9 设备的后台运行,系统将对您的应用采取以下限制:

您的应用不能访问麦克风或摄像头。
使用连续报告模式的传感器(例如加速度计和陀螺仪)不会接收事件。
使用变化或一次性报告模式的传感器不会接收事件。
如果您的应用需要在运行 AndroID 9 的设备上检测传感器事件,请使用前台服务。

##限制访问通话记录
AndroID 9 引入 CALL_LOG 权限组并将 READ_CALL_LOG、WRITE_CALL_LOG和 PROCESS_OUTGOING_CALLS权限移入该组。 在之前的 AndroID 版本中,这些权限位于 PHONE 权限组。

如果应用需要访问通话记录或者需要处理去电,则您必须向 CALL_LOG权限组明确请求这些权限。 否则会发生 SecurityException。

##限制访问电话号码
在未首先获得 READ_CALL_LOG 权限的情况下,除了应用的用例需要的其他权限之外,运行于 AndroID 9 上的应用无法读取电话号码或手机状态。

与来电和去电关联的电话号码可在手机状态广播(比如来电和去电的手机状态广播)中看到,并可通过 PhonestateListener 类访问。 但是,如果没有 READ_CALL_LOG 权限,则 PHONE_STATE_CHANGED 广播和 PhonestateListener 提供的电话号码字段为空。

要从手机状态中读取电话号码,请根据您的用例更新应用以请求必要的权限:

要通过 PHONE_STATE Intent *** 作读取电话号码,同时需要 READ_CALL_LOG 权限和 READ_PHONE_STATE 权限。
要从 onCallStateChanged() 中读取电话号码,只需要 READ_CALL_LOG 权限。 不需要 READ_PHONE_STATE 权限。

##电话信息现在依赖设备位置设置
如果用户在运行 AndroID 9 的设备上停用设备定位,则以下函数不提供结果:

TelephonyManager.getAllCellinfo()
TelephonyManager.Listen()
TelephonyManager.getCellLocation()
TelephonyManager.getNeighboringCellinfo()

##Build.SERIAL 始终设置为 “UNKNowN” 以保护用户的隐私。
如果您的应用需要访问设备的硬件序列号,您应改为请求 READ_PHONE_STATE权限,然后调用 getSerial()。

##多进程 webvIEw 信息访问限制
在 AndroID P 中为了提升系统的安全性,用户无法在多进程的 webvIEw 中共享数据目录,该目录下存储的是一些 cookies、http 缓存和其他一些永久、临时的缓存。当下不少应用会把 webvIEw 放在另一个进程中打开以避免内存泄漏,但是他们 cookies 的设置往往还是在主进程中,所以开发者需要仔细排查自己的应用是否有这么使用,webvIEw 相关运行是否正常等。

##对使用非 SDK 接口的限制
为帮助确保应用稳定性和兼容性,此平台对某些非 SDK 函数和字段的使用进行了限制;无论您是直接访问这些函数和字段,还是通过反射或 JNI 访问,这些限制均适用。 在 AndroID 9 中,您的应用可以继续访问这些受限的接口;该平台通过 toast和日志条目提醒您注意这些接口。 如果您的应用显示这样的 toast,则必须寻求受限接口之外的其他实现策略。 如果您认为没有可行的替代策略,您可以提交错误以请求重新考虑此限制。

##对于非SDK 接口
浅灰名单:仍可以访问的非 SDK 函数/字段。
深灰名单:
对于目标 SDK 低于 API 级别 28 的应用,允许使用深灰名单接口。
对于目标 SDK 为 API 28 或更高级别的应用:行为与黑名单相同。
黑名单:受限,无论目标 SDK 如何
平台将提示接口并不存在。
例如,无论应用何时尝试使用接口,平台都会引发 NoSuchMethodError/NoSuchFIEldException,即使应用想要了解某个特殊类别的字段/函数名单,平台也不会包含接口。

##检测是否使用了非SDK接口
工具verIDex
下载工具,阅读README.txt
打包一个应用 APK,建议使用 release 包,排除一些未使用到的单元测试类或者其他因素的影响,取消混淆,将 APK 放到工具目录下;
执行命令 ./appcompat.sh --dex-file=test.apk,在终端上会输出三个名单每个 API 的详细调用处

##P版本三方适配挖孔屏方案
注意,以下接口都是要Build.VERSION.SDK_INT >= 28才能调用到。
1、 新增挖孔屏挖孔尺寸和位置接口

class WindowInsets {displayCutout getdisplayCutout();}class displayCutout {int getSafeInsetleft();int getSafeInsettop();int getSafeInsetRight();int getSafeInsetBottom();Region getBounds();}

2、新窗口布局模式,允许应用程序请求是否在挖孔区域布局:

class WindowManager.LayoutParams {int layoutIndisplayCutoutMode;final int LAYOUT_IN_disPLAY_CUTOUT_MODE_DEFAulT;final int LAYOUT_IN_disPLAY_CUTOUT_MODE_ALWAYS;final int LAYOUT_IN_disPLAY_CUTOUT_MODE_NEVER;    }

layoutIndisplayCutoutMode值说明:

a)LAYOUT_IN_disPLAY_CUTOUT_MODE_DEFAulT:默认情况下,全屏窗口不会使用到挖孔区域,非全屏窗口可正常使用挖孔区域。(模式在全屏显示下跟LAYOUT_IN_disPLAY_CUTOUT_MODE_NEVER一样。当刘海区域完全在系统的状态栏时,LAYOUT_IN_disPLAY_CUTOUT_MODE_DEFAulT的显示效果与LAYOUT_IN_disPLAY_CUTOUT_MODE_SHORT_EDGES一致。)b)LAYOUT_IN_disPLAY_CUTOUT_MODE_ALWAYS(LAYOUT_IN_disPLAY_CUTOUT_MODE_SHORT_EDGES):窗口声明使用挖孔区域(模式会让屏幕到延申刘海区域中)c)LAYOUT_IN_disPLAY_CUTOUT_MODE_NEVER:窗口声明不使用挖孔区域(模式不会让屏幕到延申刘海区域中,会留出一片黑色区域。)

参数使用示例:

public class NotchActivity extends Activity {    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //去掉标题        requestwindowFeature(Window.FEATURE_NO_Title);        //开局就一张背景图        setContentVIEw(R.layout.notch);        //全屏显示        getwindow().getDecorVIEw().setsystemUIVisibility(VIEw.SYstem_UI_FLAG_FulLSCREEN | VIEw.SYstem_UI_FLAG_LAYOUT_FulLSCREEN);        WindowManager.LayoutParams lp = getwindow().getAttributes();                //1        lp.layoutIndisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_disPLAY_CUTOUT_MODE_NEVER;        //2//        lp.layoutIndisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_disPLAY_CUTOUT_MODE_SHORT_EDGES;        //3//        lp.layoutIndisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_disPLAY_CUTOUT_MODE_DEFAulT;        getwindow().setAttributes(lp);    }}
AndroID P提供提供的刘海屏适配方案
a.对于有状态栏的页面,不会受到刘海屏特性的影响,因为刘海屏包含在状态栏中了;
b.全屏显示的页面,系统刘海屏方案会对应用界面做下移处理,避开刘海区显示,这时会看到刘海区域变成一条黑边,完全看不到刘海了;
c.已经适配AndroID P应用的全屏页面可以通过谷歌提供的适配方案使用刘海区,真正做到全屏显示。

目前AndroID支持了三类凹口屏幕类型:边角显示屏凹口(斜刘海)、双显示屏凹口(刘海+胡子)、长型显示屏凹口(刘海
Google提供刘海规格<=系统状态栏

双显示屏凹口接口测试代码:

public class NotchActivity extends Activity {    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //开局就一张背景图        setContentVIEw(R.layout.notch);        getNotchParams();    }    @TargetAPI(28)    public voID getNotchParams() {        final VIEw decorVIEw = getwindow().getDecorVIEw();        decorVIEw.post(new Runnable() {            @OverrIDe            public voID run() {                WindowInsets rootwindowInsets = decorVIEw.getRootwindowInsets();                if (rootwindowInsets == null) {                    Log.e("TAG", "rootwindowInsets为空了");                    return;                }                displayCutout displayCutout = rootwindowInsets.getdisplayCutout();                Log.e("TAG", "安全区域距离屏幕左边的距离 SafeInsetleft:" + displayCutout.getSafeInsetleft());                Log.e("TAG", "安全区域距离屏幕右部的距离 SafeInsetRight:" + displayCutout.getSafeInsetRight());                Log.e("TAG", "安全区域距离屏幕顶部的距离 SafeInsettop:" + displayCutout.getSafeInsettop());                Log.e("TAG", "安全区域距离屏幕底部的距离 SafeInsetBottom:" + displayCutout.getSafeInsetBottom());                                List<Rect> rects = displayCutout.getBoundingRects();                if (rects == null || rects.size() == 0) {                    Log.e("TAG", "不是刘海屏");                } else {                    Log.e("TAG", "刘海屏数量:" + rects.size());                    for (Rect rect : rects) {                        Log.e("TAG", "刘海屏区域:" + rect);                    }                }            }        });    }}

输出结果:

E/TAG: 安全区域距离屏幕左边的距离 SafeInsetleft:0E/TAG: 安全区域距离屏幕右部的距离 SafeInsetRight:0E/TAG: 安全区域距离屏幕顶部的距离 SafeInsettop:112E/TAG: 安全区域距离屏幕底部的距离 SafeInsetBottom:112E/TAG: 刘海屏数量:2E/TAG: 刘海屏区域:Rect(468, 0 - 972, 112)E/TAG: 刘海屏区域:Rect(468, 2448 - 972, 2560)

##上面是AndroID P才有的解决方案,在P之前呢,上面的代码通通都没用。然而我们伟大的国产厂商在AndroID P之前(基本都是AndroID O)就用上了高档大气上档次的刘海屏,所以,这也造就了各大厂商在AndroID P之前的解决方案百花齐放。下面,我们来看下主流厂商:华为、vivo、OPPO、小米等所提供的方案。

##华为

a. 使用刘海区显示
使用新增的Meta-data属性androID.notch_support。
在应用的AndroIDManifest.xml中增加Meta-data属性,此属性不仅可以针对Application生效,也可以对Activity配置生效。
如下所示:

<Meta-data androID:name="androID.notch_support" androID:value="true"/>

对Application生效,意味着该应用的所有页面,系统都不会做竖屏场景的特殊下移或者是横屏场景的右移特殊处理。
对Activity生效,意味着可以针对单个页面进行刘海屏适配,设置了该属性的Activity系统将不会做特殊处理。

实际上还有一种代码实现的方式,不过代码比较多,这里就不贴了,有兴趣的话可以在文末的链接中点进去看看。
b. 是否有刘海屏
通过以下代码即可知道华为手机上是否有刘海屏了,true为有刘海,false则没有。

    public static boolean hasNotchAtHuawei(Context context) {        boolean ret = false;        try {            ClassLoader classLoader = context.getClassLoader();            Class HwNotchSizeUtil = classLoader.loadClass("com.huawei.androID.util.HwNotchSizeUtil");            Method get = HwNotchSizeUtil.getmethod("hasNotchInScreen");            ret = (boolean) get.invoke(HwNotchSizeUtil);        } catch (ClassNotFoundException e) {            Log.e("Notch", "hasNotchAtHuawei ClassNotFoundException");        } catch (NoSuchMethodException e) {            Log.e("Notch", "hasNotchAtHuawei NoSuchMethodException");        } catch (Exception e) {            Log.e("Notch", "hasNotchAtHuawei Exception");        } finally {            return ret;        }    }

c. 刘海尺寸
华为提供了接口获取刘海的尺寸,如下:

    //获取刘海尺寸:wIDth、height    //int[0]值为刘海宽度 int[1]值为刘海高度    public static int[] getNotchSizeAtHuawei(Context context) {        int[] ret = new int[]{0, 0};        try {            ClassLoader cl = context.getClassLoader();            Class HwNotchSizeUtil = cl.loadClass("com.huawei.androID.util.HwNotchSizeUtil");            Method get = HwNotchSizeUtil.getmethod("getNotchSize");            ret = (int[]) get.invoke(HwNotchSizeUtil);        } catch (ClassNotFoundException e) {            Log.e("Notch", "getNotchSizeAtHuawei ClassNotFoundException");        } catch (NoSuchMethodException e) {            Log.e("Notch", "getNotchSizeAtHuawei NoSuchMethodException");        } catch (Exception e) {            Log.e("Notch", "getNotchSizeAtHuawei Exception");        } finally {            return ret;        }    }
vivo

vivo在设置–显示与亮度–第三方应用显示比例中可以切换是否全屏显示还是安全区域显示。
a. 是否有刘海屏

    public static final int VIVO_NOTCH = 0x00000020;//是否有刘海    public static final int VIVO_FILLET = 0x00000008;//是否有圆角    public static boolean hasNotchAtVivo(Context context) {        boolean ret = false;        try {            ClassLoader classLoader = context.getClassLoader();            Class FtFeature = classLoader.loadClass("androID.util.FtFeature");            Method method = FtFeature.getmethod("isFeatureSupport", int.class);            ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH);        } catch (ClassNotFoundException e) {            Log.e("Notch", "hasNotchAtVivo ClassNotFoundException");        } catch (NoSuchMethodException e) {            Log.e("Notch", "hasNotchAtVivo NoSuchMethodException");        } catch (Exception e) {            Log.e("Notch", "hasNotchAtVivo Exception");        } finally {            return ret;        }    }

b. 刘海尺寸
vivo不提供接口获取刘海尺寸,目前vivo的刘海宽为100dp,高为27dp。

##oppo
OPPO目前在设置 – 显示 – 应用全屏显示 – 凹形区域显示控制,里面有关闭凹形区域开关。
a. 是否有刘海屏

    public static boolean hasNotchAtopPO(Context context) {        return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");    }

b. 刘海尺寸
OPPO不提供接口获取刘海尺寸,目前其有刘海屏的机型尺寸规格都是统一的。不排除以后机型会有变化。
其显示屏宽度为1080px,高度为2280px。刘海区域则都是宽度为324px, 高度为80px。

##小米
a.是否有刘海屏
系统增加了 property ro.miui.notch,值为1时则是 Notch 屏手机。
手头上没有小米8的手机,暂时没法验证,这里就不贴代码了,免得误导大家。后面测试过再放出来。
b. 刘海尺寸
小米的状态栏高度会略高于刘海屏的高度,因此可以通过获取状态栏的高度来间接避开刘海屏,获取状态栏的高度代码如下:

    public static int getStatusbarHeight(Context context) {        int statusbarHeight = 0;        int resourceID = context.getResources().getIDentifIEr("status_bar_height", "dimen", "androID");        if (resourceID > 0) {            statusbarHeight = context.getResources().getDimensionPixelSize(resourceID);        }        return statusbarHeight;    }

其他手机也可以通过这个方法来间接避开刘海屏,但是有可能有些手机的刘海屏高度会高于状态栏的高度,所以这个方法获取到的结果并不一定安全。

总结

以上是内存溢出为你收集整理的关于Android9.0适配(SDK28)全部内容,希望文章能够帮你解决关于Android9.0适配(SDK28)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1057470.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存