【Android 碎屑日记(一)】- Android 14 重要的 8 个新特性


知识回顾

前言

一年一度的 Android 升级永不缺席,今年的代号叫 Upside Down Cake,倒置蛋糕,简称 U,对外版本为 Android 14。升级任务分为 ROM 角度和 App 角度,前者比较关心系统内部实现的变化,后者则更加关心对外的 New Features 和 Behavior Changes。


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 安装的时候即被授予。

需要注意的是,该 API 只能监听电源键方式发起的截屏时机,无法监听到 adb、代码等方式发起的截屏,毕竟它不算是用户的操作。而且不会将截图带过来,App 如果需要图片数据的话,仍需要去读取。

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)
     }         
}

2.TextView Highlight

14 里针对这个痛点提供了专门的 API 即 HighLights,提供了更加简单、灵活的实现。

首先,支持静态设置高亮:

通过 Highlights.Builder 构建 HighLights 对象
通过 addRange() 设置 Paint 和对应 Range 数组即可
通过 TextView 新方法 setHighLights() 反映高亮

其次,支持动态设置高亮:

调用新方法 getHighLights() 获取已有 HighLights 实例
更改其 Paint 和 Range 属性
调用 invalidate 动态更新高亮

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
             }
         }
     }
 }

3.New System Back Design

相比以往版本增加了更美观的属性设置,不过通用的app端还是由我们美丽的UI设计师来决定什么样的返回按钮,所以对我们来说使用不太多。

4.Custom Action on Share Sheet

分享界面的呈现由 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)
    }
}


5. Locale Preferences

6. Grammar Gender

7. Path Iterator

8. Package Installer improvement

总结

添加专用 ScreenShotCallback 来规范监听截屏的开发方式
添加全新 API 来简化 Hightlight 的实现方式
重新设计 Back Arrow 和支持目标界面的预览 Predictive Back Preview 来统一、加强 Android 平台上 Back 导航的体验
支持 Custom Share Action 的标准分享,来满足丰富、灵活的分享需求
引入全新的区域设置 Locale Preferences 来改善用户习惯的体验
引入全新的、独立的语法性别 Grammar Gender 来提高文本表述的准确度
引入特定 API Path Interator 来方便开发者对 Path 历史进行回溯
通过改善 Package Installer 来全方位提升 App 安装、更新方面的细节体验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值