VIVO应用商店APP侵权投诉流程

VIVO应用商店APP侵权投诉流程

鉴于vivo开放平台中第三方提供的服务数量庞大,为了建立良好的市场秩序和保护权利人的合法权益,根据相关法律规定,制定以下处理流程,以尽可能保护权利人的合法权益。

侵权投诉流程

1.收集证据填写材料

若权利人认为第三方在vivo开放平台提供的服务侵犯其合法权益,请按照以下要求提交相关材料,通知vivo。

(1)投诉侵权通知书(《vivo开放平台侵权投诉通知书》点此下载

投诉侵权通知书需详细填写好以下内容:

i.权利人主体信息

提供权利人具体的联络信息,包括姓名、身份证或护照复印件(对自然人)、单位登记证明复印件(对单位)、通信地址、电话号码、传真和电子邮件。

ii.权利人的要求

权利人要求删除或者终止的服务的准确名称及截图

iii.构成侵权的证明材料

权利人提供包括但不限于被投诉方提供的服务构成对权利人的版权、商标权或专利权等侵权的有效证明材料等    

为保证侵权有效进行,请按照以下要求补充对应证明文件

iv.权利人保证

权利人的通知书应包含以下保证:权利人在本通知书中的陈述和提供的相关材料皆是充分、真实、和准确的,如果本通知书内容不完全属实,权利人自愿承担由此产生的一切法律后果,承担和赔偿vivo因根据权利人的通知书而删除或者断开被投诉侵权服务而给vivo公司造成的任何损失,包括但不限于vivo因向被投诉方或用户赔偿而产生的包括律师费在内的各种损失,此外,权利人还应赔偿因此给vivo造成的名誉、商誉等损失。

(2)构成侵权的初步证明材料

该初步证明材料应包括:

i.权利人拥有权利的权属证明材料:

包括但不限于相关有权机构颁发的版权证书、商标权证书、专利权证书、作品首次公开发表或发行日期证明材料、创作手稿、经权威机构签发的作品创作时间戳、作品备案证书等能证明权利人拥有相关权利的有效权属证明;

ii.被投诉方提供的服务构成侵权的证明:

包括但不限于被投诉方提供的服务对权利人的服务构成版权、商标权或专利权等侵权的有效证明材料等。

(3)权利人主体资质材料

权利人有效主体信息,若为代理,请提供代理主体营业执照及代理授权证明材料。

2.侵权投诉提交流程

①工单系统提交反馈

适用类型:app名称侵权、logo/icon侵权、APP卡通形象侵权、页面设计侵权、文学作品侵权、影视作品侵权、音乐作品侵权、ICP/IP地址/域名侵权、游戏元素侵权

提交方式:【管理中心】-【应用与游戏】-【工单系统】,选择“投诉举报类”—“应用或者游戏侵权投诉”,烦请按照要求填写信息,并提供证明材料。

②邮件提交反馈

适用类型:app软件代码侵权、游戏版号侵权等

提交方式:请按以下邮件格式,以贵公司企业邮箱发送邮件申请至devtousu@vivo.com

                标题:【侵权投诉】xxx(应用名)投诉侵权应用

                邮件正文:描述侵权情况以及下架需求。

                附件提交:

                包含营业执照、带有签章的《vivo开放平台侵权投诉通知书》(盖章扫描件),同时,附件需提交以下材料,相关有权机构颁发的版权证书、商标权证书。可提供补充材料如作品首次公开发表或发行日期证明材料、创作手稿、经权威机构签发的作品创作时间戳、作品备案证书等能证明权利人拥有相关权利的有效权属证明。若为代理,还请提供代理主体营业执照及代理授权证明材料。

3.平台回复处理结果

应用侵权投诉处理时效为6个工作日内,游戏侵权投诉处理时效为6~8个工作日内。vivo开放平台会根据权利人提供的相关资料进行核实验证,并回复处理结果,敬请耐心等待。

4.注意事项

(1)本文中的权利人,指拥有版权、商标权等合法权益的原始所有人或经原始所有人合法授权的代理人,包括自然人、法人或其他组织等。

(2)为了确保投诉的真实性和有效性,权利人的书面通知书及相关证明材料,原则上应提供原件(扫描件),不能提供原件的,应提供复印件(在复印件上应有权利人的签章)。

VIVO应用商店APP应用认领教程

VIVO应用商店APP应用认领教程

开发者要求拥有非自己账号下产品上传权限,而该应用为该开发者所属,因此申请包名归属权认领。接入支付的游戏暂不支持认领,如需认领,请联系您的对接商务。

一、应用认领

1. 发起应用认领

顶部导航选择【产品】-【应用分发】-【维护-认领】,点击认领

2. 应用认领步骤

步骤一:请填写需要认领的应用包名

步骤二:按照页面指示操作,上传打上签名的签名包。

       注:“签名空包”是平台提供的空包文件,您需要将下载的空包文件及签名说明传给您的技术人员并将要认领应用的签名打入空包。

步骤三:如需要认领的应用属于特殊行业,需提供认领账号的对应特殊行业资质,可参考《特殊行业资质规范》。

3. 查看认领结果

二、应用认领申诉

若无法通过签名包方式认领,请按照以下方式进行应用认领申诉,发送邮件至open@vivo.com。

标题:【认领申诉】xxx(权利人应用名)应用认领申诉

邮件正文:(请提交以下信息)

认领需求:

无法通过签名认领的原因:

认领应用包名:

认领应用名:

认领账号:

认领主体:

附件提交:

(注:

1.附件需提交认领者上传该应用对应的域名的权属证明,当无法提供域名权属证明时则优先提供营业执照及主流市场上架截图。如未在主流市场上架应用时,则补充提供软著或版权证明及其他市场上架截图。

2. 如需要认领的应用属于特殊行业,需提供认领账号的对应特殊行业资质,可参考《特殊行业资质规范》。)

PS:若被认领者因违规行为导致账号冻结,则旗下应用不予以认领,如被认领者存在未经授权上传他人应用、涉嫌侵权行为,认领者可进行线下申诉。

VIVO应用商店32/64分包上传说明

VIVO应用商店32/64分包上传说明

传包须知

前言

为提升终端用户使用体验,降低功耗影响,同时保证APP在手机上的运行效率和兼容性;vivo应用商店将针对不同机型下发合适的包体,推进国内安卓生态对64位架构的支持。

开发者可以在了解本文档描述的规则后,选择适合您的传包模式。

基本规则

  • 同一应用的包名、应用名称、签名需要保持一致;
  • 双包上传时,两个包体的md5值不能相同;
  • 新版本上架后,上一版本同一架构的安装包将被下架,不同架构的安装包不受影响。

单包上传规则

  • 2022年4月1日后新上传的应用,单包上传入口仅支持上传32/64位兼容包和64位架构包,不支持32位架构包;
  • 2022年10月12日起,在架包更新时,单包上传入口仅支持32/64位兼容包和64位架构包,不支持32位架构包(游戏包体更新则于12月1日起不支持32位架构包)。

注:为避免应用分发受影响,建议开发者尽快完成64位适配。

双包上传规则

  • 首次使用“双包上传”,或从“单包上传”更换为“双包上传”时:必须同时上传32位、64位架构包;
  • 通过双包上传并审核通过后,更新时允许在双包上传入口单独维护某个架构包;
  • 双包同时上传时,两个包体的versioncode需保持一致,且两个包体需要同时审核通过后才可上架。
  • 2022年4月1日后,64位架构包上传入口仅上传64位架构包,不支持兼容包。

操作方法/流程

一、创建流程

1、登录vivo开放平台账号→进入管理中心→应用与游戏→应用与游戏列表→点击【创建应用】;

2、录入基础信息后,点击【完善信息】,进入信息完善页面;

3、在该页面可选择APK上传方式为“单包上传”或“双包上传”;

4、包体上传后,等平台审核通过后则可发布。(注:选择“双包上传”则详见上述双包上传规则)

二、单双包切换限制

1、单双包入口可自由切换,但每次单包切换双包时,均需将32位、64位两个包同时上传,双包审核通过后,方可在双包入口单独维护某个架构包。

三、双包维护说明

1、首次使用“双包上传”,或从“单包上传”更换为“双包上传”时:必须同时上传32位、64位架构包;

2、已使用“双包上传”并审核通过后,更新时可单独维护“32位架构”或“64位架构”包体;

3、单独维护某个架构包体时,仅对新上传包体进行审核,未更新的架构会使用上一版本包体进行分发。

Logcat使用限制

Logcat是Android 系统提供的实时查询系统日志的命令工具,帮助开发者在开发调试阶段定位问题,优化自身功能。然而对logcat日志使用不当也会导致一些问题,如个人信息泄漏/功耗等,而开发者对这些问题则关注的少,为此vivo针对logcat做了部分的定制,以防止出现类似的问题。

1. 打印行数限制

vivo限制了logcat输出日志的频率,限制单个进程每秒只能打印 250行,一秒内超出的日志将会直接丢弃(每一秒的日志都是重新计数),并且打印以下的日志:

该日志是对应的进程中打印的,drop 关键字后面表示了当前丢失了多少行的日志,行数限制不区分日志等级。

应用开发者需要控制自身的日志打印量,不能无休止的刷日志。

2. 敏感数据过滤

任何的Android手机只要打开了开发者选项,都可以通过logcat打印系统日志,若日志中有个人数据打印则非常危险,为此vivo在logcat的输出增加了敏感信息脱敏功能,输出的日志中有敏感的数据(如:手机号,设备ID,经纬度,ip地址,URL等),都会全部转换为星号。

未脱敏日志

脱敏后日志

备注:在新的机型上,系统做了区分处理,debug版本应用打印的内容不会脱敏,release版本的会脱敏,满足开发者的调试需要。

3. Logcat调用限制

APP若在运行时需要读取系统日志定位自身发生的异常,调用 logcat 命令时必须增加 -d 参数,即调用logcat不能阻塞进程一直等待;若应用未增加此参数,则系统会特殊处理,实现同等效果(增加参数-d)。如下格式:logcat -d 

增加 -d 参数后,logcat 仅仅会读取当前系统缓存的日志,然后直接退出,不会一直阻塞住。未增加 -d 参数则会持续输出系统日志,对系统负载影响大,特别是系统日志量多的时候,对功耗的影响会非常的大。

VIVI消息推送OriginOS通知渠道 (Channel)规范

1.1  什么是通知渠道?

通知渠道 (Channel) 是 Android O 引入的新功能,旨在解决以下问题:

  • 应用的通知越来越多,给用户造成明显打扰。
  • 在用户有屏蔽应用的部分通知需求时,只能全局屏蔽这个应用的全部通知,不能屏蔽部分,然后留下对自己有用的。

从 Android8.0(API ≥ 26)开始,Android要求开发者必须为所有的通知分配渠道,不同类的消息走不同的渠道发送。用户可关闭单个渠道的消息通知,不会影响其它渠道的消息推送。以原子笔记(v1.0.3.02) 为例,通知分成了5种渠道,1个渠道分组(Channel Group),如下图:

  • 渠道:实际的通知类别,原子笔记分成了5类通知。
  • 渠道分组:一组渠道,仅用于做分组区分,没有更多的逻辑。
  • 每个通知渠道的权限互相独立,互不影响。例如,原子笔记的“录音”类通知为关闭,“提醒”类通知为优先显示。

1.2  如何适配通知渠道?

1. 在产品发布之前,需由产品和运营提前规划好该应用的通知渠道,如“订单通知”、“评论回复提醒”、“新资讯提醒”等,不同类别的消息走不同渠道发送。规划好的渠道不应该在不同版本频繁变更,以免用户设置发生变化。

2. 合理控制渠道数量,建议在2~7个之间;根据需要可以使用渠道分组来对渠道进行分组归类,方便用户区分识别;避免使用1个渠道发送多种类型的通知。

3. 渠道名称是对用户可见的,因此需要使用方便用户理解的文本,因此,渠道命名应符合通知内容特征,例如,发送快递接收信息的专用渠道,命名为“快递信息”,便于用户理解,同时避免名字重复。

4. 渠道名称需要做多语言适配(默认直接显示名称,如果要跟随系统语言的变化而变化,要提翻译),手机重启后才会切换其他语言。

1.3  通知渠道的优先级如何定义

渠道的优先级会影响通知的悬浮、响铃和振动。为了平衡业务发展的需求和通知栏的整体体验,通知栏对渠道优先级的定义做出如下规范:

优先级铃声振动在通知栏显示悬浮显示锁屏显示使用原则
max(以下简称“5”)允许允许允许允许允许(上线中)(用户设置不了)关系到用户生命和财产安全、需要用户立即作出反应否则会造成设备不可用或个人生命/财产受到威胁的通知,如台风预警、暴雨预告、流量预警等,通知栏会视应用使用情况决定是否收紧该能力
high(以下简称“4”)允许允许允许允许允许(上线中)用户短时间内必须了解或采取行动的通知,如信息、电话、账户变动等
default(以下简称“3”)允许允许允许用户在方便时需要尽早查看的通知,如好友申请等;
low(以下简称“2”)允许跟用户相关但可以等待的,或无需用户处理的通知,如关注的作者更新、有更新的内容等;
min(以下简称“1”)允许与用户完全无关的非必要信息,如促销内容、活动信息等;

具体到业务场景,本规范根据消息的类型,给出了每种消息优先级的可设置范围,不在以下范围内的,由各项目组与通知规范小组共同决策:

分类优先级上限类别举例
系统消息系统通知验证码4验证码信息
软件更新3APP版本更新提示信息
邮件3邮件的发送、接收状态信息
短信4短信,彩信等信息
语音通话4语音通话相关的信息
软件状态5与应用的运行、性能、权限、流量等通知信息
常驻信息4音乐类、工具类、天气类等常驻通知栏信息
用户订阅社交动态2用户之间的社交互动提醒,如:被赞、被@、评论、留言、关注、转发
非社交动态2非社交属性的且与用户相关的实时信息更新
订阅4用户主动订阅关注的内容更新提醒,如:你关注的xxxx更新
日程4用户设置的行程通知,提醒
物流4物流节点信息,包括收发货,派送,签收,取件通知等
订单4生成订单相关信息  如:下单成功  卖家收到新订单 订单详情
特殊关注4基于普通的动态、订阅消息之上的特别关注内容
待办4用户在app内设置的提醒信息
财务4包括收付款,红包,涉及金额、账单、交易等信息
出行4用户使用相关app时的导航、路线相关提醒
营销消息新闻资讯阅读推荐2非用户主动订阅,APP向用户推送的文字内容。如:微博、资讯、新闻、点评、小说、公告
音频推荐2非用户主动订阅,APP向用户推送的视频、音频、直播、
陌生人推荐2大V、主播、异性、可能认识的人等
理财2金融理财产品推荐,如:投资、贷款、股票、基金、贵金属。
天气2天气相关的推送
产品推荐广告促销2商品推广、宣传,或者折扣、红包、领劵优惠信息
产品推荐2所有商品、商家、店铺推荐
活动推送运营活动2各类APP内的活动、小游戏提醒,如:抽奖、积分、签到、任务、分享、偷菜、领金币、限时折扣、红包、返现、优惠卷
邀请2APP基于自身产品功能对用户发起的各类邀请,如:邀请用户点评、答题、发布视频、撰文等
IM消息即时聊天信息即时消息4用户与用户或商家进行交流时产生的文字推送
消息提醒4不展示具体消息内容的IM消息提醒,如:你收到一条新消息(伪装成消息提醒的内容推荐类不算)
其他消息/不在以上分类的,由各业务方与SQA共同决策

“社交动态”类需满足“交互要求”:1. 弹窗说明将收到该类别的PUSH通知。2. 用户可选择“同意”或“取消”,用户同意后可加入“系统消息”分类。

“订阅更新”类需满足“交互要求”:1. 弹窗说明将收到该类别的PUSH通知。2. 告知用户关闭通知的完整路径,可加入“系统消息”分类。

FAQ

1、一定要适配通知渠道吗?

取决于你的应用的API:

  • API ≥ 26(Android 8.0):必须适配,而且必须给每条通知指定一个渠道,否则无法发出通知
  • API ≤ 25(Android 7.1):可以不适配。在8.0及以上的设备,通知也能正常发出

2、一定要有渠道分组吗?

不是必须的。没必要强行设置渠道分组,应该视自己的业务需求而定。

3、我的通知是通过Vpush发的,我也能自己设置渠道吗?

目前,Vpush只有固定的渠道,不支持应用自定义Vpush渠道哦~

4、适配渠道后,在 Android 8.0 以前的设备会怎么表现

Android 8.0 以前的设备,会完全无视这个功能,因此不会带来任何兼容性问题。

VIVO高长宽比设备应用适配指导意见

一、 适配背景

目前vivo有意向采用1080×2400/1080×2460/1080×2520等更高长宽比分辨率,经测试发现有些游戏和应用存在异常边、花边、裁切、黑边过大等情况,为避免以上情况,需要对这些游戏和应用进行相应适配调整。建议游戏或应用适配时考虑更大屏幕比例的情况,提高不同屏幕比例的兼容性;同时建议不要固定屏幕比例来判断适配,这样会导致游戏或应用只能兼容固定屏幕比例。

二、调整意见

1、游戏logo或背景出现异常边

描述:logo或背景两侧,出现黑边、蓝边、白边等异常边。

原因:logo或背景宽高比例过小。

措施:建议采用第一条。

(1)提供宽高比例更大的logo或背景;

(2)优先匹配屏幕高度,宽度可稍微裁切(不影响用户体验);

(3)比例相差不大的情况下,可适度拉伸(不影响用户体验)。

2、游戏出现异常边

描述:游戏两侧出现黑边、蓝边、白边等异常边。

原因:游戏固定了宽高或屏幕比例。

措施:请参见第6条获取屏幕宽高,确保背景和游戏能充分铺满屏幕。

游戏各种按钮、状态栏等需要根据屏幕宽高,调整对屏幕相对位置,确保显示完整、布局美观。

3、游戏两边出现花边

描述:游戏两侧出现杂色边,后面内容覆盖了之前内容。

原因:游戏固定了宽高或屏幕比例,后续某帧超过该比例,造成花边。

措施:请参见第6条获取屏幕宽高,确保背景和游戏能充分铺满屏幕。

游戏各种按钮、状态栏等需要根据屏幕宽高,调整对屏幕相对位置,确保显示完整、布局美观。 

4、视频两边出现裁切

描述:播放视频时,视频宽度上发生裁切,造成显示内容变少。

原因:视频优先匹配高度,造成宽度上内容裁切。

措施:请参见第6条获取屏幕宽高,将优先适配高度,改为优先适配宽度,保证视频内容的完整性,并合理安排其他布局。

5、应用底部黑边过大

描述:应用底部黑边过大,底部文字、对话框等位置偏上,造成显示不美观。

原因:屏幕比例变大时,底部黑边相应变大,但是底部文字、对话框等未按屏幕高度动态调整,而是固定了与视频的相对位置。

措施:请参见第6条获取屏幕宽高,然后根据屏幕高度,向下动态调整文字或对话框的相对位置,使显示更美观。

6、获取屏幕宽高方法

(1)获取屏幕物理宽高

建议游戏或满屏应用使用,获取屏幕真实物理宽高。

    WindowManager manager = this.getWindowManager();
    Point outSize = new Point();

Display display = manager.getDefaultDisplay();
    display.getRealSize(outSize);
    int width = outSize.x; //屏幕物理宽度
    int height = outSize.y; //屏幕物理高度

(2)获取应用宽高

建议非满屏应用使用,在某些情况下,应用宽高和屏幕物理宽高有差异。

如在有导航栏、刘海、非透明状态栏等情况下,可以使用以下方法获取实际应用宽高。

WindowManager manager = this.getWindowManager();

DisplayMetrics outMetrics = new DisplayMetrics();

Display display = manager.getDefaultDisplay();

display.getMetrics(outMetrics);

int width = outMetrics.widthPixels; //应用宽度

int height = outMetrics.heightPixels; //应用高度

三、模拟验证

使用分辨率为1080的屏幕,比例任意的手机:

1、进入开发者选项,打开USB调试;

2、电脑进入cmd命令行,输入”adb devices”,确保能连上手机;

3、Cmd命令行输入:”adb shell wm size 1080×2400/1080×2460/1080×2520”

模拟分辨率为1080×2400/1080×2460/1080×2520的情况;

4、测试应用或游戏,是否出现黑边、花边、裁切等情况;

5、测试完毕,cmd命令行输入:”adb shell wm size reset”,恢复屏幕分辨率。

vivo X21屏下指纹适配指南

vivo X21屏下指纹适配指南,点击此处可下载开发过程中所需的全部代码。文档具体内容如下:

一、FingerprintInsets

public final class FingerprintInsets

extends Object

java.lang.Object    

↳  com.vivo.fingerprint.ud.FingerprintInsets

该类描述屏幕指纹相关信息,例如指纹图标位置,指纹图标显示状态等。该类会连接屏幕指纹服务获取状态信息,应用只有在 isReady() 返回 true 的时候才能通过该类的其它接口获取相关信息。使用本接口,需要应用声明com.vivo.fingerprint.permission.READ_STATE 权限,调用 create 方法后,应用不再使用该系列接口后应该调用 destroy 方法释放相关的资源,避免造成可能发生的内存泄露。

该类的方法都不是线程安全的,这就意味着所有方法都应该在同一线程中调用,create 方法会创建一个 Handler,因此该类的所有方法应该在主线程或者有 Looper 的线程中调用。

使用该类的 minSdkVersion 应该不小于 11(Android 3.0.x)。该类能够在 vivo 手机及其它 sdk version 不小于 11 的非 vivo 设备上使用。本类依赖 android-support-v4。

ICON_INVISIBLE

int ICON_INVISIBLE = 0

图标状态标记,表示指纹图标不可见。

值:0

ICON_VISIBLE

int ICON_VISIBLE = 1

图标状态标记,表示指纹图标可见。

static void setDebugEnable(boolean enable)

打开或者关闭内部日志

enable: 是否打开日志

static FingerprintInsets

create(Context context,FingerprintInsetsListener listener)

该类可以创建对象实例,如果多次调用该方法并且没有调用 destroy,则返回的是同一个对象,如果创建失败,则返回空,这种情况一般是在非 vivo 手机上调用该接口,如果创建成功,该方法会产生一个对 context 的弱引用对象,listener 可为 null。

context:组件上下文

listener:Insets 内部事件监听器

返回值:创建成功返回非空置,失败则为空

boolean isReady()

指纹相关状态是否初始化完毕,只有在初始化完毕后,才能调用其它接口获取正确的参数。

void destroy()

清理当前实例对象。

boolean hasUnderDisplayFingerprint()

当前机型是否有屏幕指纹,非 vivo 机型上始终返回 false

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

void setFingerprintInsetsListener(FingerprintInsetsListener listener)

设置 insets 事件监听器,用于 isReady 和 图标状态变化事件(显示,隐藏)监听。

listener:Insets 内部事件监听器

int getFingerprintIconState()

获取指纹图标状态,返回 ICON_INVISIBLE 或者 ICON_INVISIBLE

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

Rect getFingerprintIconPosition()

获取指纹图标位置,返回指纹图标 left, top, right, bottom四个维度,坐标值为屏幕绝对坐标。

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

int getFingerprintIconLeft()

获取指纹图标 left 值

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

int getFingerprintIconTop()

获取指纹图标 top 值

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

int getFingerprintIconRight()

获取指纹图标 right 值

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

int getFingerprintIconBottom()

获取指纹图标 bottom 值

注意:该方法只有在 isReady 和 hasUnderDisplayFingerprint 返回 true 时返回有效值。

二、FingerprintInsets.FingerprintInsetsListener

public interface FingerprintInsets.FingerprintInsetsListener

com.vivo.fingerprint.ud.FingerprintInsets.FingerprintInsetsListener

监听 FingerprintInsets 事件,包括 Insets 准备就绪,指纹图标显示或者隐藏。

void onReady()

Insets 准备就绪

void onIconStateChanged(int state)

指纹图标状态变化

state:FingerprintInsets.ICON_VISIBLE 可见,FingerprintInsets.ICON_VISIBLE 不可见,-1 状态更新中。

 代码示例 ↓ 

private FingerprintInsets mInsets;


class InsetsListener implements
   FingerprintInsets.FingerprintInsetsListener {
   @Override
   public void onReady() {
       boolean hasUdFeature =
           mInsets.hasUnderDisplayFingerprint();
       if (hasUdFeature) {
           final Rect rect =
             mInsets.getFingerprintIconPosition();
           Log.d(TAG, “iconRect:” +
                   rect.toShortString());
           // TODO: vivo device support
           // under display fingerprint.
       } else {
           // TODO: vivo device don’t
           // support under display 
           // fingerprint.
       }
   }


   @Override
   public void onIconStateChanged(int state) {
       Log.d(TAG, “onIconStateChanged ” + state);
   }
}


mInsets = FingerprintInsets.create(
       this, new InsetsListener());
if (mInsets == null) {
   // TODO: Not vivo device.
}


// Later call destroy if needed.
if (mInsets != null) {
   mInsets.setFingerprintInsetsListener(null);
   mInsets.destroy();
   mInsets = null;
}

移动智能终端补充设备标识服务

Android Q系统限制应用获取IMEI,DEVICE ID等标识。为满足移动应用开发者业务诉求,移动安全联盟(MSA)联合vivo等厂商共同开发了支持多厂商的统一补充设备标识调用SDK。现该统一补充设备标识调用SDK已通过vivo内部测试并开放对接。

更多问题请联系客服或对接商务。

相关附件:

附件1:移动智能终端补充设备标识体系统一调用SDK开发者说明文档v1.10

附件2:团体标准-移动智能终端补充设备标识规范

附件3:移动智能终端补充设备标识体系统一调用SDK+F&Qv1.0

附件4:msa_sdk_v1.0.10

vivo小窗适配指南

1、小窗功能介绍

vivo全局小窗在安卓原生的多窗口功能基础上,进行了一系列的优化和创新。以小窗的形式展现应用,并支持不同窗口形式(小窗、分屏、全屏)之间快速切换。
小窗入口包括但不限于:近期任务卡片“小窗”选项,应用内滑、悬浮通知下拉等。用户可以通过 设置-快捷与辅助-多任务 路径进入多窗口功能设置页,了解相关功能介绍。
(注:不同机型、不同版本表现可能有所差异)。

2、小窗应用适配关键点

应用适配全局小窗时,因一些容易被忽略的适配点,导致应用进入小窗模式后出现兼容性问题。为此,我们整理了全局小窗应用适配的五大关键点,帮助开发者快速适配。

2.1 声明支持多窗口模式
应用适配全局小窗需要先声明支持安卓原生多窗口,和多窗口适配策略相同,都需在 [activity] 或 [application] 节点中添加 android:resizeableActivity 属性。

参考代码:

<application
    android:name=".MyActivity"
    android:resizeableActivity="true" />

安卓官方多窗口适配参考链接:https://developer.android.com/guide/topics/ui/multi-window.html

2.2 正确处理Configuration变化
在应用横竖屏旋转和窗口大小变化时,如需自行处理多窗口配置,请设置android:configChanges属性,之后Activity和 Fragment将收到 onConfigurationChanged()方法回调,而不是先销毁再重建。
在管理视图更新、重新加载资源等工作时,注意不要沿用之前的Config信息,而需重新获取最新的资源信息。参考代码:

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize | smallestScreenSize 
		| screenLayout | orientation" />

2.3 正确启动Activity的task
应用需给Activity设置独立的android:taskAffinity属性,以防因继承rootActivity的多窗口属性导致无法启动到小窗模式。
因为task中的Activity会继承rootActivity的多窗口属性。如果启动该task的rootActivity是unresizable的,则即使要启动的Activity是resizable的也无法启动到小窗模式。
参考代码:

<activity
  android:name=".MyActivity"
  android:taskAffinity="com.test.example" />

2.4 正确使用Context
应用在适配小窗模式时,应使用Activity的Context加载合适的资源和计算相对位置。
在应用进程中,存在Application和Activity两类Context,其中Application Context对应的是屏幕资源信息,而Activity Context对应的是窗口的资源信息。
如果应用在小窗模式下使用的是 Application Context处理UI 相关的操作,会导致加载的资源因无法感知到小窗而显示异常。
Activity如何获取特定窗口类型下的窗口尺寸,参考代码:
java:

int screenWidthDp = getResources().getConfiguration().screenWidthDp;
int screenHeightDp = getResources().getConfiguration().screenHeightDp;

kotlin:

val screenWidthDp: Int = resources.configuration.screenWidthDp
val screenHeightDp: Int = resources.configuration.screenHeightDp

2.5 正确处理小窗下的沉浸式
小窗模式下,应用顶部有个功能bar,应用在沉浸式适配时需为此功能bar预留一定空间。因此应用在布局时,需要监听安卓原生的WindowInsetsListener接口回调,针对captionBarInsets变化来处理view高度,注意不要使用固定高度!!!

参考代码:
java:

getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
    //应用在回调中计算view高度
    return insets;
});

