一年一度的 Android 晋级永不缺席,今年的代叫喊
Upside Down Cake
,倒置蛋糕,简称U
,对外版别为 Android 14。
一般来说,晋级任务分为 ROM 视点和 App 视点,前者比较关怀体系内部完成的改变,后者则愈加关怀对外的 New Features 和 Behavior Changes。本文首要聚集在 App 视点,即作为 3rd Party App 怎么去看待 14 体系晋级。由于晋级内容过于庞杂,本次先介绍 New Features 部分,原因是作为 New Features、很容易被我们忽略,实则更重要。
理由是 New Features 不像 Behavior Changes:OS 晋级之后假如运转上出了问题,调查下文档就知道 14 改变了什么、怎么改。而 New Features 作为新的功用、API,并不会影响 App 本来的逻辑,但实真实在地解决了痛点、优化了体会、供给了一个又一个特色才干,从长远来讲是更有价值的。
假如开发者总是忽略 New Features 部分,那么 App 难免停留在旧的完成上、旧的计划上,OSV 工作也变成了改一改、能跑就行的被动晋级。建议我们在关注 Behavior Changes 以外多留心下 New Features 是否能够改进现有的计划,优化产品体会。
14 推出的新 API,大部分我都试过,并开源了 DEMO。本文将从规划的理由、运用解读等视点,带我们切实感受这重要的 8 个新特性:
- ScreenShot Detection,截屏感知
- TextView Highlight,文本高亮
- New System Back Design,全新的体系回来规划
- Custom Action on Share Sheet,支撑自定义操作的体系共享
- Locale Preferences,区域偏好
- Grammar Gender,语法性别
- Path Iterator,途径迭代器
- Package Installer improvement,装置改进
1.ScreenShot Detection
部分 App 常常需求监听用户的截屏操作,进行发送反馈的提示等,往常是运用哪些手段来完成呢?
一般来说,开发者会经过监听寄存截屏文件的媒体目录的改变来迂回完成,这往往需求 Runtime 等级的读写权限,并且稍有不慎还或许牵扯到隐私问题。
那么 Android 14 为了规范这种开发需求,推出了专用 API,即 ScreenShotCallback
。它无需无需 Runtime 等级的读写权限,声明专用权限即可,在 App 装置的时分即被授予:
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
运用的办法来说,以 Activity
为单位进行注册和刊出截屏 ScreenCaptureCallback。并且建议在 onStart() 里注册、onStop() 里刊出。
class ScreenShotActivity : AppCompatActivity() {
private val screenCaptureCallback = ScreenCaptureCallback {
// 提示用户等操作
AlertDialog.Builder(this).show()
}
override fun onStart() {
super.onStart()
registerScreenCaptureCallback(mainExecutor, screenCaptureCallback)
}
override fun onStop() {
super.onStop()
unregisterScreenCaptureCallback(screenCaptureCallback)
}
}
如下的截图能够看到,利用该 API 成功地监听到了截屏操作,并执行了预期的 Dialog 提示。
需求留心的是,该 API 只能监听电源键办法建议的截屏机遇,无法监听到 adb、代码等办法建议的截屏,毕竟它不算是用户的操作。并且不会将截图带过来,App 假如需求图片数据的话,仍需求去读取。
相关文章引荐:Android 14 新 API:直接监听截屏操作,不必再调查媒体文件了~
2.TextView Highlight
HighLights API
对于做 Mail、SMS、Note 类的 App 难免遇到设置文本 Highlight 的需求,而传统的完成办法无非是 Spannable
。但这种办法的代码稍显杂乱、并且无法便利地更新高亮。
那么 14 里针对这个痛点供给了专门的 API 即 HighLights
,供给了愈加简略、灵敏的完成。
首要,支撑静态设置高亮:
1. 经过 Highlights.Builder 构建 HighLights 方针
2. 经过 addRange() 设置 Paint 和对应 Range 数组即可
3. 经过 TextView 新办法 setHighLights() 反映高亮
其次,支撑动态设置高亮:
- 调用新办法 getHighLights() 获取已有 HighLights 实例
- 更改其 Paint 和 Range 特点
- 调用 invalidate 动态更新高亮
经过如下的代码进行黄色和绿色的静态高亮设置,以及点击 Button 之后动态更新绿色高亮为深蓝色高亮:
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
...
val greenPaint = Paint().apply {
color = Color.GREEN
}
with(binding.textview1) {
text = TEXT
val builder = Highlights.Builder()
.addRange(yellowPaint, 0, 3)
.addRange(greenPaint, 14, 24)
.addRange(greenPaint, 25, 32)
highlights = builder.build()
}
binding.changeHighlights.setOnClickListener {
Log.d("HighLights", "changeHighlights tapped & change highlights")
textView1Highlights?.apply {
// Change color
getPaint(1).color = Color.BLUE
// Change ranges
getRanges(1)[0] -= 3
getRanges(1)[1] += 1
for (i in 0 until size) {
Log.d("HighLights", "textView1Highlights'" +
" paint:${getPaint(i).color.toColorString()}")
val range = getRanges(i)
for (j in range.indices) {
Log.d("HighLights", "ranges:${range[j]}")
}
}
}
binding.textview1.invalidate()
}
}
}
下图能够看到,经过 HighLights API 成功地设置了黄色和绿色的高亮。并且在点击 CHANGE button 之后,动态更改了上面 TextView HighLights 的色彩为蓝色。
或许有人会问这个 HighLights API 能自适应多言语吗?
答案是 NO,事实上 HighLights API 和多言语无关,不同言语下要自行处理方针高亮的 range。
相关文章引荐:Android 14 新功用之 HighLights:快速完成文本高亮~
Search Highlight
除了一般的高亮以外,Android 14 还推出了针对查找的高亮 API,首要是运用如下 TextView 的相关新办法:
-
searchResultHighlightColor
设置查找匹配到的高亮 -
focusedSearchResultHighlightColor
设置聚集到的高亮 -
setSearchResultHighlights
设置查找到的文字 range -
focusedSearchResultIndex
针对查找焦点高亮和移动,index 常量:- -1:没有开端查找/查找不到成果
- 0:匹配到查找成果
- 1:聚集到某个查找成果
如下代码设置匹配到查找关键字的高亮为水蓝色,聚集到该匹配的高亮是灰色,并用 search button 模仿匹配到的文字 range、forward button 模仿查找焦点的移动。
class TextViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
with(binding.textview2) {
searchResultHighlightColor = Color.CYAN
focusedSearchResultHighlightColor = Color.GRAY
}
// 模仿查找按钮
binding.startSearch.setOnClickListener {
binding.textview2.run {
Log.d("HighLights", "startSearch tapped" +
" and current search Color:${searchResultHighlightColor.toColorString()}"
)
// set searching ranges
setSearchResultHighlights(4, 11, 25, 32)
}
}
binding.changeSearchIndex.setOnClickListener {
binding.textview2.run {
// Set index to first or second
val newSearchIndex = when (focusedSearchResultIndex) {
TextView.FOCUSED_SEARCH_RESULT_INDEX_NONE, 1 -> 0
0 -> 1
else -> TextView.FOCUSED_SEARCH_RESULT_INDEX_NONE
}
binding.textview2.focusedSearchResultIndex = newSearchIndex
}
}
}
}
如下的 GIF 能够看到,匹配到查找的时分,文本色彩变成了水蓝色,当聚集到该匹配之后变成灰色,默许情况下这是无高亮。
相关文章引荐:Android 14 新功用之 TextView 查找成果高亮和焦点移动~
3.New System Back Design
随着屏幕越来越大,交互办法的愈加多元、灵敏,传统的 Back 按键、虚拟键显得越来越冗余。那么怎么简化回来操作、一致回来的开发就显得尤为重要。
New Back Arrow
事实上,自 Android 13 开端即针对 Back 事情的处理进行了一致,想要运用该新特性的好,首要需求做两个设置:
- Manifest 中敞开
enableOnBackInvokedCallback
- 注册完成 Back 逻辑的
OnBackInvokedCallback
到 Activity 中
Android 14 针对体系的 Back 效果进行了进一步的晋级,榜首块则是优化 arrow,包含:
- 增加了 Arrow 边框、布景,愈加明显
- 自适应体系
Material Design
主题,theme 改变的同时 Arrow 的布景色跟着刷新:
如下的比照,能够看到 14 的体系回来 Arrow 相对 13 愈加和谐、明晰。
Predictive Back Preview
第二块便是增加回来预览,让用户能够提前检查方针界面,决定取消或继续回来操作。而这块功用尚在完善傍边,需求体会首要得在开发者选项中手动敞开。
- 设置 > 体系 > 开发者选项 > 预测性回来手势动画(Predictive back animation)
如下 GIF 即能够看到 Back 手势触发后,App 全体缩小、反面画面展现的预览效果。
相关文章引荐:Android 14 之回来界面晋级:预览方针界面 + 全新回来箭头
4.Custom Action on Share Sheet
现在 App 生态越来越丰厚,数据共享也变得极为需求。一般来说,共享界面的出现由 App 的适配以及体系的调度有关。可是许多愈加细节、详细的操作,体系或 App 或许无法及时 cover,这时分支撑自定义的共享操作就显得十分必要。
Android 14 里新增了 ChooserAction
类,当用 Android ShareSheet
创立规范的共享界面时,能够用该 Class展现的自定义操作和信息,来供给更丰厚的共享菜单:
-
运用
ChooserAction.Builder
创立自定义 ChooserAction- 指定 Icon
- 指定 title
- 指定共享菜单点击后方针的
PendingIntent
类型的 Action
-
运用 Intent#createChooser() 创立规范的 Chooser Intent
-
放置 ChooserAction 实例到 key 为
EXTRA_CHOOSER_CUSTOM_ACTIONS
的 Bundle 中- 留心,此处的入参是 ChooserAction 数组,由于能够一次支撑多个自定义操作
如下的代码展现了设置自定义共享的规范写法:
class ShareSheetActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val pendingIntent: PendingIntent =PendingIntent.getActivity(
this@ShareSheetActivity,
0,
Intent(Intent.ACTION_WEB_SEARCH).apply {
putExtra(SearchManager.QUERY, "Search on web .")
},
PendingIntent.FLAG_IMMUTABLE
)
val chooserAction = ChooserAction.Builder(
Icon.createWithResource(this@ShareSheetActivity, R.drawable.ic_launcher_foreground),
"Send to Ellison",
pendingIntent
).build()
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, arrayOf(chooserAction))
startActivity(shareIntent)
}
}
下图能够看到在体系默许的 Copy 旁边多出了一个 Send to Ellison 的自定义共享项,点击之后将执行预设的 PendingIntent 的 action。
相关 API 文档:
- developer.android.com/reference/a…
- developer.android.com/reference/a…
- www.droidcon.com/2023/04/18/…
5.Locale Preferences
有适当部分的一群人运用的设备言语和他的日常习惯是不同的。比方想要学习英语的人或许将体系言语设置成英语,但会形成不少费事,比方日历 App 会变成公历类型,没了阴历、也没了节假日调休标记、一周首日还变成了周日,着实不太便利。
那么 Android 14 推出的区域偏好设置能够帮 App 改进用户的这个体会。
Android 14 能够供用户在体系言语以外独立地设置地区偏好:设置诸如温度单位、一周首日、日历类型、小时周期等类型。下图能够看到区域偏好的设置入口。
对 App 来说,只需求运用新 API LocalePreferences
中供给的办法,获取体系的区域偏好做适配即可:
- getTemperatureUnit() 获取温度单位偏好,是摄氏仍是华氏单位
- getFirstDayOfWeek() 获取一周首日偏好,是从周一仍是周日开端
- getHourCycle() 获取小时周期偏好,是 12 小时制仍是 24 小时制,12 小时制还包含 0~11、1~12 两种,24 小时制还包含 0~23、1~24 两种
- getCalendarType() 获取日历类型偏好,是公历仍是阴历等
别的需求提示一点,现在的 LocalePreferences API 没有集成到 AOSP SDK 中,需求导入 AndroidX SDK。
dependencies {
implementation "androidx.core:core:1.12.0-alpha04"
}
相关文章引荐:Android 14 新功用:区域偏好 Regional Preferences
6.Grammar Gender
如同汉语里的他、她、它,英语里的 He、She、it 相同,许多言语都存在根据性别不同、方针不同而形成的语法差异,乃至不仅限于名词,还涉及到形容词、动词等,杂乱得多。而这部分言语的运用人群多达 30 亿,假如 App 文本只运用通用的、中性的表述,则显得不行准确。倘若不加区分,乃至对女性运用男性化的表述办法,则体会更为糟糕。
所以假如 App 的界面言语能正确反映用户的语法性别,则就能够进步用户好感度、互动度,到达更个性化、更自然的用户体会。
这便要说到 Android 14 推出的重要新特性:语法性别 Grammar Gender。详细的,Android 14 新增了专用的语法性别 API:GrammaticalInflectionManager
,用其能够获取和设置针对单个 App 的性别偏:
-
getApplicationGrammaticalGender()
:获取语法性别偏好,回来的是Configuration
类中的 int 型常量,有这么几种类型:- GRAMMATICAL_GENDER_NOT_SPECIFIED, 0:没有指定性别偏好,将用默许的 values 资源
- GRAMMATICAL_GENDER_NEUTRAL, 1:指定中性、客观的资源文本,比方 values-fr 资源
- GRAMMATICAL_GENDER_FEMININE, 2:指定针对女性的资源文本,比方 values-fr-feminine 资源
- GRAMMATICAL_GENDER_MASCULINE, 3:指定针对男性的资源文本,比方 values-fr-masculine 资源
-
setRequestedApplicationGrammaticalGender()
:将上述常量类型动态设置到性别偏好
动态设置 Gender 偏好之后,Activity 会发生重绘,由于它本质上也属于 Configuration 的范畴。为了防止这种重绘,14 也供给了针对该特性的专用装备改变 attr:grammaticalGender,能够在 Manifest 中装备。
<manifest ...>
<application...>
<activity
...
android:configChanges="grammaticalGender">
</activity>
</application>
</manifest>
接着,能够在 onConfigurationChanged()
里获取新的语法性别文本,手动刷新方针 TextView 的展现。
class GenderActivity : AppCompatActivity() {
override fun onConfigurationChanged(newConfig: Configuration) {
// Resources will be updated with new configuration
val newText = resources.getString(R.string.example_string)
Log.d("Gender", "onConfigurationChanged()" +
" new text:${resources.getString(R.string.example_string)}"
)
binding.textview.text = newText
}
}
如下的 GIF 显现了 GrammarGender 改变之后,针对性别的表述也在主动刷新,且没有发生闪烁。
相关文章引荐:Android 14 新特性:语法性别 Grammatical Gender
7.Path Iterator
部分开发者运用过 Path API 执行移动、连线等操作去制作曲线、动画,但你无法去回溯某个 Path 实例到底进行了多少操作,没有这样的 API,真实需求的话,你得自行缓存和管理这些操作数据。
Android 14 针对此痛点新增了 PathIterator
类。
运用办法很简略,经过 Path 的新办法 getPathIterator()
取得 PathIterator 实例,接着逐一遍历 Path 改变片段 Segment
,能够查询 Path 的操作前史以及各 Point 数据:
-
getVerb()
- PathIterator.VERB_MOVE,0
- PathIterator.VERB_LINE,1
- PathIterator.VERB_QUAD,2
- PathIterator.VERB_CONIC,3
- PathIterator.VERB_CUBIC,4
- PathIterator.VERB_CLOSE,5
- PathIterator.VERB_DONE,6
-
getPoints()
如下代码展现了获取途径迭代器和打印其信息的示例。
class PathActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val path = Path().apply {
moveTo(1.0f, 1.0f)
lineTo(2.0f, 2.0f)
close()
}
val pathIterator = path.pathIterator
for (segment in pathIterator) {
Log.i("Path", "segment action: ${segment.verb.toPathAction()}")
for (f in segment.points) {
Log.i("Path", "point: $f")
}
}
}
...
}
相应的打印信息如下:
2023-06-24 Path I segment action: VERB_MOVE
2023-06-24 Path I point: 1.0
2023-06-24 Path I point: 1.0
...
2023-06-24 Path I segment action: VERB_LINE
2023-06-24 Path I point: 1.0
2023-06-24 Path I point: 1.0
2023-06-24 Path I point: 2.0
2023-06-24 Path I point: 2.0
...
2023-06-24 Path I segment action: VERB_CLOSE
2023-06-24 Path I point: 1.0
...
相关 API 文档:
- developer.android.com/reference/a…
8.Package Installer improvement
Request install approval before downloading
前期的 Android 版别里针对需求装置 APK 的 App 推出了 REQUEST_INSTALL_PACKAGES
权限,但要比及下载完成、装置 Session
建议之后,该装置权限的赞同 Dialog 才会被 PackageInstaller
弹出。这显得稍稍滞后,由于假如用户终究拒绝装置,前面的下载流量和等待时间能够说是浪费了。
那么 PackageInstaller 则推出新办法来规避这个漏洞,即 requestUserPreapproval()
:
- 可让 App 在提交下载/装置之前,请求用户赞同、取得授权
- 用户赞同后,App 可在后台下载并装置使用,不会再次搅扰用户。
requestUserPreapproval(
PackageInstaller.PreapprovalDetails details,
IntentSender statusReceiver
)
requestUserPreapproval 函数接收如下两个参数,需求留心一下:
-
PreapprovalDetails
,新增的预授权的信息 Class,由 PreapprovalDetails.Builder 构建,需求指定预装置的 App 的 Icon、名称、包名等细节 -
IntentSender
,当授权经过过用来建议装置 Session 的 Sender
相关 API 文档:
- developer.android.com/reference/a…
Claim responsibility for future updates
装置相关的第 2 个新特性叫做 Claim responsibility for future updates,什么意思呢?
许多用户的 Android 设备中很或许不止一个使用商场,当装置了一个 App 之后,其他的商场或许提示 App 有可用更新,可是跟装置源头不相同的话,或许存在不兼容、不正规等危险。
那么凭借 Android 14 新的 setRequestUpdateOwnership()
办法,装置程序能够向体系表明它打算担任将被装置的使用未来的更新,那么体系将仅允许该商场为使用主动装置更新。
此特权需求声明专用的 permission:
- android.permission.ENFORCE_UPDATE_OWNERSHIP,也是 normal 等级,装置即被授予
此后,假如其他装置程序想要担任该 App 的更新都必须取得用户的清晰赞同,才干进行。一旦用户赞同了从其他来历装置更新,那么元商场将失去主动更新的所有权。
相关 API 文档:
- developer.android.google.cn/reference/a…
- developer.android.google.cn/reference/a…
Update apps at less-disruptive times
装置相关的第 3 个新特性叫做:Update apps at less-disruptive times。
假运用户敞开了主动更新或许手动更新一堆 App 的途中,碰巧在运用其中的某个 App,那么该 App 的进程很有或许会被更新打断、操作停止,严重的还会导致编辑中的数据发生丢失。
为了防止由于更新导致正在运转的使用进程被停止这种差的体会,Android 14 引进了装置束缚 InstallConstraints
API 让装置程序能够保证其使用更新在适当的机遇进行。
- 运用 InstallConstraints.Builder 构建,设置诸如是否要求不在前台
setAppNotForegroundRequired()
、是否要求设备在 IDLE 状态setDeviceIdleRequired()
、是否要求设备不在通话中setNotInCallRequired()
等等 - 接着调用 PackageInstaller 的新办法
commitSessionAfterInstallConstraintsAreMet()
传入上述 InstallConstraints 装备实例,来保证仅在用户不再与相应使用进行束缚条件的互动时才进行更新
相关 API 文档:
- developer.android.com/reference/a…
结语
至此,已经介绍完了这 8 个重要的 Android 14 新特性,能够看到 Android 发展到 14 这么老练的版别,仍是不忘关注用户体会上的细节、开发办法的痛点:
- 增加专用
ScreenShotCallback
来规范监听截屏的开发办法 - 增加全新 API 来简化
Hightlight
的完成办法 - 从头规划
Back Arrow
和支撑方针界面的预览Predictive Back Preview
来一致、加强 Android 平台上 Back 导航的体会 - 支撑
Custom Share Action
的规范共享,来满意丰厚、灵敏的共享需求 - 引进全新的区域设置
Locale Preferences
来改进用户习惯的体会 - 引进全新的、独立的语法性别
Grammar Gender
来进步文本表述的准确度 - 引进特定 API
Path Interator
来便利开发者对 Path 前史进行回溯 - 经过改进
Package Installer
来全方位提升 App 装置、更新方面的细节体会
全体上来说这几个新特性比较简略、易懂,但仍是建议我们去测验,便于在开发相应需求的时分,记得 Android 14 官方有个新特性能够适用。
Android 14 Sample
github.com/ellisonchan…
相关技术文章
- Android 14 之回来界面晋级:预览方针界面 + 全新回来箭头
- Android 14 新功用之 TextView 查找成果高亮和焦点移动~
- Android 14 新功用之 HighLights:快速完成文本高亮
- Android 14 新 API:直接监听截屏操作,不必再调查媒体文件了
- Android 14 新特性:语法性别 Grammatical Gender
- Android 14 新功用:区域偏好 Regional Preferences
相关技术文档
- Android 14 主页
- Android 14 New Features