kotlin:

window.decorView.setOnApplyWindowInsetsListener { v: View?, insets: WindowInsets ->
    //应用在回调中计算view高度
    insets
}

2.6 其他界面布局建议
• 布局参数尽量使用相对的布局参数,不要使用固定尺寸
• 避免根据屏幕大小,输入法高度等计算view的布局参数,如设置popwindow、dialog等子窗口的位置时,避免使用整个屏幕的相对位置
• 避免对DecorView,content等根布局进行定制,比如设置DecorView的背景、在DecorView添加子布局等
• 注意生命周期处理,如小窗模式下出现页面点击、拖动无响应问题,可能跟布局或生命周期有关
• 避免根据物理屏幕方向设置当前功能或布局

vivo分屏适配指南

1. 适配背景

vivo分屏在原生分屏的基础上做了定制化处理,比如增加分屏方式(消息\三指\组合)、分屏小桌面列表、输入法边界定制、加密界面定制等

2. 适配指导

2.1 判断分屏的方式 

Activity判断:

isInMultiWindowMode方法,判断mIsInMultiWindowMode变量,该变量在oncreate和模式变化时赋值

onMultiWindowModeChanged方法,在模式发生变化时回调

Services判断:

Q以及之前可以通过

1. WindowManagerGlobal.getWindowManagerService().getDockedStackSide()  !=  WindowManager.DOCKED_INVALID

2. getStackInfo,判断WINDOWING_MODE_SPLIT_SCREEN_PRIMARY(分屏)的stack是否存在,存在处于分屏

R以及以后通过

1. isSplitScreenModeActivated方法判断

2. Settings.system. in_multi_window,  0非分屏,1进入分屏

2.2 配置支持分屏

应用AndroidManifest.xml中可以针对app或activity进行设置。

<application
        android:resizeableActivity="true">

        <activity
                    android:resizeableActivity="true" />
</application>

当应用targetSdkVersion >=24时,android系统默认设置android:resizeableActivity=”true”,不需要应用声明即可支持应用分屏。当应用targetSdkVersion < 24时,需要应用针对application或activity设置android:resizeableActivity=”true”。

应用设置application android:resizeableActivity=”true”时,会针对app的所有activity生效,因此如果应用只需要声明单独的activity时,可以只针对单个activity进行设置,系统侧建议针对application设置android:resizeableActivity=”true”,避免应用部分页面在分屏下的异常。

2.3 获取Activity实际显示的窗口大小和位置

使用:context.getResources().getDisplayMetrics()

不推荐使用:context.getWindowManager().getDefaultDisplay().getMetrics(outMetrics)

上述接口中,context为Activity对应的上下文句柄,每个Activity应该严格使用自己的context来进行布局,而不是使用application的context。

2.4 获取Activity的窗口布局方向

获取Activity窗口方向的的方法为:

context.getResources().getConfiguration().orientation

注:不要使用width /height的方法来判Activity为横竖屏布局,因为在多窗口状态下,支持应用的拖动,会改变宽高

获取设备的方向context.getWindowManager().getDefaultDisplay().getRotation()

2.5 Activity大小切换时不重启适配

应用在Activity窗口大小切换时不重启适配,在android:configChanges属性增加screenSize|screenLayout| orientation|smallestScreenSize,并在Activity的onConfigurationChanged回调中更新宽高刷新子布局。

应用复写onConfigurationChanged()方法,通过该方法的Configuration参数获得窗口高度等信息,并对界面布局做相应调整,如切换布局、调整控件位置和间距等。

2.6 状态栏位置

当处于分屏下屏,和小窗模式时,应用没有状态栏,此时不应该留出状态栏高度,需要从顶部开始布局。

可以通过configuration中windowingmode判断当前处于的模式,WINDOWING_MODE_FREEFORM和WINDOWING_MODE_SPLIT_SCREEN_SECONDARY不需要空出状态栏

vivo 折叠屏三方应用开发适配指南

一、vivo 多窗口(分屏小窗)功能适配指南

1.1 适配背景

随着大屏手机的普及,用户对于多窗口功能的使用越来越频繁,尽管google 已经推出了多窗口功能,但是很多应用还没有适配多窗口功能,因此,我们输出《vivo 多窗口(分屏小窗)功能适配指南》提供给应用侧进行适配,让三方应用开发者能够更清楚多窗口功能的适配开发流程。

1.2 适配指导

1.2.1 配置支持多窗口功能

应用AndroidManifest.xml 中可以针对 app 或 activity 进行设置。

代码实例:

<application
  android:resizeableActivity="true">
  <activity
      android:resizeableActivity="true" />
</application>

当应用 targetSdkVersion >=24 时,android 系统默认设置 android:resizeableActivity=”true”,不需要应用声明即可支持应用使用多窗口功能。当应用 targetSdkVersion < 24 时,需要应用针对 application 或 activity 设置 android:resizeableActivity=”true”。

1.2.2 获取Activity 实际显示的窗口大小和位置

Android11 及以上(API 级别为30 及以上)推荐使用:

WindowManager#getCurrentWindowMetrics() : 针对系统的当前窗口状态, 返回WindowMetrics 对象

WindowManager#getMaximumWindowMetrics():针对系统可能的最大窗口状态,返回 WindowMetrics

代码实例:

获取当前activity 的窗口指标

WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();

Android10(API 级别为29)推荐使用:

context.getResources().getDisplayMetrics()

不推荐使用:

context.getWindowManager().getDefaultDisplay().getMetrics(outMetrics)

上述接口中,context 为 Activity 对应的上下文句柄,每个 Activity 应该严格使用自己的context 来进行布局,而不是使用 application 的 context。

备注:

Display 方法 getSize() 和 getMetrics() 在 API 级别 30 中已被弃用,取而代之的是新的 WindowManager# getCurrentWindowMetrics() 方法。

Android 12(API 级别 31)弃用了 Display 方法 getRealSize() 和 getRealMetrics(),并更新了它们的行为以使其更接近 getMaximumWindowMetrics() 的行为。

getSize():获取context 显示的尺寸,不包括状态栏等系统显示区域的尺寸

getRealSize():获取手机屏幕的真实尺寸,包括状态栏等系统显示区域的尺寸

getMetrics():获取context 显示区域的屏幕元素,例如屏幕尺寸、屏幕密度等屏幕元素信息,不包括状态栏等系统显示区域的屏幕元素信息

getRealMetrics():获取context 显示区域的屏幕元素信息,例如屏幕尺寸、屏幕密度等屏幕元素信息,包括状态栏等系统显示区域的屏幕元素信息

Android10 上,我们推荐使用getSize 和getMetrics 来获取显示区域的大小。在多窗口(分屏小窗)模式下,getSize 和getMetrics 获取出来的是context 显示区域的大小,getRealSize和getRealMetrics 获取出来的是手机屏幕的真实大小,getSize 和getMetrics 获取出来的尺寸值要小于getRealSize 和getRealMetrics 的尺寸值。

1.2.3 获取Activity 的窗口布局方向

获取Activity 窗口方向的的方法为:

context.getResources().getConfiguration().orientation

注:不要使用width /height 的方法来判Activity 为横竖屏布局,因为在多窗状态下,支持应用的拖动,会改变宽高。

获取设备方向的方法如下:

context.getWindowManager().getDefaultDisplay().getRotation()。

1.2.4 Activity 大小切换时不重启适配

1. 应用在Activity 窗口大小切换时不重启适配,在android:configChanges 属性增加 screenSize|screenLayout| orientation|smallestScreenSize

代码示例:

<activity
 android:name=".MyActivity"
 android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation" />

2. 在Activity 的onConfigurationChanged 回调中更新宽高刷新子布局。

代码示例:

@Override
public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(newConfig);
   ……
}

应用复写 onConfigurationChanged() 方法,通过该方法的 Configuration 参数获得窗口高度等信息,并对界面布局做相应调整,如切换布局、调整控件位置和间距等。

1.2.5 状态栏位置

当处于分屏下屏,和小窗模式时,应用没有状态栏,此时不应该留出状态栏高度,需要从顶部开始布局。

可以通过configuration 中windowingmode 判断当前处于的模式,WINDOWING_MODE_FREEFORM 和WINDOWING_MODE_SPLIT_SCREEN_SECONDARY 不需要空出状态栏。

1.2.6 分屏下ActivityRecord 动画问题

很多应用会重写

<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>

分屏下containingWidth/containingHeight 为分屏窗口的尺寸, width/height 为displaycontent 尺寸(全屏)

initialize(containingWidth, containingHeight, width, height);

对于动画类型有 ABSOLUTE/RELATIVE_TO_SELF/RELATIVE_TO_PARENT

如果应用配置的xml 中带了p,使用的displaycontent 尺寸,会导致分屏下位移动画问题。没有p 为 RELATIVE_TO_SELF 类型

1.2.7 正确处理分屏小窗的沉浸式

分屏或小窗模式下,应用顶部有个功能bar,应用在沉浸式适配时需为此功能bar 预留一定空间。因此应用在布局时,需要监听安卓原生的WindowInsetsListener 接口回调,针对captionBarInsets 变化来处理view 高度,注意不要使用固定高度!!!

参考代码:

java:

getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
  //应用在回调中计算view 高度
  return insets;
});

kotlin:

window.decorView.setOnApplyWindowInsetsListener { v: View?, insets: WindowInsets ->
  //应用在回调中计算view 高度
  insets
}

1.2.8 其他布局建议

•  布局参数尽量使用相对的布局参数,不要使用固定尺寸

•  避免根据屏幕大小,输入法高度等计算view 的布局参数,如设置popwindow、dialog 等子窗口的位置时,避免使用整个屏幕的相对位置

•  避免对DecorView,content 等根布局进行定制,比如设置DecorView 的背景、在DecorView 添加子布局等

•  注意生命周期处理,如小窗模式下出现页面点击、拖动无响应问题,可能跟布局或生命周期有关

•  避免根据物理屏幕方向设置当前功能或布局

二、折叠屏前后屏切换适配指南

2.1 屏幕兼容性

2.1.1 应用布局优化

折叠屏有主屏(展开态)和副屏(折叠态)两种形态,以X Fold 为例,主屏和副屏的分辨率分别是1916×2160 和1080×2520,densityDpi 是480,应用程序需要针对不同的屏幕尺寸进行布局适配和优化。

2.1.1.1 屏幕兼容显示

在对不同尺寸屏幕适配过程中,为了确保在折叠屏各个屏幕形态下获取最佳的布局显示效果,例如页面无明显的拉伸放大、布局错位、重叠和显示更多更清晰的内容,建议您对布局进行优化。应用界面正确、美观的布局和显示,包含如下:

•  确保您的布局能够根据屏幕适当地调整大小

•  根据屏幕配置提供合适的 UI 布局

•  确保对正确的屏幕应用正确的布局

•  提供可正常缩放的位图

    详细适配方法请参考Android 开发者适配指导:https://developer.android.com/training/multiscreen/screensizes?hl=zh-cn

    基于折叠屏的特性,用户经常会在主屏(大屏)玩游戏或全屏看视频,以X Fold 为例,主屏有前置摄像头,因此应用程序页面需要针对打孔屏做适配,避免页面显示时摄像头区域出现白边或黑边,影响显示效果。参考vivo 手机全屏适配开发指导:https://developers.vivo.com/doc/d/52a902cf33fa72efeeeaf5197d60efa5

2.1.1.2 支持横竖屏切换

以X Fold 为例,主屏(展开态)屏幕尺寸接近4:3,桌面应用支持横竖屏显示,因此用户会在任何形态下打开应用。因此我们建议应用程序支持横竖屏切换,提高用户体验。横竖屏切换适配建议如下:

1、 横竖屏切换涉及到方向、尺寸和键盘隐藏/ 显示, 因此需要在Activity 配置

android:configChanges=”orientation|screenSize|screenLayout|smallestScreenSize|keyboard|keyboardHidden”

2、 在onConfigurationChanged 函数收到config 变化后,动态加载横竖屏布局以及完成其他任务

public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(newConfig);
   if(newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
      //switch to port and load layout
      setContentView(R.layout.activity_main);
      //TODO something
   }else{
      //switch to land and load layout
      setContentView(R.layout.activity_main_land);
      //TODO something
   }
}

2.1.2 应用resizeable 能力支持

折叠屏状态切换时,涉及到分辨率和像素密度的动态变化。若应用程序界面不支持resizeable 能力,在切屏时会存在应用程序界面未全屏显示的问题,如下图所示:

展开态

折叠态

因此我们期望应用程序界面在切屏后可以全屏显示,应用程序支持resiszeable 需要在 AndroidManifest.xml 针对Application 或Activity 设置android:resizeableActivity。

<application
  android:resizeableActivity="true"> ->对应用内所有activity 生效
  <activity
      android:resizeableActivity="true" /> ->仅对此activity 生效
</application>

开发者需要根据应用面向的API Level (targetSdkVersion)进行支持resizeable 能力的申明。

•  如果应用程序面向API Level 24 以上(targetSdkVersion>=24),系统将默认应用支持resizeable 能力。

•  如果应用程序面向API Level 24 以下(targetSdkVersion< 24),需要应用在manifest 中显式的声明android:resizeableActivity=true, 才可以支持resizeable 能力。

    备注:虽然安卓提供了申请受限屏幕能力,但强烈建议您为应用设计resizeable 能力,因为一旦您声明了受限屏幕比例(最大或最小)这意味着,当您的app 运行在一个屏幕比例超出了您声明的范围,您的应用程序在屏幕上将出现黑边等现象。

    受限屏幕支持开发者适配指导:https://developer.android.com/guide/practices/screens-distribution?hl=zh-cn

2.2 应用连续性

为了保证应用程序在折叠屏展开/折叠过程无缝切换,开发者需要做应用连续性的设计,以确保应用程序任务不中断。以X Flod 为例,最佳的体验为,应用在展开切换过程中,不发生应用的重启,且切换之前的任务和应用相关状态得以保存和延续。

折叠屏切屏时会触发对smallestscreensize、screensize 和screenlayout 的配置更改。每当发生配置更改时,默认情况下会销毁并重新创建整个activity。开发者可以通过注册监听系统configchanges 消息,不重启应用的情况下处理配置更改,应用程序需要向manifest 中添加android:configchanges 属性,其中至少包含以下值:

android: configChanges = “screenSize|smallestScreenSize|screenLayout” 应用程序需要复

写 onConfigurationChanged() 方法,通过该方法的Configuration 参数获得屏幕的分辨率等信息,就可以针对不同比例屏幕下的应用界面布局做相应调整,如切换布局、调整控件位置和间距等。

public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(newConfig);
if(newConfig.screenWidthDp > xxx) //判定屏幕尺寸
  //load layout
    setContentView(R.layout.activity_main);
    ...
}

如果您的应用必须进行重新走生命周期来以响应屏幕切换,需要进行状态的保存和恢复。

您可以通过OnSaveInstanceState()和ViewModel 对象来进行之前状态保存和后续的恢复。即,在销毁activity 之前,通过onSaveInstancesState()存储状态, 在onCreate() or onRestoreInstanceState()进行状态的恢复。

Note:不要在OnDestroy()中调用finish()或其他自行终止进程。这将导致应用程序在设备折叠或展开时关闭、闪退等问题。

其他适配事项可以参考Android 开发者适配指导(例如链接中提到的 保存界面状态和支持配置变更 部分):

https://developer.android.com/guide/topics/ui/foldables?hl=zhcn#%E5%BA%94%E7%94%A8%E8%BF%9E%E7%BB%AD%E6%80%A7

2.3.判定折叠屏设备方法

根据应用程序判定折叠屏设备的需求,提供了两种判定折叠屏设备的方法。

2.3.1 根据model 机型判定

此方法适用于应用程序已经针对部分折叠屏设备适配且支持新折叠屏设备在线配置生效场景,否则强烈建议开发者通过方法2 判定折叠屏设备。

以X Fold 为例,可以获取如下属性获取model 名

λ adb shell getprop ro.product.model

V2178A

2.3.2 通过接口判定

建议开发者使用此方法判定设备类型,接口说明如下:

类 :android.util.FtDeviceInfo

public static String getDeviceType

返回目前是三种类型:phone、tablet 和foldable

可以通过反射的方式获取设备类型,返回值foldable 表示折叠屏设备。

反射代码示例:

private static boolean isVivoFoldableDevice(){
     try{
       Class<?> c= Class.forName("android.util.FtDeviceInfo");
       Method m = c.getMethod("getDeviceType");
       Object dType = m.invoke(c);
       Log.d("fold","getDeviceType="+dType);
       return "foldable".equals(dType);
     }catch(Exception e){
       e.printStackTrace();
     }
     return false;
}

2.4.调试和验证

2.4.1 通过命令模拟调试

开发者可以在非折叠屏手机上面通过命令修改手机的屏幕分辨率和densityDpi 来进行模拟调试,如下以X Fold 屏幕配置为例模拟切屏(主屏->展开态,副屏->折叠态):

副屏切主屏模拟方法:

(1)预先在手机设置如下屏幕配置:

  adb shell wm size 1080×2520

  adb shell wm density 480

(2)adb shell wm size 1916×2160

主屏切副屏模拟方法:

(1)预先在手机设置如下屏幕配置:

  adb shell wm size 1916×2160

  adb shell wm density 480

(2)adb shell wm size 1080×2520

配置恢复方法:

adb shell wm size reset

adb shell wm density reset

2.4.2 通过模拟器调试

2.4.2.1 Android 折叠屏模拟器

除了通过手机动态切换分辨率的方式来进行调试外,也可以通过模拟器的方式进行调试和验证,Android Studio 模拟器Phone 分类支持8 英寸和7.3 英寸的折叠屏调试,但是无法克隆,即无法修改模拟器的物理尺寸和分辨率,且模拟器System image 如果是x86 的系统,只支持32 位应用的安装和运行,如果是纯64 位的应用,模拟器需要选择arm64-v8a,否则无法安装和运行应用。

Note:

1. Android Studio Foldable 模拟器无法修改物理尺寸、分辨率和densityDpi,因此在适配时,无法完全模拟vivo 折叠屏手机,在app 或activity resizeableActivity = true 时,为了验证切屏是否有黑边可以在Android 原生模拟器查看效果。

展开态
折叠态

2. 64 位模拟器需要PC 主机支持,部分PC 无法正常启动64 位模拟器。

2.4.2.2 折叠屏展开态模拟器

Android 折叠屏模拟器无法修改物理尺寸、分辨率和densityDpi,若应用在进行《2.2 不同分辨率布局适配》时,需要100%模拟折叠屏展开态的屏幕进行调试时,可以通过克隆Tablet分类的Nexus 10,然后修改vivo 折叠屏手机对应的物理尺寸、分辨率和DPI 进行调试和验证。

Note:

1. 应用UI 兼容性适配对物理尺寸有强关联时,请务必修改Screen size 为8.03,分辨率是展开态分辨率

2. 64 位模拟器是否可以运行需要PC 主机支持

3. 若手机模拟densityDpi 和分辨率调试无问题后,无法在模拟器运行,可以发包给vivo 接口人,在vivo 折叠屏真机运行点检。

4. 模拟器无法修改densityDpi,需要启动模拟器后,通过adb shell 命令设置。

此时打开终端,可以看到模拟器设备已经挂载和连接,可以进行adb 操作。

λ adb devices

List of devices attached

emulator-5554 device

模拟器无法直接修改densityDpi,需要启动模拟器后单独设置。

adb shell wm density 480

2.4.3 远程真机调试

目前vivo 已经支持X Fold 远程真机调试,开发者可以访问如下链接使用远程真机

https://vcl.vivo.com.cn/#/machine/picking

远程真机主屏效果图

远程真机副屏效果图

2.4.4 测试用例建议

2.4.4.1 用例1

应用在展开态下页面显示正常

测试步骤:

(1)在屏幕展开的状态下,打开应用,查看应用各个页面显示效果;

预期结果:

(1)应用的所有页面可以全屏显示,页面没有发生截断、拉伸变形、放大模糊,按钮缺失等问题;

2.4.4.2 用例2

应用在展开态下核心页面功能正常

测试步骤:

(1)在屏幕展开的状态下,打开应用;

(2)遍历应用核心页面的控件按钮,所有功能按钮可用,无失效/crash/anr 等问题;

预期结果:

(1)应用在折叠屏展开后,核心页面功能可用

2.4.4.3 用例3

应用在折叠和展开状态切换时业务不中断,应用页面显示和控件点击正常。

测试步骤:

(1)在展开态下,打开应用的测试页面;

(2)在应用的测试页面切换到折叠态,观察页面显示;

(3)点击测试页面的所有控件和按钮;

(4)在折叠态下,打开应用的测试页面;

(5)在应用的测试页面切换到展开态,观察页面显示;

(6)点击测试页面的所有控件和按钮。

预期结果:

(1)应用页面在状态切换过程中,不要出现页面重启、闪退;页面显示正常,不要出

现页面截断、拉伸变形、放大模糊,按钮缺失等问题;

(2)测试页面按钮和控件点击都能正常响应;

(3)应用页面在状态切换过程中,不要出现页面重启、闪退;页面显示正常,不要出

现页面截断、拉伸变形、放大模糊,按钮缺失等问题;

(4)测试页面按钮和控件点击都能正常响应。

三、vivo 多窗模式适配指南

3.1 适配规则

窗口在左右两边拆分显示以Activity 为基本单位,如果要实现拆分,应用窗口需要用Activity 实现和启动,子布局或者非Activity 实现的窗口,无法拆分。以下提供Pad 设备上在横屏时应用不同界面分屏显示的适配方法和规则

3.1.1 AndroidManifest 增加meta-data

在app 的AndroidManifest.xml 文件中 <application>标签内新增

<meta-data android:name=”VivoMultiWindow” android:value=”true” />

3.1.2 Assert 目录新增vivo_multiwindow.json 配置文件

“vivo_multiwindow.json”模板

在 assert 目录下新建配置文件 “vivo_multiwindow.json”,模板示例如下:

{         “funtouchPlugVersion”: “1.1”,       “package”:   “com.vivo.test”,       “elements”:   [                 {                        “fun”: {                                 “name”: “multi-landscape”,                                 “enable”: “true”                        },                        “config”: {                                 “mode”: 1,                                 “action”: [                                         {                                                  “pages”: “com.vivo.test.MainActivity”,                                                  “attachedPage”: “com.vivo.test.primaryActivity1”                                         },                                         {                                                  “from”: “com.vivo.test.FromActivity1”,                                                  “to”: “com.vivo.test.ToActivity”                                         },                                         {                                                “from”:   “com.vivo.test.FromActivity2”,                                                  “to”: “*”                                         }                               ],                               “Activities”:   {                                         “fullscreenActivities”: [                                                  “com.vivo.test.fullScreenActivity1”,                                                  “com.vivo.test.fullScreenActivity2”                                         ],                                         “transitActivities”: [                                                  “com.vivo.test.transitionActivity1”,                                                  “com.vivo.test.transitionActivity2”,                                                  “com.vivo.test.transitionActivity3”                                         ],                               },                               “EX”:   {                                         “draggable”:   “true”,                                         “statusBarVisible”:   “true”,                                         “videoAutoFullscreen”:   “true”,                                         “isRelaunchForResizing”:   “false”,                                         “supportDoubleResume”:   “true”,                                         “windowsGravity”: [                                                {                                                         “deviceType”: “FOLD”,                                                         “gravity”: “1|2”                                                },                                                {                                                         “deviceType”: “PAD”,                                                         “gravity”: “900|1654”                                                }                               ],                               “splitBarColor”:   “0xffe5e5e5”                        }                  }           }      ]}

“vivo_multiwindow.json”字段描述

“vivo_multiwindow.json”具体字段描述如下:

参数描述
funtouchPlugVersion1.0vivo 多窗口功能版本,目前固定1.0
package应用包名
fun.namemultilandscapevivo 多窗口功能名称,固定为multi-landscape
fun.enablefalse/是否启用该配置
false 关闭
true 启用
config.mode0/1默认模式
0 购物模式
1 自定义模式
config.action应用冷启动时默认打开的双界面配置
config.action.pages默认双屏主页面列表
注:可以指定多个,分号隔开,应用冷起动启动该页面,自动在副页面位置启动attachedPage页面
config.action.attachedPage默认双屏副页面
config.action.from(自定义模式生效)触发多窗口的源activity
config.action.to(自定义模式生效)触发多窗口的目标activity
“*”表示任意activity
注:当从源Activity启动目标Activity,自动在主副位置打开对应Activity
config.Activities.fullscreenActivities0/1是否需要全屏启动
0 非全屏
1 全屏
config.Activities.transitActivities过渡页面列表
注:无固定窗口位置,跟随启动时上一级页面窗口位置
config.EX特殊属性配置
config.EX.draggable0/1是否支持窗口拖动
0 不支持
1 支持
config.EX.statusBarVisible0/1是否支持状态栏可见
0 不支持
1 支持
config.EX.videoAutoFullscreen0/1是否支持默认视频全屏播放
0 不支持
1 支持
config.EX.isRelaunchForResizing0/1是否支持重启
0 不支持
1 支持
config.EX.windowsGravity窗口比例
config.EX.windowsGravity.deviceTypeFOLD/PAD设备类型
FOLD 折叠屏
PAD 平板
config.EX.windowsGravity.gravity1|2 /
900|1654
窗口比例
FOLD 默认1|2
PAD 默认900|1654
config.EX.supportDoubleResume0/1是否支持两个界面同时resume
config.EX.splitBarColor分隔条的颜色

3.2 适配建议

3.2.1 状态判断

获取Activity 是否运行在模式下:

String config = context.getResources().getConfiguration().toString();

boolean isInMagicWindow = config.contains(“multi-landscape”);

context 为Activity 的context

配置了Fullscreen 的页面,显示为全屏,但也运行在模式下

3.2.2 获取Activity 显示大小

推荐使用:context.getResources().getDisplayMetrics()

不推荐使用:context.getWindowManager().getDefaultDisplay().getMetrics(outMetrics)

context 为Activity 对应的上下文句柄,每个Activity 应该严格使用自己的context 来进行布局,而不是使用application 的context。

3.2.3 获取Activity 窗口布局方向

获取Activity 窗口方向的方法为:context.getResources().getConfiguration().orientation

当Activity 处于横屏应用显示状态下时,获取的orientation 统一为竖屏;如果Activity是在状态下全屏显示,其orientation 为值为横屏。

获取设备的方向context.getWindowManager().getDefaultDisplay().getRotation()。

3.2.4 指定Activity 全屏显示

横屏应用显示状态下,Activity 希望以全屏展示,有三种方法:

方法一:动态全屏显示,Activity 首先以横屏应用显示非全屏显示,调用Activity 类的如下接口申请横屏方向可进入全屏显示状态:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

在此状态下,调用Activity 类申请竖屏方向即可退出全屏状态:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)

此场景广泛应用于视频全屏播放场景。

方法二:在配置文件fullscreenActivities 中添加想要全屏的Activity,即可实现Activity默认以全屏启动,此方法中,Activity 会一直以全屏状态显示

方法三:在“AndroidManifest.xml”文件中将Activity 的方向配置为横屏,此方法中,Activity 会一直以全屏状态显示

android:screenOrientation = “landscape”

或android:screenOrientation = “sensorLandscape”

3.2.5 开发建议

•  应用主界面Activity 的启动以singleTask 的模式来启动,保证其在栈内的唯一性。

•  应用内不要存在两个及以上组件名不一样的主界面Activity,例如某个应用在登录前的主界面Activity 组件名与登录后的Activity 组件名不同,会导致新的主界面Activity显示在右半边

•  尽量避免或减少过渡Activity 的使用,尽量避免或者减少使用过渡Activity 来实现Activity 的启动,如果一定要使用,建议使用ActivityA->ActivityB->ActivityC 的启动方式,而不是(ActivityA->ActivityB) + (ActivityA->ActivityC)的方式(示例中,ActivityB 为过渡Activity ) 。过渡Activity 的数量不能超过1 个, 例如ActivityA->ActivityB->ActivityC->ActivityD,其中ActivityB 和ActivityC 是过渡窗口,建议从ActivityA 直接启动ActivityC。

•  Activity 大小切换时不重启适配,建议应用在Activity 窗口大小切换时不重启适配,在android:configChanges 属性增加screenSize|screenLayout|orientation|

smallestScreenSize,并在Activity 的onConfigurationChanged 回调中更新宽高刷新子布局。

•  避免Activity 子布局的缺省重用,由于左右Activity 同时显示,左右显示的两个Activity中不能同时存在单实例的公共布局模块

•  避免左右两个Activity 共用一个播放器,左右两个Activity 同时显示,建议两边使用的播放器资源相互独立,互不影响。

•  建议Camera 相关的Activity 界面配置为全屏显示

3.3 启动返回显示逻辑

基于目前横屏应用显示模式,在模式中启动或者回退链条展示。

3.4 三方适配多窗模式过程中需要注意:

应用更新json 文件后安装不生效,可以通过下面两种方式更新:

1. 修改完之后,升级应用版本号,重新安装应用

2. 把数据库都删除,重新创建,需要root 权限删除数据库之后重启。

adb vivoroot

adb shell rm -rf data/data/com.vivo.smartmultiwindow/*

adb shell rm -rf data/user_de/0/com.vivo.smartmultiwindow/*

建议使用第一种。

vivo折叠屏适配指南2

跨应用拖拽

跨应用拖拽可以让用户将一个应用中的图像、文档或文件拖拽到另一个应用中。

通过分屏和悬浮小窗实现在大屏的跨应用拖拽,减少用户在应用之间来回切换,更高效地进行多任务处理,提高生产力。

关于跨应用拖拽的适配:https://developer.android.com/guide/topics/ui/drag-drop

三、典型场景

3.1 影音娱乐

影音娱乐类场景以大量影音内容资源带来的沉浸式体验为主。

3.1.1 视频资源平台

首页推荐

视频列表页

3.1.2 短视频/直播互动页

3.1.3 音乐播放界面

3.1.4 视频播放界面(悬停)

3.2 资讯阅读

资讯阅读类场景以信息的聚合为主,需利用屏幕优势,确保用户对关键信息浏览、理解的完整和高效。

3.2.1 首页布局:左右图文结构

3.2.2 首页布局:上下图文结构

3.2.3 资讯详情页

3.3 生活服务

生活服务类场景广泛地包含了购物、饮食、出行、学习等用户日常生活的各个方面。

3.3.1 首页列表

3.3.2 详情页面

3.4 通讯社交

社交通讯类场景主要包括:文字交流为主的IM对话、图像视频通话、社交动态等场景。

3.4.1 文字交流为主(IM对话)

3.4.2 图像·视频通话

3.4.3 社交动态

首页结构:推荐

详情页

可根据实际情况,自由选择应用多窗的两种交互规则。请参考基础适配原则-交互方式-多窗口交互(2.7)

3.5 效率办公

效率办公类场景以高效的体验,辅助和提升工作者的办公效率为主。

3.6 H5页面

H5页面以其便利的特性,广泛应用于小程序和网页版应用。

3.7 金融理财

用户在金融理财类场景中,需确保大屏信息呈现所带来的高效与舒适。

同时,需保障用户办理金融业务过程中的易用性。

3.7.1 首页布局

3.7.2 股票·走势详情页

3.8 游戏

根据不同的游戏类型和场景,优化大屏布局,在呈现与交互层面给用户带来愉悦的体验。

同时,考虑到用户在玩游戏时长时间握持设备,在设计展开态布局时,应根据不同的交互区做适配优化。

请参考交互方式(2.5)-合适的交互区

四、测试应用

4.1 设备尺寸

可在 Android Studio 中基于以下设备规格信息进行测试。

屏幕类型对角线长度(英寸)比例分辨率(像素)
主屏(展开态)8.034:3.551916*2160
副屏(折叠态)6.5321:9 1080*2520

vivo折叠屏适配指南1

一、概述

1.1 折叠屏简介

折叠屏手机作为一种具有特殊形态的设备,具备折叠使用的外屏(副屏),和展开使用的内屏(主屏),通常展开使用的内屏尺寸相对较大。

本文主要提供针对折叠屏大屏的适配建议,帮助设计师及开发者能够更简单、快速地将应用适配至折叠屏设备,以确保用户在不同设备中保持应用的一致体验所带来的愉悦感。

1.2 折叠屏形态

    1. 折叠态(副屏):外屏尺寸接近普通直屏手机,其设计规范可与直屏手机基本保持一致。

    2. 展开态(主屏):内屏较外屏有更大的屏幕宽度,需充分利用大屏优势,在信息呈现和交互方式上利用合适的布局方式对应用进行优化调整。

    3. 悬停态:折叠屏设备处于完全展开和折叠的中间状态,可平稳放置。可悬停角度:5°-160°

1.3 折叠屏特性

1.3.1 大屏内容呈现

折叠屏手机的展开态具有以下三个优势:

    1. 展示更多内容:提升信息呈现丰富度与交互效率。

    2. 提升沉浸感:在游戏、电影、视频通话、图片浏览等应用和场景下减少干扰,提升专注度。

    3. 多窗口、多任务:通过展示更多窗口和内容,实现多任务的并行,以丰富体验场景。

1.3.2 主副屏的体验连续

体验连续是指:从一种窗口大小转换为另一种窗口大小时带来无缝的用户体验。无论用户当前置身于什么体验,都应继续进行而不中断,防止用户感知无法接续。

通常情况下,从折叠态切换至展开态时,应用默认在主屏显示运行,并维持在副屏时的应用与任务状态。

同时,用户可在 “设置-显示与亮度-合上屏幕后熄屏” 中选择在展开态切换至折叠态后,是否自动熄屏:

    1. 开启的情况下,折叠设备后,副屏自动熄屏。

    2. 关闭的情况下,折叠设备后,副屏不熄屏并维持在主屏时的应用与任务状态。

二、基础适配原则

2.1 概述

为了避免应用在普通直屏手机移植到折叠屏手机时,缺少针对大屏的优化,导致布局混乱、信息呈现不完整等问题,大幅降低用户体验,建议基于以下三个核心指导建议优化设计:

    1. 适合展开态的界面元素为了发挥折叠屏展开态的大屏优势,在设计时需要基于屏幕特性和业务场景,优化界面布局结构,以提高用户的交互效率与愉悦感。原则上,更大的屏幕应当呈现更多的内容;在页面适配上,应当优先保证所有界面元素显示为适宜的大小,不应将界面单纯的整体放大,导致单屏信息呈现的减少,影响界面的使用效率。

    2. 灵活的响应式布局通过响应式布局建构页面,能够在可用空间发生变化时及时、灵活地进行调整优化。本文提供了多种布局建议,可根据业务场景和具体需求,使用其中一种或多种布局进行最优组合。关于布局的具体介绍,请参考界面布局(2.6)。

    3. 高效利用多窗口交互通过在更大的屏幕上同时展示多个窗口,用户可以高效、直观地处理多个任务,提升使用体验的价值。建议应用为用户在折叠屏展开态中提供更加丰富高效的使用方式,让用户体验得到不同维度的增值。

具体来说,基础适配原则从“信息呈现”与“交互方式”两个维度提供指导建议

2.2 信息呈现

界面中的信息呈现包括图片、视频、卡片、按钮、字体、控件等通用基础体验元素的展示。

屏幕展开前后,通用基础体验元素需保持一致。如:元素不发生变形、裁剪、信息显示不全或者模糊等情况,避免信息呈现的不一致。

2.3 基础元素适配

需将所有界面元素显示为适宜的大小。不应过大或过小,影响显示效率。

不应从折叠态到展开态直接等比放大文字图标、图片视频等要素,图片与文章的比例与在直屏手机的界面设计出入过大,导致用户在大屏界面中与在直屏手机中的感知不符合预期。

2.4 弹出框适配

建议应用在展开态下的弹出框尺寸与折叠态下弹出框尺寸保持一致,如因特殊需求,需要进行放大,则不应超过原尺寸的1.3倍

2.5 交互方式

2.5.1 合适的交互区

在展开态时,由于用户双手握持设备的情况较为常见,手指会难以顺利在屏幕所有区域进行交互。为了确保户的交互体验的高效与愉悦,在设计展开态布局时,应考虑到以下三个交互区域:

        ① 用户易于触达的区域。操作频率最高的控件元素建议放在此区域。

        ② 用户可以触达的区域。但有时候可能会造成一定不便,有一定操作频率的控件元素建议放在此区域。

        ③ 用户较难触达的区域。除特殊情况,不建议将需要交互的控件元素放在此区域。

2.3.2 折叠屏手机形态

折叠屏手机形态分为折叠态、展开态与悬停态:

    1. 折叠态:折叠屏手机折叠后的形态,折叠后屏幕尺寸变小。

    2. 展开态:折叠屏手机展开后的形态,展开后屏幕尺寸变大。

    3. 悬停态:折叠屏设备处于完全展开和折叠的中间状态,可平稳放置。可悬停角度为:5°-160°

在悬停状态下,建议“上半屏显示内容,下半屏展示操作”。

例如在视频播放的悬停态中,上半屏为播放页,下半屏为操作区,更方便地进行拖动播放进度、暂停、调节亮度音量等操作。

2.6 界面布局

由于折叠屏在展开态下,屏幕尺寸和比例与直屏手机差异较大,需根据不同需求调整合适的布局,确保用户在不同形态上保持一致的体验。

界面布局主要分为“相对拉伸”、“相对缩放”、“挪移”、“延伸”、“分栏布局”5个类别。

相对拉伸

布局中元素的高度为固定值,元素的宽度对比参照物确定,元素的显示宽度或者元素之间的间距随着屏幕变大而相对变大。

相对拉伸适用于文字内容、输入框、搜索框等。需要注意的是,随着拉伸而改变比例的图片是一种延展,不应因拉伸而变形。

相对缩放

布局中元素的大小比例保持固定,通过对比参照物确定尺寸,显示宽度随着屏幕变大而放大。

相对缩放适用于全屏状态下有固定比例的元素,如图片、视频等。页面中的图片比例不建议放太大,应保持合适的比例。

挪移

当屏幕宽度发生变化时,部分模块的布局可以挪动位置,例如将原先的上下布局切换成左右布局,用以提供屏幕的利用率。

挪移适用于信息层级相对较少的页面,例如歌单详情页等。

延伸

布局中元素横向布局,元素间的距离固定,可显示元素的数量随着显示宽度的改变而变化。

延伸布局适用于资讯TAB、内容推荐卡片、可视化数据等。

瀑布为延伸的拓展用法,将原来单列纵向布局,切分为两列或多列的纵向布局,在⼤屏上呈现更多内容。

分栏布局

具有 “父子和父父关系层级”的列表应用,可以左侧展示一级页面右侧展示其优先级高的子页面。

分栏布局适用于 IM、笔记、信息、邮件等列表类应用。

2.7 多窗口交互

多窗口类别优势适用场景
悬浮小窗通过减少跳转,更快处理临时任务,且广泛适用于各种场景多应用多任务单应用多任务
分屏双应用/任务的并行处理,且广泛适用于各种场景多应用多任务单应用多任务
应用多窗以多实例实现应用内的双窗口单应用多任务

悬浮小窗

悬浮小窗以小窗的形式展现应用,并支持不同窗口形式(小窗、分屏、全屏)之间快速切换。

小窗入口包括但不限于:近期任务卡片“小窗”选项,应用内滑、悬浮通知下拉等。

悬浮小窗能通过减少跳转,更快处理临时任务,且广泛适用于各种场景。

悬浮小窗技术接入规范:https://dev.vivo.com.cn/documentCenter/doc/582

分屏

vivo分屏在原生分屏的基础上做了定制化处理,例如增加分屏方式(消息三指组合)、分屏小桌面列表、输入法边界定制、加密界面定制等。

分屏的优势在于多应用/任务的并行处理,且广泛适用于各种场景。

vivo分屏的手势分屏方式为:三指上滑

分屏技术接入规范:https://dev.vivo.com.cn/documentCenter/doc/573

应用多窗

应用多窗以多实例实现应用内的双窗口,根据应用自身特性进行界面组合,减少频繁切换窗口的行为,提升效率。

应用多窗的优势主要分为以下两个:

    1. 同时比较两个同类型内容的不同信息。比如两个不同的图像、文档、商品详情等。

    2. 同时显示多级页面,呈现相同信息的不同维度。通常为主次关系,比如左半屏展示列表页面,右半屏为选中项的详情页面。适用于电商购物、通讯社交、效率办公等频繁切换窗口的应用场景。

应用多窗-左静右变

应用多窗提供了“左静右变”和“左变右变”两种交互规则:

左静右变的规则为:左侧固定页面,右侧可变,进行内容切换,右侧窗口是最终窗口。

适用于效率办公和通讯社交类应用。

应用多窗-左变右变

左变右变的规则为:左侧右侧皆可变。在右侧交互后启动新窗口时,把右侧界面往左推,新的界面在右侧展示。

适用于购物场景类应用。

跨应用拖拽

跨应用拖拽可以让用户将一个应用中的图像、文档或文件拖拽到另一个应用中。

通过分屏和悬浮小窗实现在大屏的跨应用拖拽,减少用户在应用之间来回切换,更高效地进行多任务处理,提高生产力。

关于跨应用拖拽的适配:https://developer.android.com/guide/topics/ui/drag-drop

三、典型场景

3.1 影音娱乐

影音娱乐类场景以大量影音内容资源带来的沉浸式体验为主。

3.1.1 视频资源平台

首页推荐

视频列表页

3.1.2 短视频/直播互动页

3.1.3 音乐播放界面

3.1.4 视频播放界面(悬停)

3.2 资讯阅读

资讯阅读类场景以信息的聚合为主,需利用屏幕优势,确保用户对关键信息浏览、理解的完整和高效。

3.2.1 首页布局:左右图文结构

3.2.2 首页布局:上下图文结构

3.2.3 资讯详情页

3.3 生活服务

生活服务类场景广泛地包含了购物、饮食、出行、学习等用户日常生活的各个方面。

3.3.1 首页列表

3.3.2 详情页面

3.4 通讯社交

社交通讯类场景主要包括:文字交流为主的IM对话、图像视频通话、社交动态等场景。

3.4.1 文字交流为主(IM对话)

3.4.2 图像·视频通话

3.4.3 社交动态

首页结构:推荐

详情页

可根据实际情况,自由选择应用多窗的两种交互规则。请参考基础适配原则-交互方式-多窗口交互(2.7)

3.5 效率办公

效率办公类场景以高效的体验,辅助和提升工作者的办公效率为主。

3.6 H5页面

H5页面以其便利的特性,广泛应用于小程序和网页版应用。

3.7 金融理财

用户在金融理财类场景中,需确保大屏信息呈现所带来的高效与舒适。

同时,需保障用户办理金融业务过程中的易用性。

3.7.1 首页布局

3.7.2 股票·走势详情页

3.8 游戏

根据不同的游戏类型和场景,优化大屏布局,在呈现与交互层面给用户带来愉悦的体验。

同时,考虑到用户在玩游戏时长时间握持设备,在设计展开态布局时,应根据不同的交互区做适配优化。

请参考交互方式(2.5)-合适的交互区

四、测试应用

4.1 设备尺寸

可在 Android Studio 中基于以下设备规格信息进行测试。

屏幕类型对角线长度(英寸)比例分辨率(像素)
主屏(展开态)8.034:3.551916*2160
副屏(折叠态)6.5321:9 1080*2520

Android P应用适配指南

一、如何体验升级android P

1.1 x21升级android P指导

请开发者更新到市场最新系统版本进行对应调试。

1.2 vivo远程真机服务

vivo云测平台已经提供关于vivo x21 androidP的远程真机服务,开发者可以直接通过以下链接进入远程真机进行试用体验:

https://vcl.vivo.com.cn/#/home/index

1.3 pixel升级android P

开发者持有Pixel系列的机器可以直接ota升级,或则下载镜像升级,具体见链接:

https://developers.google.com/android/images

二、AndroidP兼容性变化

2.1 对非 SDK 接口的限制

2.1.1 介绍

非sdk的接口存在着稳定性问题,随着android版本的变化随时都有可能被移除,AndroidP开始,为了更好的提升app的兼容性,正对隐藏的非sdk接口进行限制,通过名单控制进行使用限制,具体规则限制如下:

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

2.1.2 影响范围

所有运行在AndroidP系统上的应用

2.1.3 如何适配

(1)对于黑名单及深灰名单中的接口,应用及时调整新的方案进行适配;

(2)黑名单及灰名单是在源码构建的时候生成的,在此提供一份,文件下载链接:【黑名单】点此下载   | 【灰名单】点此下载

(3)应用可以直接adb logcat命令中过滤”Accessing hidden”查看当前应用使用非sdk的情况

2.2 刘海屏适配指导(cutout)

2.2.1 介绍

随着X21后各种刘海屏相继出现,但没有一致的接口,AndroidP开始提供规范化的接口,应用可以使用标准接口,获取当前是否有刘海,控制应用在刘海屏上的布局显示区域。AndroidP的设备支持模拟刘海效果,持有P的设备的可以打开“开发者选项”,找到“模拟巨有凹口的显示屏”进行模拟调试。

2.2.2 影响范围

所有运行在AndroidP系统上的应用,不分targetsdkversion

2.2.3 如何适配

■ 怎么判断是否刘海支持与否?

View.getRootWindowInsets().getDisplayCutout()

返回DisplayCutout对象,为刘海的描述信息,不支持则返回空

■ 怎么获取刘海信息?

DisplayCutout.getSafeInsets() 返回安全区域Rect

DisplayCutout.getBounds()  返回刘海的区域的Region

■ 如何控制应用的布局显示?

通过控制窗口布局的layoutInDisplayCutoutMode属性可以达到控制应用在刘海屏下布局区域,具体可以设置以下值

LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT

没有设置的情况下默认此标记,只有状态栏区域可见的情况下,才意味着加了FLAG_FULLSCREEN or SYSTEM_UI_FLAG_FULLSCREEN标记的应用窗口都会被切边放在刘海以下

LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

此flag下不进行应用窗口的限制,窗口可以显示到刘海区域

LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

此flag下应用窗口一直被限制在刘海区域以下

应用也可以通过theme来达到同样的效果

<item name=”android:windowLayoutInDisplayCutoutMode”>default</item>

对应LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT

<item name=”android:windowLayoutInDisplayCutoutMode”>shortEdges</item>

对应LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

<item name=”android:windowLayoutInDisplayCutoutMode”>never</item>

对应LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

应用遇到窗口显示被限制在刘海以下区域的可以调整

layoutInDisplayCutoutMode 设置为

LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,再通过获取

DisplayCutout 关于刘海区域信息,调整UI达到更好的满屏体验。

2.3 应用待机分组策略

2.3.1 介绍

应用待机分组为AndroidP上新的电源管理功能,它将应用归为五类,没有采用不同的限制策略,来控制应用的访问资源的能力。

具体分以下五类:

活跃如果用户当前正在使用应用,应用将被归到“活跃”群组中,例如:
应用已启动一个 Activity
应用正在运行前台服务
应用的同步适配器与某个前台应用使用的 content provider 关联
用户在应用中点击了某个通知
工作集如果应用经常运行,但当前未处于活跃状态,它将被归到“工作集”群组中。 例如,用户在大部分时间都启动的某个社交媒体应用可能就属于“工作集”群组。 如果应用被间接使用,它们也会被升级到“工作集”群组中。
常用如果应用会定期使用,但不是每天都必须使用,它将被归到“常用”群组中。 例如,用户在健身房运行的某个锻炼跟踪应用可能就属于“常用”群组。
极少使用如果应用不经常使用,那么它属于“极少使用”群组。 例如,用户仅在入住酒店期间运行的酒店应用就可能属于“极少使用”群组。
从未使用安装但是从未运行过的应用会被归到“从未使用”群组中,此类应用不具备运行条件。

限制策略如下:

分类jobs*Alarns NetworkFirebase Cloud Messaging
活跃无限制无限制无限制无限制
工作集2小时每次6分钟每次无限制无限制
常用 8小时每次30分每次无限制High priority: 10/day
极少使用24小时每次2小时每次24小时每次High priority: 5/day
1. jobs在限制的情况下,只有10分钟窗口时间执行,超出十分钟将被停止
2. alarms在限制的情况下,只有10s中的执行时间
3. 网络被限制的情况下,每次10分钟的窗口时间访问网络资源

2.3.2 影响范围

所有运行在AndroidP系统上的应用,不分targetsdkversion,受此影响为主要为应用的后台行为受限制,特别如闹钟,地图导航,后台下载,健康类应用。

2.3.3 如何适配

■ 应用根据Android的限制策略,点检应用的后台行为是否被限制。

■ 如何确认是否因为应用待机分组导致的后台行为限制?

(1)先确认应用的待机分组

            adb shell am get-standby-bucket [packagename]  //查下当前应用的分组情况;

(2)如果不在活跃组(active)

            adb shell am set-standby-bucket packagename active  //强制切换应用到活跃分组;

确认在此情况下用户的行为是否依然受限制,如果是的话,才确认为待机分组策略导致的后台行为限制。

■ 应用可以通过

            adb shell am set-standby-bucket packagename active|working_set|frequent|rare 在不同分组见强制进行切换,调试自身应用。

■ 对于由于后台分组策略导致的后台限制,应用需要进行相关策略上的调整详细见:https://developer.android.com/about/versions/pie/power

2.4 Crypto JCA 提供程序已被移除,弃用 Bouncy Castle 加密

2.4.1 介绍

Crypto JCA 提供程序已被移除。调用 SecureRandom.getInstance(“SHA1PRNG”,”Crypto”) 将会引发 NoSuchProviderException,调用Bouncy Castle 提供程序的 getInstance(),会生成 NoSuchAlgorithmException 错误。

2.4.2 影响范围

(1)Crypto JCA 提供程序已被移除,此影响所有运行AndriodP系统的所有应用;

(2)Bouncy Castle 提供程序异常的问题,影响所有targetsdkversion>=28的应用;

2.4.3 如何适配

模块应该在getInstance()的时候不指派提供程序,采用默认实现即可

2.5 FLAG_ACTIVITY_NEW_TASK被强制要求

AndroidP上,从非 Activity 环境中启动 Activity,除非传递 Intent 标志 FLAG_ACTIVITY_NEW_TASK。 如果尝试在不传递此标志的情况下启动 Activity,则该 Activity 不会启动,此限制对所有运行AndroidP的应用生效。

2.6 禁止空闲应用访问相机、麦克风和传感器

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

(1)应用不能访问麦克风或摄像头。

(2)使用连续报告模式的传感器(例如加速度计和陀螺仪)不会接收事件。

(3)使用变化或一次性报告模式的传感器不会接收事件。

2.7 前台服务的应用必须请求 FOREGROUND_SERVICE 权限

targetsdkversion>=28的应用在使用前台服务的都需要进行必须请求 FOREGROUND_SERVICE 权限。 这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

<uses-permission ndroid:name=”android.permission.FOREGROUND_SERVICE”/>

2.8 默认情况下启用网络传输层安全协议

AndroidP上,对应targetsdkversion>=28的应用需要为特定域名启用明文,必须在应用的网络安全性配置中针对这些域名将 cleartextTrafficPermitted 显式设置为 true,默认情况下明文传输会直接抛出“java.io.IOException: Cleartext HTTP traffic to xxx.com not permitted”异常。

2.9 Apache HTTP 客户端弃用,bootclasspath 中已移除

AndroidP开始org.apache.http.legacy.jar这个包不在打包进bootclasspath,对于targetsdkversion>=28的,继续引用此包的应用将直接出现NoClassDefFoundError,对于targetsdkversion低于28的,系统会将此包加载到应用的classloader中,如果应用采用系统的classloader加载应用,将同样会出现NoClassDefFoundError,建议模块使用 HttpURLConnection 类,更加高效。

2.10 移除对 Build.serial 的直接访问

Build.SERIAL字段已经被废弃,AndroidP上值一直为“UNKNOWN”, 如果您的应用需要访问设备的硬件序列号,您应请求 READ_PHONE_STATE 权限,然后调用 getSerial()。

2.11 不允许共享 WebView 数据目录

targetsdkversion>=28的应用不允许在不同进程之间共享一个 WebView 数据目录。如果应用有多个进程使用 WebView、CookieManager 或 android.webkit 软件包中的任何其他 API,则在第二个进程调用 WebView 函数时,应用将会崩溃。

2.12 应用禁止访问xt_qtagui目录的文件

AndroidP后,不再允许应用直接读取 /proc/net/xt_qtaguid 文件夹中的文件。 这样做是为了确保与某些根本不提供这些文件的设备保持一致。应用应该采用标准 API TrafficStats 和 NetworkStatsManager 进行访问,此限制对所有运行AndroidP系统上的应用生效。

2.13 SELinux 禁止访问应用的数据目录

对于targetsdkversion>=28的应用,系统强制每个应用的 SELinux 沙盒对每个应用的私有数据目录强制执行逐个应用的 SELinux 限制。现在,不允许直接通过路径访问其他应用的数据目录。应用可以继续使用进程间通信 (IPC) 机制(包括通过传递 FD)共享数据,例如可以采用FileProvider

三、参考链接

(1)AndroidP所有应用行为变更:https://developer.android.com/about/versions/pie/android-9.0-changes-all

(2)AndroidP targetSDK 28应用行为变更:https://developer.android.com/about/versions/pie/android-9.0-changes-28

(3)AndroidP 电源管理:https://developer.android.com/about/versions/pie/power

(4)pixles系列镜像升级:https://developers.google.com/android/images

Android Q应用适配指南

一、如何体验升级android Q

1.1 vivo机器升级android Q指导

vivo NEX S, vivo NEX A,vivo X27已经提供有可升级到Android Q的开发者预览版本,开发者可以直接通过以下链接指导进行升级试用:

https://dev.vivo.com.cn/documentCenter/doc/210

1.2 vivo远程真机调试

vivo云测平台已经提供关于vivo NEX S, vivo NEX A,vivo X27 Android Q的远程真机服务,开发者可以直接通过以下链接进入远程真机进行试用体验:

https://vcl.vivo.com.cn/#/home/index

1.3 google原生机升级android Q

开发者持有Pixel系列的机器可以直接ota升级,或者下载镜像升级,具体见链接:

https://developer.android.google.cn/preview/download

二、Android Q兼容性变化

2.1 非SDK接口限制

Android 平台开始限制您的应用在 Android 9(API 级别 28)中使用非 SDK 接口,灰名单和白名单的非 SDK 接口已有更新。

适配建议: 

依赖非SDK接口的应用应尽快迁移到 SDK 替代方案,如部分非SDK接口无替代方案,则请求新的公共API。

2.2 重大隐私权变更

2.2.1 分区存储

以 Android Q 为目标平台的应用(以及选择接受这些变更的应用),Android Q 更改了应用对设备外部存储设备中的文件(例如存储在路径 /sdcard 下的文件)的访问方式,只有满足相关条件,应用才能访问其他应用创建的文件。

适配建议: 

如果应用以 Android Q 为目标平台,则在访问外部存储设备中的文件时会进入过滤视图,具有过滤视图的应用对其创建的文件始终拥有读/写权限,无论文件位于特定于此应用的目录以内还是以外。只有在满足以下两个条件时,您的应用才能访问其他应用创建的文件:

(1)您的应用已获得 READ_EXTERNAL_STORAGE 权限。

(2)这些文件位于以下其中一个明确定义的媒体集合中:

照片:存储在 MediaStore.Images 中。

视频:存储在 MediaStore.Video 中。

音乐文件:存储在 MediaStore.Audio 中。

2.2.2 设置位置信息

Android Q 引入了新的位置权限,区分应用前台和后台获取位置信息。如果您的应用在后台时请求访问设备位置信息,则会影响您的应用。如果用户只授权前台获取位置信息权限, 应用在返回后台后则不能再获取位置信息。

适配建议: 

使用新权限在后台访问位置信息,并在没有后台位置信息更新的情况下确保优雅降级。应用应向用户说明他们需要允许该应用始终都能访问设备位置信息,以确保正常运行,然后请求在后台访问位置信息。

2.2.3 后台应用启动

Android Q 对应用可启动 Activity 的时间施加了限制,只有在满足相关条件时才能启动 Activity。此项行为变更适用于在 Android Q 上运行的所有应用。

适配建议: 

检查activity是否符合启动的条件,后台应用都应创建通知以便向用户提供信息。

2.2.4 硬件标识符获取

从 Android Q 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 特许权限才能访问设备的不可重置标识符(包含 IMEI 和序列号),会对应用依赖device id的功能产生影响。影响在 Android Q 上运行的所有应用,即使这些应用以 Android 9(API 级别 28)或更低版本为目标平台。

适配建议: 

请关注厂商近期发布的适配指导。

2.3 加固版本兼容

Android每个大版本升级,加固方案商都会对android大版本适配和兼容。依赖加固固件的应用需要及时更新最新的加固固件来适配Android新版本,避免加固导致应用无法正常使用或影响应用稳定性。

2.4 第三方SDK兼容

应用会依赖第三方的SDK Jar或Native so库等第三方SDK,Android大版本升级第三方SDK会存在不兼容的问题,需要推动以及更新依赖的第三方SDK适配android Q。

三、参考链接

(1)Android Q所有应用行为变更:https://developer.android.google.cn/preview/behavior-changes-all

(2)Android Q targetSDK 29应用行为变更:https://developer.android.google.cn/about/versions/10/behavior-changes-10

(3)Android Q 中的隐私权:https://developer.android.google.cn/preview/privacy

(4)google pixel系列镜像升级包:https://developer.android.google.cn/preview/download

Android 11应用适配指南

1、如何体验升级Android 11

1.1 vivo机器升级Android 11指导

请开发者更新到市场最新系统版本进行对应调试。

1.2 vivo远程真机调试

vivo云测平台上线了搭载有Android 11开发者预览版的测试机,提供了iQOO3、NEX 3S两款测试机型。vivo开发者云测平台官网链接:vcl.vivo.com.cn

1.3 google原生机升级Android 11

开发者持有Pixel系列的机器可以直接ota升级,或者下载镜像升级,具体见此链接。 

2、Android 11上的主要变更

2.1 兼容性

2.1.1 分区存储

说明:分区存储机制使得应用在外部存储空间能有一块属于自己的专用存储区域,这块区域是私有的,因此,这块区域非常适用于保存用户的私有数据。当然,应用无法访问其他应用的专用存储区域。但如果应用需要将自己专用存储区域的特定文件让其他应用也访问得到,可以通过设置文件分享的方式,去为这些文件做可共享的标记。分区存储将在文件管理、应用程序保护、用户隐私数据保护等方面上有很好的作用。

影响范围:

1) targetSdkVersion为30的应用。

2) targetSdkVersion为29,且未将requestLegacyExternalStorage设为true以停用分区存储的应用。

适配建议:

若您的应用依然使用旧版存储机制,现则需要将数据迁移到与分区存储兼容的目录。

访问文件的位置所需权限访问方法
应用的私有目录无需权限即可访问getExternalFilesDir()
其他应用的私有目录无,但目标文件要被其应用使用FileProvider标记为可共享文件通过ParcelFileDescriptor与FileDescriptor获取
媒体文件目录(音频、照片、视频文件)READ_EXTERNAL_STORAGE(仅当访问其他应用的文件时需要)MediaStore   API
下载目录(文档文件等)无需权限即可访问存储访问框架SAF

分区存储的详细介绍:https://developer.android.google.cn/preview/privacy/storage

2.1.2 单次授权

说明:Android 11开发者预览版本对权限进行了更细颗粒度的划分,引入了“单次授权”的概念。用户可以进行单次授权,让应用获得对用户位置、相机或麦克风的临时性访问权限,如下图所示。在获得本次的授权后,应用可以在以下时间段内获得对应数据的访问:

1) 当应用的Activity可见时。

2) 应用转为后台运行后的一小段时间。

3) Activity可见时启动了一项前台服务,并且随后将应用转到后台,那么应用可以继续访问相关数据,直到该前台服务停止。

影响范围:运行于Android 11上的所有应用。

适配建议:如果您的应用已遵循与权限相关的最佳做法(https://developer.android.google.cn/privacy/best-practices),您无需更改应用即可支持单次授权。

图:应用内的权限申请窗口提供一次性权限选项

2.1.3 后台位置信息访问权限获取方式

说明:当应用申请后台位置信息访问权限时,让用户授予权限的弹窗中,将不再提供“始终允许”的选项,这个选项只存在于设置中的应用权限授予页面,一定程度上能减少应用的“走后门”情况发生,如下图所示,并且后台位置权限的申请需要应用已经拥有前台位置权限。

影响范围:运行于Android 11开发者预览版本上的所有应用

适配建议:若您的应用确定需要获得后台位置信息访问的权限,现在则需要分为两个步骤,因为已无法在没有前台位置信息访问权限的时候直接申请后台位置信息访问权限。

1) 先申请前台位置信息访问权限

2) 再申请后台位置信息访问权限,也就是所谓的“始终允许”,而用户将被引导到设置中进行授予

图:申请后台位置信息访问权限时,应用内的权限申请弹框不再包含“始终允许”

图:后台位置信息访问权限的授予只能在设置中进行

2.1.4 软件包可见性

说明:Android 11开发者预览版本更改了应用查询同一设备上的其他已安装应用的方式,以及与之交互的方式。

影响范围:targetSdkVersion为30的应用

适配建议:应用需要在应用的清单文件中添加<queries>元素,以便系统了解应向其显示哪些其他已安装的应用。如果您的应用执行与其他应用的常见互动,那么您无需更改应用。更多关于Android 11开发者预览版本软件包可见性的信息可参考https://developer.android.google.cn/preview/privacy/package-visibility

2.1.5 新的前台服务类型

说明: Android 11更改了前台服务访问摄像头和麦克风相关数据的方式以进一步保护用户隐私。

影响范围:targetSdkVersion为30的应用

适配建议:您需要在该前台服务声明的foregroundServiceType属性中添加新的camera和microphone类型,否则将无法获取摄像头与麦克风的数据。

2.1.6 自定义视图消息框使用受限

说明:从后台发布的自定义视图消息框将会被系统屏蔽。这类消息框使用setView()为自己定义了一个布局,如图所示。出于安全与用户体验上的考虑,系统屏蔽了从后台发起的自定义视图消息框。但从前台发布的自定义视图消息框依然可以正常生效,且使用Toast.makeText()创建的文本消息框不受影响,在前后台发布均可正常生效。

影响范围:targetSdkVersion为30的应用

适配建议:建议使用信息提示控件(Snackbar)来做代替。

图:Android Q上从后台发布的自定义视图消息框示例

2.1.7 非SDK接口名单更新

说明:Android 11有大量的非SDK接口名单更新,各接口名单更新情况可查询https://developer.android.google.cn/about/versions/11/non-sdk-11。这些变更可能会对一些依赖了非SDK接口的应用带来不同程度的兼容性问题,特别是依赖了Android Q灰名单接口的应用,因为这些接口有一部分已经在Android 11中已归入黑名单中。

影响范围:运行于Android 11上的所有应用。

适配建议:如果您的应用依赖于Android 11的受限接口,您应该开始计划升级SDK并迁移到SDK替代方案。

2.2 新的交互体验和方式

每次Android系统的升级,几乎都会在交互体验上带来一些新变化,此次Android 11也不例外。

例如:

2.2.1 聊天气泡

聊天气泡(chat bubbles)的会话方式正式推出,不再是实验性功能,该特性支持会话窗口最小化为一个或多个悬浮气泡,气泡可以展开为小窗口模式的页面;

图:气泡形式的消息通知

图:气泡展开为会话小窗口

2.2.2 新的输入法键盘过渡动画

借助两个新的API接口——边衬区动画监听器(Insets Animation Listener)与窗口动画控制器(WindowInsets Animation Controller),Android 11为每天都要与我们打交道的输入法键盘带来了新的过渡动画,这些API可让您更轻松地调整应用内容,与IME的出现和消失以及状态和导航栏等其他元素保持同步。这是一个谷歌所提供的示例https://github.com/android/user-interface-samples/tree/master/WindowInsetsAnimation。和当前主流版本中直接从底部弹出的动画相比,新的输入法键盘动画可以跟随我们手指的实际划动逐帧变换,呈现出更加流畅也更加自然的滑入、滑出效果等等。

2.3 硬件层面的新支持

2.3.1 Android 11将更好地支持各类手机屏幕,以提升用户体验

● 瀑布屏:瀑布屏的“瀑布”区域,会带来边缘内容显示失真和误触的情况。在Android 11上,开发者已可以控制“瀑布”区域的交互,现有的DisplayCutout.getSafeInset…()方法现在会返回能够避开瀑布区域以及刘海的安全边衬区。

● 高刷屏:Android 11加入了新的API——Surface.setFrameRate()来允许应用设置自身运行的首选刷新率,以发挥高刷屏的优势获得更好的使用体验,同时也帮助系统在运行应用时智能切换,从系统层面解决高刷新率可能会带来的功耗问题。

2.3.2 Android 11支持并发使用多个摄像头

开发者可以通过新的API以查询对同时使用多个摄像头(包括前置摄像头和后置摄像头)的支持。如需在运行应用的设备上检查支持情况,可以使用以下2个方法,getConcurrentCameraIds()方法可返回摄像头ID的组合,isConcurrentSessionConfigurationSupported()可查询摄像头设备是否可以并发支持相应的会话配置。

2.4 增强5G支持

Android 11 带来了针对5G的“动态计量”和“带宽估算”,更好地发挥5G的高带宽和低延迟特性。灵活地针对不同的场景,不同的网络情况,自适应流媒体质量。

2.5 其他功能

2.5.1 ADB增量APK安装

在设备上安装大型APK可能需要很长的时间。ADB增量APK安装可以安装足够的APK以启动应用,同时在后台流式传输剩余数据,从而加速这一过程。如果设备支持该功能,并且您安装了最新的SDK平台工具,adb install命令将自动使用此功能。或运行此命令adb install –incremental以使用该功能。在运行ADB增量APK安装之前,您必须先为APK签名并创建一个APK签名方案v4文件。且必须将v4签名文件放在APK旁边,才能使此功能正常运行。

2.5.2 应用进程退出原因

Android 11引入了ActivityManager.getHistoricalProcessExitReasons()方法,用于报告近期任何进程终止的原因。应用可以使用此方法收集崩溃诊断信息,例如进程终止是由于ANR、内存问题还是其他原因所致。此外,您还可以使用新的setProcessStateSummary()方法存储自定义状态信息,以便日后进行分析。

2.5.3 动态资源加载器

Android 11引入了两个新API类ResourcesLoader和ResourcesProvider,用来支持应用动态扩展资源的搜索和加载方式。主要的一个用例就是让应用去访问APK外特定目录的资源。

3、参考链接

[1] Android 11中的存储机制更新:https://developer.android.google.cn/preview/privacy/storage

[2] 遵循权限方面的最佳做法:https://developer.android.google.cn/privacy/best-practices

[3] Android 11中的软件包可见性:https://developer.android.google.cn/preview/privacy/package-visibility

[4] Android 11中消息框的更新:https://developer.android.google.cn/guide/topics/ui/notifiers/toasts

[5] 非SDK接口名单更新:https://developer.android.google.cn/about/versions/11/non-sdk-11

[6] 新的输入法键盘过渡动画示例:https://github.com/android/user-interface-samples/tree/master/WindowInsetsAnimation

[7] Android 11中的重大隐私权变更:https://developer.android.google.cn/preview/privacy

[8] Android 11新的功能和API概览:https://developer.android.google.cn/preview/features

Android 12应用适配指南

1.Android 12上的主要变更

1.1 兼容性

1.1.1 前台服务启动限制

说明:除少数特殊情况外,以Android 12为目标的应用程序无法在后台运行时启动前台服务。如果应用程序在后台运行时尝试启动前台服务,并且前台服务不满足以下特殊情况之一,则系统将抛出ForegroundServiceStartNotAllowedException异常。具体情况可查询  https://developer.android.com/about/versions/12/foreground-services 。

注意:如果一个应用程序调用Context.startForegroundService()启动另一个应用程序拥有的前台服务,则只有两个应用程序的API级别都为Android 12时,此页面上描述的限制才有效。

影响范围:targetSdkVersion为31的应用。

适配建议:如果您的应用想要在后台运行时启动前台服务但又不符合以上几种特例时,您可以尝试使用WorkManager启动优先级更高的后台任务。在Android 12中WorkManager将支持一种新作业-加急作业,它允许应用执行重要任务,同时使系统能够更好地控制对资源的访问权限。但是加急作业并不是万能的,在系统负载过高或者已超出加急作业配额限制的时候,系统会延迟启动新的加急作业。

1.1.2 前台服务通知延迟

为了在 Android 12 上提供针对短时间运行的前台服务的流畅体验,系统可以为某些前台服务延迟 10 秒显示前台服务通知。此更改使某些短期任务在显示通知之前完成。如果某项前台服务至少具有以下特征之一,则系统会在服务启动后立即显示相关通知:

1.该服务与包含操作按钮的通知相关联。

2.该服务的 foregroundServiceType 为mediaPlayback、mediaProjection 或 phoneCall。

3.该服务根据通知的类别属性中的定义,提供与通话、导航或媒体播放相关的用例。

注意:在未来的 Android 12 开发者预览版中,这些用例可能会发生变化。

4.该服务通过在设置通知时调用 setShowForegroundImmediately(),以停用行为变更。

1.1.3 待处理 intent 必须声明可变性

说明:如果您的应用以 Android 12 为目标平台,您必须为您的应用创建的每个 PendingIntent 对象指定可变性。这项额外的要求可提高应用的安全性。如需声明特定 PendingIntent 对象是否可变,请分别使用 PendingIntent.FLAG_MUTABLE 或 PendingIntent.FLAG_IMMUTABLE 标志。如果您的应用试图在不设置任何可变标志的情况下创建 PendingIntent 对象,系统会抛出 IllegalArgumentException。 

影响范围:targetSdkVersion为31的应用。

适配建议:您必须为您的应用创建的每个 PendingIntent 对象指定可变性。

1.1.4 非SDK接口名单更新

说明:Android 12相较于Android11有大量的非SDK接口名单更新,这些改变可分为两种: 

1.Android 11(API 级别 30)中不受支持的(已被列入灰名单)的非 SDK 接口现已在 Android 12 中被屏蔽;

2.在 Android 12 中被添加到 Android SDK 的非 SDK 接口。

各接口名单更新情况可查询https://developer.android.com/about/versions/12/non-sdk-12 。这些变更可能会对一些依赖了非SDK接口的应用带来不同程度的兼容性问题,特别是依赖了Android 11灰名单接口的应用,因为这些接口有一部分已经在Android 12中已归入屏蔽名单中。

影响范围:运行于Android 12上的所有应用。

适配建议:如果您的应用依赖于Android 12的受限接口,您应该开始计划升级SDK并迁移到SDK替代方案。

1.2 用户体验

每次Android系统的升级,几乎都会在交互体验上带来一些变化,此次Android 12也不例外。

1.2.1 接收内容的统一API

对于用户来说,目前还没什么方法在应用中插入和移动图片、视频和其他富有表现力的内容。为了使您的应用能够轻松接收富媒体内容,我们引入了全新的统一 API,便于您接受来自任何来源的内容。在Android 12上,您可以用粘贴板复制粘贴、键盘输入或者拖放图片或者视频等内容。

在Android 11以及之前的版本,每个界面机制(例如长按菜单或拖放)都有对应的 API。这意味着您必须单独与每个API集成,并为每种插入内容的机制添加类似的代码:

而在Android 12上,统一API会通过创建一个要实现的单一 API 来整合这些不同的代码路径,这样您就可以专注于应用特定的逻辑,而让平台处理其余的工作。

您可以向界面组件附加新接口 OnReceiveContentListener,并在通过任何机制插入内容时获得回调。此回调会成为您的代码处理接收所有内容(从纯文本和样式文本到标记、图片、视频、音频文件等)的唯一位置。

1.2.2 自定义通知变更

以前,自定义通知能够使用整个通知区域并提供自己的布局和样式。由此产生的反模式可能会令用户困惑,或在不同设备上引发布局兼容性问题。Android 12 改变了完全自定义通知的外观。

对于以 Android 12 为目标平台的应用,包含自定义内容视图的通知将不再使用完整通知区域;相反,系统会应用标准模板。此模板可确保自定义通知在所有状态下都与其他通知相同,例如,在收起状态下的通知图标和展开功能,以及在展开状态下的通知图标、应用名称和收起功能。

通过这种方式,Android 12 通过为用户提供可看到且熟悉的通知展开功能,使所有通知保持外观一致且易于浏览。

如果您的应用使用的是完全自定义的通知,我们建议您尽快使用新模板进行测试,并进行必要的调整:

1.启用自定义通知变更:

a.将应用的 targetSdkVersion 变更为 S 以启用新行为。

b.重新编译。

c.在搭载 Android 12 的设备或模拟器上安装您的应用。

2.测试所有使用自定义视图的通知,确保这些通知在通知栏中看起来符合预期。

3.请注意自定义视图规格。一般来说,提供给自定义通知的高度比之前小。在收起状态下,自定义内容的最大高度已从 106dp 减少到 48dp。此外,水平空间也减小了。

4.为了确保“浮动通知”状态看起来符合您的预期,请勿忘记将通知渠道的重要性提升至“高”(在屏幕中弹出)。

1.2.3 配套设备的权限授予

连接到手表时,面向Android 12及更高版本的开发者们现在可以使用配置文件将特定于设备类型的一组权限捆绑在一起,让用户在手机连接上设备时将一次性授予所有权限,从而简化了设置过程。用户删除应用程序或删除关联之后,系统也会删除相关权限。

1.3 图形、图像和媒体

1.3.1 更轻松的模糊,滤色器和其他效果

Android 12添加了新功能RenderEffect ,可将常见的图形效果(例如模糊,滤色器,Android着色器效果等)应用于Views和渲染层次结构。效果可以组合为链式效果(组成内部和外部效果)或混合效果。由于处理能力有限,部分的Android设备可能不支持该功能。通过调用View.setRenderEffect(RenderEffect),效果也可以适用于View的底层的RenderNode。

实施RenderEffect:view.setRenderEffect(RenderEffect.createBlurEffect(radiusX, radiusY, SHADER_TILE_MODE))。

1.3.2音频和触觉耦合效果

Android 12应用程序可以使用手机的振动器从音频会话中生成触觉反馈。这为更身临其境的游戏和音频体验提供了机会。例如,触觉增强的铃声可以帮助识别呼叫者,或者驾驶游戏可以模拟崎岖地形的感觉。

1.4 安全性与隐私

1.4.1 更安全地导出组件

说明:如果您的应用以 Android 12 为目标平台,且包含使用 intent 过滤器的 activity、服务或广播接收器,您必须为这些应用组件显式声明 android:exported 属性。如果 activity、服务或广播接收器使用 intent 过滤器,并且未显式声明 android:exported 的值,则您的应用将无法在搭载 Android 12 的设备上进行安装。

影响范围:targetSdkVersion为31的应用。

适配建议:您必须为包含intent过滤器的应用组件显式声明 android:exported 属性。

1.4.2 adb 备份限制

说明:为了保护私有应用数据,Android 12 变更了 adb backup 命令的默认行为。对于以 Android 12 为目标平台的应用,用户运行 adb backup 命令时,从设备导出的任何其他系统数据都不包含应用数据。

影响范围:targetSdkVersion为31的应用。

适配建议:如果您的测试或开发工作流程依赖于使用 adb backup 的应用数据,现在您可以选择通过在应用的清单文件中将 android:debuggable 设置为 true 来导出应用数据。

注意:为了帮助保护应用数据,请务必在发布应用前将 android:debuggable 设置为 false。

1.4.3 以不安全的方式启动嵌套 intent

说明:嵌套 intent 是在其他 intent 中作为 extra 传递的 intent。如果您的应用同时执行以下两项操作,就会发生 StrictMode 违规行为。

1.您的应用从已传递的 intent 的 extra 中解封嵌套 intent。

2.您的应用立即使用该嵌套 intent 启动应用组件,例如将 intent 传递给 startActivity()、startService() 或 bindService()。

为了提高平台安全性,Android 12 提供了一种调试功能,如果您的应用以不安全的方式启动嵌套 intent,此功能便会发出警告。如需检查您的应用中是否会以不安全的方式启动嵌套 intent,请在配置 VmPolicy 时调用 detectUnsafeIntentLaunch()。如果您的应用检测到 StrictMode 违规行为,您可能需要停止应用的执行以保护潜在的敏感信息。

影响范围:targetSdkVersion为31的应用。

适配建议:您的应用可能会启动嵌套 intent,以便在应用的各个组件之间导航,或代表其他应用执行操作。如需在这两种情况下最大限度地降低出现 StrictMode 违规行为的可能性,请执行以下操作:

1.嵌套 intent 的内部启动:确保这些组件不会被导出。

2.嵌套 intent 的跨应用启动:使用 PendingIntent 代替嵌套 intent。如此一来,当 PendingIntent 从包含它的 Intent 中解封时,应用组件可以使用调用进程的身份启动 PendingIntent。该配置允许提供程序应用向调用应用的任何组件(包括未导出的组件)发送回调。

1.4.4 应用无法关闭系统对话框

说明:为了加强用户与应用和系统互动时的控制,从 Android 12 开始,弃用了 ACTION_CLOSE_SYSTEM_DIALOGS intent 操作。除了一些特殊情况之外,当应用尝试调用包含此操作的 intent 时,系统会基于应用的目标 SDK 版本执行以下操作之一:

1.如果应用以 Android 12 为目标平台,则会发生 SecurityException。

2.如果应用以 Android 11或更低版本为目标平台,则系统不会执行 intent,并且打印log。

在以下情况下,应用仍然可以在 Android 12 上关闭系统对话框:

1.您的应用运行的是插桩测试。

2.您的应用以 Android 11 或更低版本为目标平台,并在抽屉式通知栏顶部显示一个窗口。

如果您的应用以 Android 12 为目标平台,在这种情况下您无需使用 ACTION_CLOSE_SYSTEM_DIALOGS。这是因为,如果在窗口位于抽屉式通知栏的顶部时您的应用调用 startActivity(),系统会自动关闭抽屉式通知栏。

3. 您的应用以 Android 11 或更低版本为目标平台。此外,用户已与通知互动,可能使用了通知的操作按钮,您的应用正在处理服务或广播接收器来响应该用户操作。

影响范围:运行于Android 12上的所有应用。

1.4.5 不受信任的触摸事件被屏蔽

说明:为了维持系统安全并保持良好的用户体验,Android 12 会阻止应用使用触摸事件,使用触摸事件时叠加层会以不安全的方式遮掩应用。换言之,系统会屏蔽穿透某些窗口的触摸操作。此变更会影响选择让触摸操作穿透其窗口的应用,例如使用 FLAG_NOT_TOUCHABLE 标志。包括但不限于以下示例:

1.需要 SYSTEM_ALERT_WINDOW 权限并使用 FLAG_NOT_TOUCHABLE 标志的叠加层,例如使用 TYPE_APPLICATION_OVERLAY 的窗口。

2.使用 FLAG_NOT_TOUCHABLE 标志的 activity 窗口。

3.消息框消息。

在以下情况下,允许执行“穿透”触摸操作:

1.应用中的互动。您的应用会显示叠加层,并且只有当用户与您的应用进行互动时才会显示叠加层。

2.可信窗口。包括但不限于以下窗口:

    a.无障碍窗口

    b.输入法 (IME) 窗口

    c.Google 助理窗口

    注意:类型为 TYPE_APPLICATION_OVERLAY 的窗口不受信任。

3.不可见窗口。窗口的根视图是 GONE 或 INVISIBLE。

4.全透明窗口。窗口的 alpha 属性为 0.0。

5.足够半透明的系统警报窗口。当组合后的不透明度小于或等于系统针对触摸的最大遮掩不透明度时,系统会将一组系统警报窗口视为足够半透明。如果系统屏蔽触摸操作,Logcat 会记录以下消息:Untrusted touch due to occlusion by PACKAGE_NAME。

影响范围:运行于Android 12上的所有应用。

1.4.6 隐藏应用程序覆盖窗口

为了使开发人员能够更好地控制用户与开发人员的应用进行交互时所看到的内容,Android 12引入了隐藏已授予SYSTEM_ALERT_WINDOW 权限的应用的叠加窗口的功能 。

声明 HIDE_OVERLAY_WINDOWS 许可后,应用程序可以调用 setHideOverlayWindows() 以指示当该应用程序自己的窗口可见时,所有TYPE_APPLICATION_OVERLAY类型的窗口都应隐藏。在显示敏感内容(例如交易确认)时,应用程序可能会选择执行此操作。

显示TYPE_APPLICATION_OVERLAY窗口类型的应用应考虑可能更适合其用例的替代方案,例如画中画或气泡。

1.4.7 安全锁屏通知操作

Android 12在Notification.Action.Builder中添加了新的setAuthenticationRequired 标志。您可以使用该标志为锁定设备上的通知添加额外的安全保护。

当通知操作(notificaiton action)中的setAuthenticationRequired值为true时,用户必须先完成身份认证之后才能在锁定设备上进行通知操作。在这之前,仅当用户通知操作启动Activity或直接答复时,系统才会要求在锁定的设备上进行身份验证。要实现此功能,请添加setAuthenticationRequired到通知操作中。

1.5 其他功能

1.5.1 圆角API

Android 12引入了RoundedCorner 和WindowInsets.getRoundedCorner(int position) API,提供了屏幕圆角的半径和中心点。使用这些API,您的应用程序可以避免UI元素在带有圆角的屏幕上被截断。这些API在非圆角屏幕的设备上不生效。

1.5.2 运动传感器的速率限制

为了保护用户的潜在敏感信息,如果您的应用以 Android 12 为目标平台,则系统会将来自某些运动传感器和位置传感器的数据刷新率限制为200 Hz。该数据包括由设备的加速度计,陀螺仪和地磁场传感器记录的值 。

如果您的应用程序以Android 12为目标平台并且需要以更高的速率收集运动传感器数据,则必须声明 HIGH_SAMPLING_RATE_SENSORS 权限。如果您的应用尝试在未声明此权限的情况下以更高的速率收集运动传感器数据, 系统会抛出SecurityException异常。

2.参考链接

[1]前台服务启动设置:https://developer.android.com/about/versions/12/foreground-services

[2]非SDK接口名单更新:https://developer.android.com/about/versions/12/non-sdk-12

[3]接收内容的统一API:https://developer.android.com/about/versions/12/features/unified-content-api

[4]自定义通知变更:https://developer.android.com/about/versions/12/behavior-changes-12#custom-notifications

vivo Android 13应用适配指南

1. Android 13上的主要变更

1.1 兼容性

1.1.1 使用 JobScheduler 改进预提取作业处理

说明:利用 JobScheduler,应用可使用 JobInfo.Builder.setPrefetch() 将特定作业标记为“预提取”作业,这意味着,理想情况下这些作业应该在应用下一次启动前提前一点运行,以提升用户体验。过去,JobScheduler 仅使用该信号让预提取作业有机会使用免费或多余的数据。

在 Android 13 中,系统现在会尝试确定应用下次启动的时间,并根据该估算值运行预提取作业。应用应尝试使用预提取作业来完成他们想要在下次应用启动前完成的任何工作。

影响范围:运行于Android 13上的所有应用。

1.1.2 停止使用共享用户 ID

说明:如果应用使用已废弃的 android:sharedUserId 属性,并且不再依赖于该属性的功能,可以将 android:sharedUserMaxSdkVersion 属性设置为 32。

这个新属性会告知系统,应用不再依赖于共享用户 ID。如果应用声明 android:sharedUserMaxSdkVersion 并且首次安装在搭载 Android 13 或更高版本的设备上,则应用的行为就像从未定义过 android:sharedUserId 一样,更新后的应用仍会使用现有的共享用户ID。

如果已在清单中定义了 android:sharedUserId 属性,请不要将其移除。这样做会导致应用更新失败。

共享用户 ID 会在软件包管理器中导致具有不确定性的行为。应用应使用适当的通信机制(例如服务和 content provider),在共享组件之间实现互操作性。

影响范围:运行于Android 13上的所有应用。

1.2 用户体验

每次Android系统的升级,几乎都会在交互体验上带来一些变化,此次Android 13也不例外。

1.2.1 前台服务(FGS)任务管理器

无论应用targetSdkVersion为多少,Android 13 都允许用户从抽屉式通知栏中停止前台服务。这项新功能称为前台服务 (FGS) 任务管理器,它会显示当前正在运行前台服务的应用列表。此列表的标签为使用中的应用,每个应用旁边都有一个停止按钮。

1.2.2 放置快捷设置图块API

借助新的图块放置API,应用现在可以提示用户直接将自定义图块添加到通知栏中的快捷设置图块中。借助新的系统对话框,用户只需一步即可不离开应用就添加图块,而不必转到“快捷设置”来添加图块。

1.2.3 按应用设置的语言偏好设置

在许多情况下,多语言用户会将其系统语言设置为某一种语言,但又想为特定应用选择其他语言。为了帮助应用为这些用户提供更好的体验,Android 13 针对支持多种语言的应用引入了以下新功能:

1. 应用可在运行时在界面中设置使用其他语言

2. 用户可在系统设置里为每个应用选择首选语言

1.3 图形、图像和媒体

1.3.1 可编程的着色器

Android 13 添加了对可编程 RuntimeShader 对象的支持,其行为是使用 Android 图形着色语言 (AGSL) 定义的。AGSL 与 GLSL 共用大部分语法,但可用于 Android 渲染引擎中以自定义 Android 画布中的绘制行为以及过滤 View 内容。Android 在内部使用这些着色器来实现涟漪效果、模糊以及拉伸滚动,并且 Android 13 让您能为应用制作类似的高级效果。

1.3.2 蓝牙低功耗音频

低功耗 (LE) 音频是新一代无线音频,旨在取代传统蓝牙并支持新的使用情形和连接拓扑。通过该技术,用户能够与朋友和家人分享音频内容以及播放音频给他们听,也可以订阅信息、娱乐或无障碍用途的公共广播内容。这项新技术可以确保用户接收到高保真度的音频,而不必牺牲电池续航时间,并且还可以在不同使用情形之间无缝切换,这是传统蓝牙技术无法实现的。

1.4 安全性与隐私

1.4.1 通知运行时权限

说明:Android 13 中引入了新的运行时权限,用于从应用发送非豁免通知:POST_NOTIFICATIONS。

1. 限对话框中可执行以下操作:

 ●  选择“允许”

如果用户选择允许选项,应用可以执行以下操作:

①发送通知。可以使用所有通知渠道。

②发送与前台服务相关的通知。这些通知会显示在抽屉式通知栏中。

 ●  用户选择“不允许”

如果用户选择不允许选项,应用将无法发送通知。除了几个特定情况之外,所有通知渠道都会被屏蔽。这类似于用户在系统设置中手动关闭应用的所有通知后发生的行为。

 ●  用户滑开对话框

滑开对话框(即既没有选择允许,也没有选择不允许),会发生以下行为:

①如果应用符合获得临时通知授权的条件,系统会保留临时授权。

②如果应用没有临时授权,则将无法发送通知。

2. 安装的应用的影响

在搭载 Android 13 的设备上安装应用,应用的通知默认处于关闭状态。在请求新的权限且用户向应用授予该权限之前,应用都将无法发送通知。

权限对话框的显示时间取决于应用的目标 SDK 版本:

 ●  应用targetSdkVersion为33或者更高版本时,应用将可以完全自行控制权限对话框的显示时间。应用可以借此机会向用户说明应用需要此权限的原因,进而鼓励他们授予该权限。

 ●  应用targetSdkVersion低于33时,系统会在应用创建第一个通知渠道时显示权限对话框。这通常是在应用启动时。

3. 对已安装应用的影响

为最大限度地减少与新通知权限相关的中断,系统会自动向系统升级前用户设备上已安装的所有符合条件的应用临时授予新通知权限。此临时授权的持续时间取决于应用的目标 SDK 版本:

 ●  如果应用targetSdkVersion为33或者更高版本时,则临时授权将持续到应用首次启动 activity 为止。

     应用可以完全自行控制权限对话框的显示时间。应用可以借此机会向用户说明应用需要此权限的原因,进而鼓励他们授予该权限。

 ●  如果应用targetSdkVersion低于33时,则临时授权将一直有效,直到用户在通知权限运行时对话框中明确选择一个选项。也就是说,如果用户在未做出选择的情况下关闭了权限提示,系统会保留应用的临时授权。

影响范围:运行于Android 13上的所有应用。

适配建议:

1. 更新应用的目标 SDK 版本。

2. 等待一段时间再显示通知权限提示。等到用户熟悉您的应用之后,再请求他们授予任何权限。新用户可能想要探索您的应用,并切身体会每项通知请求可以带来的好处。

3. 在上下文中请求权限。在应用内请求通知权限时,请在正确的上下文中请求,以便用户明确了解通知的用途以及应该选择接收通知的原因。

4. 检查您的应用能否发送通。用户必须为应用启用通知,应用才能发送通知。要确认用户是否已启用通知,请调用 areNotificationsEnabled()。

5. 以负责任的方式使用权限。获得发送通知的许可后,请负责任地使用该权限。用户可以查看您的应用每天发送的通知数量,并且可以随时撤消该权限。

1.4.2 针对附近 Wi-Fi 设备的新运行时权限

说明:在以前的 Android 版本中,用户需要向应用授予 ACCESS_FINE_LOCATION 权限,应用才能完成与热点相关的多个常见 Wi-Fi 用例、Wi-Fi 直连、Wi-Fi RTT 等。

由于用户很难将位置信息权限与 Wi-Fi 功能相关联,因此 Android 13 在 NEARBY_DEVICES 权限组中引入了新的运行时权限,适用于管理设备与附近 Wi-Fi 接入点连接情况的应用。此权限 (NEARBY_WIFI_DEVICES) 可满足这些 Wi-Fi 用例。

只要应用不会通过 Wi-Fi API 推导物理位置,那么当targetSdkVersion为33或更高版本的应用使用Wi-Fi API时,就可以请求 NEARBY_WIFI_DEVICES 而不是 ACCESS_FINE_LOCATION。

影响范围:targetSdkVersion为33的应用。

1.4.3 在后台使用身体传感器需要新的权限

说明:Android 13 中引入了“在使用时”访问身体传感器(例如心率、体温和血氧饱和度)的概念。如果应用targetSdkVersion为33并且在后台运行时需要访问身体传感器信息,那么除了现有的 BODY_SENSORS 权限外,还必须声明新的 BODY_SENSORS_BACKGROUND 权限。

影响范围:targetSdkVersion为33的应用。

1.4.4 intent 过滤器会屏蔽不匹配的 intent

说明:当应用向targetSdkVersion为33或更高版本的其他应用的导出组件发送 intent 时,仅当该 intent 与接收应用中的 <intent-filter> 元素匹配时,系统才会传送该 intent。系统会屏蔽所有不匹配的 intent,以下情况除外:

 ●  发送给其他应用的未声明任何 intent 过滤器的组件的 intent。

 ●  发送给应用中的其他组件的 intent。

 ●  由系统发送的 intent。

 ●  由具有根级特权的用户发送的 intent。

影响范围:targetSdkVersion为33的应用。

1.4.5 更安全地导出上下文注册的接收器

说明:为了帮助提高运行时接收器的安全性,Android 13 允许指定应用中的特定广播接收器是否应被导出以及是否对设备上的其他应用可见。如果导出广播接收器,其他应用将可以向应用发送不受保护的广播。

在以前的 Android 版本中,设备上的任何应用都可以向动态注册的接收器发送不受保护的广播,除非该接收器受签名权限的保护。要实现此安全增强措施,请执行以下操作:

 ●  启用 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED 兼容性框架更改。

 ●  在应用的每个广播接收器中,明确指明其他应用是否可以向其发送广播。

注意:如果启用了 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED 兼容性框架更改,则必须为每个广播接收器指定 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED。否则,当注册广播接收器时,系统会抛出 SecurityException。

影响范围:targetSdkVersion为33的应用。

1.4.6 可主动降级的权限

说明:从 Android 13 开始,应用可以撤消先前由系统或用户授予的运行时权限。此 API 可以帮助应用保护用户的隐私。如需撤消特定运行时权限,请将该权限的名称传入 revokeOwnPermissionOnKill()。如需同时撤消一组运行时权限,请将这组权限的名称传入 revokeOwnPermissionsOnKill()。撤消是异步发生的,会终止与应用的 UID 相关联的所有进程。

系统只有在安全的情况下才会触发撤消操作。当有应用组件仍在前台运行,或者有另一个应用正在访问应用的组件时,不会发生撤消。如果想立即撤消权限,可以调用 exit()。但是,对 exit() 进行此类调用可能会导致当前正在访问应用的其他应用出现未定义的行为或崩溃。

1.4.7 使用精确闹钟的新权限

说明:应用可以使用自动授予应用的 USE_EXACT_ALARM 权限。不过,应用若要使用此权限,必须至少满足以下条件之一:

1.应用是闹钟应用或计时器应用。

2.应用是日历应用,可显示即将进行的活动的通知。

即将推出的 Google Play 政策会阻止应用使用 USE_EXACT_ALARM 权限,除非应用满足前面列表中显示的任一情况。

影响范围:targetSdkVersion为33的应用。

1.4.8 精细媒体权限

说明:如果应用以 Android 13 为目标平台,则必须请求一项或多项新权限,而不是 READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE 权限。

请求的权限集取决于您的应用需要访问的媒体类型:

媒体类型请求许可
图片和照片READ_MEDIA_IMAGES
视频READ_MEDIA_VIDEO
音频文件READ_MEDIA_AUDIO

如果用户之前授予应用READ_EXTERNAL_STORAGE权限,系统会自动将每个新权限授予您的应用。否则,当应用请求上表中显示的任何权限时,系统会显示一个面向用户的对话框。在下图 中,应用程序请求READ_MEDIA_AUDIO权限。如果同时请求 READ_MEDIA_IMAGES权限和READ_MEDIA_VIDEO权限,则只会出现一个系统权限对话框。

2. 参考链接

[1]Android 13开发者预览版:https://developer.android.com/about/versions/13/overview

vivo Android 13 开发者体验版

1、计划概览

欢迎加入vivo Android 13 开发者体验版,此计划将给开发者提供适配 Android 13系统的体验。

注:vivo Android 13 开发者体验版本仅面向开发者,极客用户,对于普通用户,我们强烈建议不要使用。

● 硬件和系统

开发者体验版本可以在iQOO 10、iQOO 10 Pro、X80 Pro设备系统上运行并体验。

● 开发和测试

如果您在vivo Android 13 开发者体验版本进行开发和测试工作, 您将可以针对新的软件变更测试您的应用,请参阅迁移指南,了解让应用与新平台兼容的简单步骤。更多详细的Android 13 相关的介绍,点击这里

感谢您加入vivo Android 13 开发者体验版!

2、获取vivo Android 13 开发者体验版

您可以通过如下方式下载使用iQOO 10、iQOO 10 Pro、X80 Pro设备的软件包固件,然后升级测试自己的应用。

注意:为避免在vivo设备上安装开发者体验版出现异常,升级前请务必先备份数据。

2.1 下载Android 13 开发者体验版

如下升级包下载链接:

设备下载链接MD5校验值
iQOO 10PD2217_A_13.1.7.10.W10.V000L1-update-full.zipd60e54b4ab3d3562f1a15f11d800f2c7
iQOO 10 ProPD2217_A_13.1.7.10.W10.V000L1-update-full.zipd60e54b4ab3d3562f1a15f11d800f2c7
X80 ProPD2185_A_13.0.12.6.W10.V000L1-update-full.zip594caad95190b4454b3237359186df26

2.2 升级Android 13 开发者体验版

您可以将下载到的开发者体验版本软件包固件,按照以下步骤,烧写到对应的vivo设备。手动烧写固件的步骤以X80 Pro为例,具体如下:

(1)下载X80 Pro开发者体验版本软件包固件。

(2)设备连接电脑后将手机USB设置切换到文件传输模式,将已下载好的软件包固件拷贝到X80 Pro手机存储根目录。

(3)按照以上步骤,在设置->系统升级->本地升级中点击升级包,待校验完成后开始升级。

(4)等待手机自动升级完成。

2.3 回退Android 13 开发者体验版

如果您已经手动升级到iQOO 10、iQOO 10 Pro、X80 Pro的开发者体验版,想对应降级到Android 12.0正常系统版本,请使用降级工具进行降级工作,具体请参考:

https://bbs.vivo.com.cn/newbbs/thread/32215628?show_title=1

3、反馈

如果您在使用中遇到严重问题,请进入对应的群进行反馈,群验证信息请填写手机的IMEI号

iQOO 10、iQOO 10 Pro QQ群 : 854374916

X80 Pro QQ群 : 759578505

4、Android 13 特性:

新增特性功能,包括但不限于:

  • 照片选择器

提供了一种更安全的媒体共享方式,而无需向应用授予整个媒体库的访问权限。

  • 控制中心

允许应用主动添加开关至控制中心,方便用户便捷地添加应用的控制中心开关。

  • 前台服务管理器

新增 前台服务管理功能,您可以通过控制中心查看运行中的前台服务及服务的运行时长,并随时停用前台服务。

5、已知问题

iQOO 10、iQOO 10 Pro:

1、当前系统版本有较多常用三方应用与 Android 13 不兼容,升级后可能会出现第三方应用无法正常使用的情况(如闪退、卡顿、黑屏、耗电等),建议您谨慎升级。

2、下拉状态栏,低概率背景透明,自动恢复。

3、健康APP概率定位异常,无法形成轨迹。

4、部分应用未同步深色模式。

X80 Pro:

1、当前系统版本有较多常用三方应用与 Android 13 不兼容,升级后可能会出现第三方应用无法正常使用的情况(如闪退、卡顿、黑屏、耗电等),建议您谨慎升级。

2、部分系统弹框主题样式不一致

3、分屏时,移动分屏,存在低概率性动画不连贯,出现黑屏

4、连续快速多次人像拍摄时,手机相机出现低概率的闪退