我们好,好久不见,从去年底写完年终总结之后就再也没有更新过文章,之前最多也就距离一两个月时刻,但这回距离时刻确实有点长,根本快半年了!也没有别的原因,便是工作太忙了。。。好了,废话不多说,开端今天的主题吧!

三年前写了一篇文章:安卓11来了,快!扶我起来,然后 Android 12 由于工作原因没有时刻写,之后去年又写了一篇文章:安卓13来了,快!扶起我来!时刻真的过的太快了,转眼间 Android 14 又来了,还是简略来看看我们安卓开发者需求留意些什么吧!

怎么获取 Android 14?

Android 14 又来了?别扶!抬起我来吧!

官方供给有三种办法:

  • 在 Google Pixel 设备上获取 Android 14
  • 设置 Android 模拟器
  • 获取通用体系映像 (GSI)

这三种都挺好了解:假如你有 Pixel 的话(比较新的设备,老的不支撑,Pixel 4a (5G) 之后的能够),直接申请就能够;假如我们没有 Pixel 的话(大部分都没有),能够运用模拟器;最后一种是能够往设备中刷入 GSI,这个操作起来就比较复杂了,我们假如想搞一搞的话能够进官方文档看下:通用体系映像 (GSI)。

一切运用需留意

一般来说 Android 版别更新都会有两种行为改变:

1、一切运用都会受到的影响,即便你的运用没有将 TargetSDK 升级到 34(即 Android 14),但你的运用或许在 Android 14 的设备中运转,那么就需求你做的适配

2、将 TargetSDK 升级到 34,运用也在 Andorid 14 的设备中运转时需求你做的适配

这一个模块我们先来看第一个,即一切运用都需求做的适配。

默许回绝设定准确的闹钟

准确的闹钟适用于用户指定的告诉,或是在确切时刻需求履行的操作。从 Android 14 开端,体系不再向以 Android 13 及更高版别为方针渠道的大多数新装置运用预先颁发 SCHEDULE_EXACT_ALARM 权限,该权限默许处于回绝状况。

准确闹钟适用于用户指定的告诉,或是在确切时刻需求履行的操作。

SCHEDULE_EXACT_ALARM 是 Android 12 中引进的可让运用安排准确闹钟的权限,不再预先颁发以 Android 13 和更高版别为方针渠道的最新装置运用(默许情况下,设置为“回绝”)。假如用户经过备份和康复操作将运用数据转移到搭载 Android 14 的设备,则该权限依然会被回绝。假如现有运用已拥有此权限,则当设备升级到 Android 14 时,体系会预先颁发此权限。

需求 SCHEDULE_EXACT_ALARM 权限才干经过以下 API 发动准确闹钟,不然体系会抛出 SecurityException

  • setExact()
  • setExactAndAllowWhileIdle()
  • setAlarmClock()

留意: 假如运用 OnAlarmListener 方针设置准确闹钟(例如在 setExact API 中),则不需求 SCHEDULE_EXACT_ALARM 权限。

SCHEDULE_EXACT_ALARM 权限的现有最佳实践依然适用,其间包含:

  • 在安排准确闹钟之前,请运用 canScheduleExactAlarms() 检查权限。
  • 请将运用设置为监听并正确响应前台播送 AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,当用户颁发权限时体系会发送该播送。

日历或闹钟运用需求在运用中止运转时发送日历提示、唤醒闹钟或提示。这些运用能够恳求 USE_EXACT_ALARM 常规权限。体系将在装置时颁发 USE_EXACT_ALARM 权限,拥有此权限的运用将能够像具有 SCHEDULE_EXACT_ALARM 权限的运用相同安排准确闹钟。

当然,假如你的运用是体系运用,能够进行申请豁免。

当运用进入缓存时,上下文注册的播送将参加行列

在 Android 14 中,当运用处于缓存状况时,体系或许会将上下文注册的播送放入行列中。这与 Android 12(API 等级 31)为异步 binder 事务引进的行列行为相似。在清单中声明的播送不会参加行列,而且运用会从缓存状况中移除以进行播送传递。

当运用离开缓存状况(例如回来前台)时,体系会传递一切已参加行列的播送。某些播送的多个实例能够合并为一个播送。

运用只能中止自己的后台进程

从 Android 14 开端,当运用调用 killBackgroundProcesses() 时,该 API 只能中止自己运用的后台进程。

假如传入另一个运用的软件包称号的话,此办法对该运用的后台进程将没有任何影响,只会在 Logcat 中会显现以下音讯:

Invalid packageName: com.example.anotherapp

运用不该运用 killBackgroundProcesses() API,也不得以其他办法测验影响其他运用的进程生命周期,即便在旧版操作体系上也是如此。Android 旨在让缓存运用在后台运转,并在体系需求内存时主动中止它们。

最低可装置的方针 API 等级

从 Android 14 开端,targetSdkVersion 低于 23 的运用无法装置。要求运用满意这些最低方针 API 等级要求有助于进步用户的安全性和隐私性。

歹意软件通常会以较旧的 API 等级为方针渠道,以绕过在较新版别 Android 中引进的安全和隐私维护机制。例如,有些歹意软件运用运用 targetSdkVersion 22,以避免受到 Android 6.0 Marshmallow(API 等级 23)在 2015 年引进的运转时权限模型的约束。这项 Android 14 改变使歹意软件更难以规避安全和隐私权方面的改进约束。测验装置以较低 API 等级为方针渠道的运用将导致装置失败,而且 Logcat 中会显现以下音讯:

INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 7

在升级到 Android 14 的设备上,targetSdkVersion 低于 23 的一切运用都将继续保持装置状况。假如需求测验以旧版 API 等级为方针渠道的运用,请运用以下 ADB 指令:

adb install --bypass-low-target-sdk-block FILENAME.apk

媒体包称号或许会隐藏

媒体库支撑查询 OWNER_PACKAGE_NAME 列,该列表示存储特定媒体文件的运用。从 Android 14 开端,除非满意以下条件之一,不然体系会隐去此值:

  • 存储媒体文件的运用有一个软件包称号始终对其他运用可见。
  • 查询媒体库的运用会恳求 QUERY_ALL_PACKAGES 权限。

关于不行封闭告诉用户体会办法的改变

假如运用向用户显现不行封闭的前台告诉的话需求留意:Android 14 中答运用户封闭此类告诉。

这项改变适用于经过 Notification.Builder#setOngoing(true)NotificationCompat.Builder#setOngoing(true) 设置 Notification.FLAG_ONGOING_EVENT 来阻挠用户封闭前台告诉的运用。FLAG_ONGOING_EVENT 的行为已发生改变,运用户实践上能够封闭此类告诉。

在以下情况下,此类告诉仍不行封闭:

  • 当手机处于确认状况时
  • 假如用户挑选悉数铲除告诉操作(有助于避免意外封闭)

此外,这一新行为不适用于以下用例中的不行封闭告诉:

  • 运用 MediaStyle 创立的告诉
  • 安全和隐私用例的方针约束运用
  • 企业设备方针控制器 (DPC) 和支撑软件包

颁发对相片和视频的部分拜访权限

留意: 假如运用现已在运用相片挑选器,则无需履行任何操作即可支撑此改变。

在 Android 14 中,当运用恳求 Android 13(API 等级 33)中引进的任何视觉媒体权限时,用户能够颁发对其相片和视频的部分拜访权限:READ_MEDIA_IMAGESREAD_MEDIA_VIDEO

新对话框会显现以下权限选项:

  • 挑选相片和视频: Android 14 中的新功用。用户挑选期望供给给运用的详细相片和视频。
  • 悉数答应:用户颁发对设备上的一切相片和视频的完整拜访权限。
  • 不答应:用户回绝颁发一切拜访权限。

如需在运用中更妥善地处理此更改,请考虑声明新的 READ_MEDIA_VISUAL_USER_SELECTED 权限。详细了解怎么支撑用户颁发对其媒体库的部分拜访权限。

升级到 Android 14 需求做的适配

上面说了一切的运用在 Android 14 中需求做的适配,这儿来看下将 TargetSDK 升级到 Android 14 的运用需求做的适配吧!

前台服务类型

假如 TargetSDK 是 Android 14,则有必要为运用中的每个前台服务指定至少一个前台服务类型,体系期望具有特定类型的前台服务来满意特定的用例。下面列出了可供挑选的前台服务类型:

  • camera
  • connectedDevice
  • dataSync
  • health
  • location
  • mediaPlayback
  • mediaProjection
  • microphone
  • phoneCall
  • remoteMessaging
  • shortService
  • specialUse
  • systemExempted

下面来举一个栗子吧:

<manifest ...>
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
  <application ...>
   <service
     android:name=".MyMediaPlaybackService"
     android:foregroundServiceType="mediaPlayback"
     android:exported="false">
   </service>
  </application>
</manifest>

留意:Android 14为运转状况和远程音讯传递用例引进了前台服务类型。体系还为短期服务、特别用例和体系豁免保存新类型。假如以 Android 14 为方针渠道的运用未在清单中定义给定服务的类型,体系会在调用 startForeground() 时引发 MissingForegroundServiceTypeException

假如运用中的用例与这些类型中的任何一个都没有关联,官方主张我们运用 WorkManager 或用户主张的数据传输作业。

WorkManager 我们都运用过,但“用户主张的数据传输作业”又是个什么东西呢?

这是 Android 14 中 Google 引进的一个新 API,用于指定作业有必要是用户主张的数据传输作业。此 API 适用于需求由用户主张的继续时刻较长的数据传输,例如从远程服务器下载文件。这些类型的使命应运用由用户主张的数据传输作业。

留意: 假如现在针对网络数据传输运用景象运用的是 WorkManager,官方主张还是继续运用该库,而不是运用由用户主张的数据传输作业。

由用户主张的数据传输作业需求具备以下新权限才干运转:RUN_USER_INITIATED_JOBS。体系会主动颁发此权限(无需动态申请)。假如未在运用清单中声明此权限,体系会抛出 SecurityException

运转用户主张的数据传输作业的流程

如需运转用户主张的作业,请履行以下操作:

  1. 在清单中声明 RUN_USER_INITIATED_JOBS 权限:

    <manifest ...>
       <uses-permission android:name="android.permission.RUN_USER_INITIATED_JOBS" />
       <application ...>
         ...
       </application>
    </manifest>
    
  2. 构建 JobInfo 方针时,调用新的 setUserInitiated()setDataTransfer() 办法。还能够在创立作业时经过调用 setEstimatedNetworkBytes() 供给载荷巨细预算值:

    val networkRequestBuilder = NetworkRequest.Builder()
         .addCapability(NET_CAPABILITY_INTERNET)
         .addCapability(NET_CAPABILITY_VALIDATED)
    ​
    val jobInfo = JobInfo.Builder()
         // ...
         .setUserInitiated(true)
         .setDataTransfer(true)
         .setRequiredNetwork(networkRequestBuilder.build())
         .setEstimatedNetworkBytes(1024 * 1024 * 1024)
         // ...
         .build()
    
  3. 在运用可见时或在答应的条件列表中列出的条件下调度作业:

    val jobScheduler: JobScheduler =
         context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
    jobScheduler.schedule(jobInfo)
    
  4. 履行作业时,请确保对 JobService 方针调用 setNotification()。该值用于在使命管理器和状况栏告诉区域中告知用户作业正在运转:

    val notification = Notification.Builder(applicationContext, NOTIFICATION_CHANNEL_ID)
         .setContentTitle("My user-initiated data transfer job")
         .setSmallIcon(android.R.mipmap.myicon)
         .setContentText("Job is running")
         .build()
    ​
    class CustomJobService : JobService() {
      override fun onStartJob(params: JobParameters?): Boolean {
        setNotification(params, notification.id, notification,
            JobService.JOB_END_NOTIFICATION_POLICY_DETACH)
        // Do the job execution.
      }
    }
    

    留意: 假如未在短时刻内调用 setNotification(),则会导致运用呈现 ANR。

  5. 定期更新告诉,让用户了解作业的状况和进度。假如在安排作业之前无法确认传输巨细,请在知道传输巨细之后运用新的 API updateEstimatedNetworkBytes() 更新传输巨细。

  6. 履行完成后,调用 jobFinished() 以向体系标明作业已完成,或许应从头调度作业。

能够中止用户主张的数据传输作业

用户和体系都能够中止用户主张的传输作业。

由用户从使命管理器供给

用户能够中止显现在使命管理器中的用户主张的传输作业。

在用户按 Stop 时,体系会履行以下操作:

  • 立即中止运用的进程,包含正在运转的一切其他作业或前台服务。
  • 不针对任何正在运转的作业调用 onStopJob()
  • 阻挠从头调度用户可见的作业。

因而,主张在发布的作业告诉中供给控件,以便顺利中止和从头调度作业。

请留意,在特别情况下,Stop 按钮不会显现在使命管理器中的作业旁边,或许该作业根本不会显现在使命管理器中。

由体系供给

与常规作业不同,用户主张的数据传输作业不受运用待机形式存储分区配额的影响。可是,假如呈现以下任一情况,体系仍会中止作业:

  • 不再满意开发者定义的约束条件。
  • 体系确认该作业的运转时刻超出了完成数据传输使命所需的时刻。
  • 体系需求优先考虑体系运转状况,并因发热程度上升而中止作业。
  • 运用进程因设备内存不足而被中止。

体系中止作业(并非由于内存不足)时,体系会调用 onStopJob(),体系会在体系以为最佳的时刻重试作业。检查运用是否能够保存数据传输状况(即便未调用 onStopJob()),而且运用能够在再次调用 onStartJob() 时康复此状况。

答应安排用户主张的数据传输作业的条件

只要当运用处于可见窗口中或满意特定条件时,运用才干发动用户主张的数据传输作业。为确认何时能够安排用户主张的数据传输作业,体系会采用答应运用在特别情况下从后台发动 activity 的一组相同条件。值得留意的是,这组条件与后台发动的前台服务约束的豁免集不同。

上述阐明的例外情况包含:

  • 假如运用能够从后台发动 activity,则也能够从后台发动用户主张的数据传输作业。
  • 假如运用在最近用过屏幕上现有使命的回来堆栈中有 activity,单靠这一点并不答应运转用户主张的数据传输作业。

假如作业安排在答应的条件列表中未列出的其他时刻,则作业将失败并回来 RESULT_FAILURE 错误代码。

适用于用户主张的数据传输作业的约束条件

为了支撑在最佳时刻点运转的作业,Android 供给了为每种作业类型分配约束条件的功用。这些约束条件从 Android 13 开端就现已可用。

留意:下表仅比较了因作业类型而异的约束条件。如需了解一切约束条件,请参看 JobScheduler 开发者页面或工作约束条件。

下表显现了支撑给定作业约束条件的不同作业类型,以及 WorkManager 支撑的作业约束条件集。能够运用表格前的查找栏按作业约束办法的称号过滤表格。

以下是用户主张的数据传输作业答应运用的约束条件:

  • setBackoffCriteria(JobInfo.BACKOFF_POLICY_EXPONENTIAL)
  • setClipData()
  • setEstimatedNetworkBytes()
  • setMinimumNetworkChunkBytes()
  • setPersisted()
  • setNamespace()
  • setRequiredNetwork()
  • setRequiredNetworkType()
  • setRequiresBatteryNotLow()
  • setRequiresCharging()
  • setRequiresStorageNotLow()

OpenJDK 17 更新

Android 14 将继续更新 Android 的中心库,以与最新 OpenJDK LTS 版别中的功用保持一致,包含合适运用和渠道开发者的库更新和 Java 17 言语支撑。

以下改变或许会影响运用兼容性:

  • 对正则表达式的更改:现在,为了更严厉地遵从 OpenJDK 的语义,不答应无效的组引证。我们或许会看到 java.util.regex.Matcher 类抛出 IllegalArgumentException 的新情况,因而请有必要测验运用中运用正则表达式的景象。如需在测验期间启用或停用此改变,请运用兼容性结构工具切换 DISALLOW_INVALID_GROUP_REFERENCE 标志。
  • UUID 处理:现在,验证输入参数时,java.util.UUID.fromString() 办法会履行更严厉的检查,因而或许会在反序列化期间看到 IllegalArgumentException。如需在测验期间启用或停用此改变,请运用兼容性结构工具切换 ENABLE_STRICT_VALIDATION 标志。
  • ProGuard 问题:有时,在测验运用 ProGuard 减缩、混淆和优化运用时,增加 java.lang.ClassValue 类会导致问题。问题源自 Kotlin 库,该库会依据 Class.forName("java.lang.ClassValue") 是否会回来类更改运转时行为。假如运用是依据没有 java.lang.ClassValue 类的旧版运转时开发的,则这些优化或许会将 computeValue 办法从派生自 java.lang.ClassValue 的类中移除。

对隐式 intent 和待处理 intent 的约束

关于以 Android 14 为方针渠道的运用,Android 会经过以下办法约束运用向内部运用组件发送隐式 intent:

  • 隐式 intent 只能传送到导出的组件。运用有必要运用显式 intent 传送到未导出的组件,或将该组件标记为已导出。
  • 假如运用经过未指定组件或软件包的 intent 创立可变待处理 intent,体系现在会抛出反常。

这些改变可避免歹意运用拦截意在供运用内部组件运用的隐式 intent。

例如,下面是能够在运用的清单文件中声明的 intent 过滤器:

<activity
  android:name=".AppActivity"
  android:exported="false">
  <intent-filter>
    <action android:name="com.example.action.APP_ACTION" />
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

假如运用测验运用隐式 intent 发动此 activity,则体系会抛出反常:

// Throws an exception when targeting Android 14.
context.startActivity(new Intent("com.example.action.APP_ACTION"));

如需发动非导出的 activity,运用应改用显式 intent:

// This makes the intent explicit.
Intent explicitIntent =
    new Intent("com.example.action.APP_ACTION")
explicitIntent.setPackage(context.getPackageName());
context.startActivity(explicitIntent);

在运转时注册的播送接纳器有必要指定导出行为

以 Android 14 为方针渠道并运用上下文注册的接纳器的运用和服务有必要指定以下标志,以指明接纳器是否应导出到设备上的一切其他运用:RECEIVER_EXPORTEDRECEIVER_NOT_EXPORTED。此要求有助于运用 Android 13 中引进的这些接纳器的功用,来维护运用免受安全漏洞的影响。

仅接纳体系播送的接纳器的例外情况

假如运用仅经过 Context#registerReceiver 办法(例如 Context#registerReceiver())针对体系播送注册接纳器,那么它在注册接纳器时不该指定标志。

更安全的动态代码加载

假如运用以 Android 14 为方针渠道并运用动态代码加载 (DCL) 功用,则有必要将一切动态加载的文件标记为只读。不然,体系会抛出反常。官方主张运用尽或许避免动态加载代码,由于这样做会大大增加运用因代码注入或代码篡改而遭到侵略的危险。

假如有必要动态加载代码,请运用以下办法,在动态文件(例如 DEX、JAR 或 APK 文件)翻开并写入任何内容之前立即将其设为只读:

File jar = new File("DYNAMICALLY_LOADED_FILE.jar");
try (FileOutputStream os = new FileOutputStream(jar)) {
  // Set the file to read-only first to prevent race conditions
  jar.setReadOnly();
  // Then write the actual file content
} catch (IOException e) { ... }
PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);

处理已存在的动态加载文件

为避免体系对现有动态加载的文件抛出反常,官方主张先删除并从头创立文件,然后再测验在运用中从头动态加载这些文件。从头创立文件时,请按照上述攻略在写入时将文件标记为只读。或许,能够将现有文件从头标记为只读,但在这种情况下,官方主张先验证文件的完整性(例如,对照可信值检查文件的签名)以维护运用免遭歹意操作的影响。

压缩途径遍历

关于以 Android 14 为方针渠道的运用,Android 会经过以下办法避免 Zip 途径遍历漏洞:假如 Zip 文件条目称号包含“..”或以“/”开头,ZipFile(String)ZipInputStream.getNextEntry() 会抛出 ZipException

运用能够经过调用 dalvik.system.ZipPathValidator.clearCallback() 挑选停用此验证。

针对从后台发动 activity 的其他约束

关于以 Android 14 为方针渠道的运用,体系会进一步约束答应运用在后台发动 activity 的时刻:

  • 现在,当运用运用 PendingIntent#send() 或相似办法发送 PendingIntent 时,假如它想要颁发自己的后台 activity 发动待处理 intent 的发动特权,则有必要挑选启用。如需挑选启用,运用应经过 setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED) 传递 ActivityOptions 软件包。
  • 当可见运用运用 bindService() 办法绑定其他在后台运用的服务时,假如可见运用想要颁发自己的后台 activity 对绑定服务的发动特权,则有必要挑选启用。如需挑选启用,运用应在调用 bindService() 办法时包含 BIND_ALLOW_ACTIVITY_STARTS 标志。

这些更改扩展了一组现有约束条件的范围,目的是避免歹意运用乱用 API 以在后台发动搅扰性活动,然后维护用户。

更新后的非 SDK 约束

Android 14 包含更新后的受限非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测验)。在约束运用非 SDK 接口之前,官方说会尽或许确保有可用的揭露代替计划。

假如运用没有升级到 Android 14 ,其间一些改变或许不会立即产生影响。可是,尽管现在仍能够运用一些非 SDK 接口(详细取决于运用的方针 API 等级),但只要运用任何非 SDK 办法或字段,终归存在导致运用出问题的显著危险。

假如不确认自己的运用是否运用了非 SDK 接口,则能够测验运用来进行确认。假如运用依靠于非 SDK 接口,应该开端计划迁移到 SDK 代替计划。可是,官方知道某些运用具有运用非 SDK 接口的有效用例。假如无法为运用中的某项功用找到运用非 SDK 接口的代替计划,应恳求新的公共 API。

如需详细了解此 Android 版别中的改变,能够参看 Android 14 中有关约束非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,能够参看对非 SDK 接口的约束。

Android 14 的新功用

上面的一大堆便是在 Android 14 中运用需求做的适配,其实看着许多,实践上需求运用修正的地方并不是许多。Android 14 面向开发者还引进了一些超卓的新功用和 API,一起来看下吧!

各运用言语偏好设定

Android 14 扩展了 Android 13(API 等级 33)中引进的按运用设定言语功用,并包含以下额外功用:

  • 主动生成运用的 localeConfig:从 Android Studio Giraffe Canary 7 和 AGP 8.1.0-alpha07 开端,能够将运用装备为主动支撑各运用言语偏好设定。Android Gradle 插件会依据项目资源生成 LocaleConfig 文件,并在最终清单文件中增加对该文件的引证,这样就不再需求手动创立或更新该文件。AGP 运用运用模块的 res 文件夹中的资源以及任何库模块依靠项来确认要在 LocaleConfig 文件中增加的言语区域。如需了解概况并供给反馈,请参看按运用主动设定言语支撑。
  • 动态更新运用的 localeConfig:运用 LocaleManager 办法中的 setOverrideLocaleConfig()getOverrideLocaleConfig() 能够在设备的体系设置中动态更新运用的受支撑言语列表。有了这种灵敏性,就能够按区域自定义支撑的言语列表、运转 A/B 试验,或许假如运用经过服务器端推送进行本地化,则能够供给更新后的言语区域列表。
  • 输入法 (IME) 的运用言语可见性:IME 能够运用 getApplicationLocales() 办法检查当时运用的言语,并将 IME 言语与该言语进行匹配。

语法改变 API

有 30 亿人在运用区别性别的言语,此类言语的语法类别(例如名词、动词、形容词和介词)会依据攀谈所触及的人或物的性别而改变。传统上,许多区别性别的言语运用阳性语法性别作为默许或通用性别。

以错误的语法性别来称号用户,例如以阳性语法性别来称号女性,或许会对她们的体现和情绪产生负面影响。相比之下,界面言语假如能正确反映用户的语法性别,就能够进步用户互动度,并供给更个性化、更天然的用户体会。

为帮助针对区别性别的言语构建以用户为中心的界面,Android 14 引进了语法改变 API,让我们无需重构运用便能增加对语法性别的支撑。

地区偏好设置

区域偏好运用户能够修正温度单位(华氏度、摄氏度),一周的第一天(周日为第一天还是周一)。

新的Android设置菜单为用户供给了一个可发现和集中的方位来更改运用程序偏好。这些首选项在备份和康复过程中也会继续存在。几个api和目的-如’ getTemperatureUnit ‘和’ getFirstDayOfWeek ‘ -颁发运用程序读取拜访用户的偏好,所以你的运用程序能够调整它怎么显现信息。我们还能够在’ ACTION_LOCALE_CHANGED ‘上注册’ BroadcastReceiver ‘来处理区域首选项更改时的区域装备更改。

要找到这些设置,请翻开设置运用程序并导航到体系>言语和输入>区域偏好,官方截图如下:

Android 14 又来了?别扶!抬起我来吧!

途径现在可查询和插值

Android 的 Path API 是一种强壮且灵敏的机制,可用于创立和渲染矢量图形,能够描边或填充途径,依据线段、二次曲线或立方曲线构建途径,履行布尔运算以获取更复杂的形状,或一起履行一切这些操作。可是无法了解 Path 方针中实践包含的内容;该方针的内部信息在创立后关于调用方是不透明的。

如需创立 Path,能够调用 moveTo()lineTo()cubicTo() 等办法来增加途径片段。但无法询问该途径有哪些片段,因而有必要在创立时保存该信息。

从 Android 14 开端,能够查询途径以了解其内部内容。首先,需求运用 Path.getPathIterator API 获取 PathIterator 方针:

Path path = new Path();
path.moveTo(1.0F, 1.0F);
path.lineTo(2.0F, 2.0F);
path.close();
PathIterator pathIterator = path.getPathIterator();

接下来,能够调用 PathIterator 逐一遍历片段,并检索每个片段的一切必要数据。以下示例运用了 PathIterator.Segment 方针,它会打包数据:

while (pathIterator.hasNext()) {
  PathIterator.Segment segment = pathIterator.next();
  Log.i(LOG_TAG, "segment: " + segment.getVerb() + ", " + segment.getPoints());
}

PathIterator 还有一个非分配版 next(),能够在其间传入缓冲区来保存点数据。

查询 Path 数据的一个重要用例是插值。例如,我们或许想在两个不同的途径之间增加动画(或变形)。为了进一步简化该用例,Android 14 针对 Path 还有一个新的 interpolate() 办法。假设两个途径具有相同的内部结构,interpolate() 办法会运用该插值结果创立一个新的 Path。以下示例回来了一个形状介于 pathotherPath 之间的一半(线性插值为 0.5)的途径:

Path interpolatedResult = new Path();
if (path.isInterpolatable(otherPath)) {
  path.interpolate(otherPath, 0.5F, interpolatedResult);
}

还有一点需求留意:Jetpack graphics-path 库现已发布 Alpha 版,它也为早期版别的 Android 供给了相似的 API。

检测用户何时截取设备屏幕截图

为了创立更标准化的截图检测体会,Android 14 中引进了一个维护隐私的截图检测API。这个API答应运用程序以每个活动为基础注册回调。当用户在活动可见时截取屏幕截图时,调用这些回调函数,并告诉用户。

留意: 回调不供给实践截图的图画。当用户截图时,屏幕上显现的内容由运用进行决定。

支撑的用例

在Android 14中,体系API仅在用户履行特定的硬件按键组合时检测截图。API不会检测在运转与屏幕截图相关的测验指令时所截取的屏幕截图,包含ADB或在捕获设备当时屏幕内容的仪器测验中截取的屏幕截图。

完成步骤

要增加截图检测,声明新的’ DETECT_SCREEN_CAPTURE ‘装置时权限:

<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />

然后,完成以下步骤,在你的运用程序中的每个活动,用户或许会捕获屏幕截图:

  1. 经过覆盖 onScreenCapture() 函数完成回调。在这个回调中,运用程序能够采纳一些行动,比如警告另一个用户有人截取了音讯对话的截图。

    final Activity.ScreenCaptureCallback screenCaptureCallback =
      new Activity.ScreenCaptureCallback() {
        @Override
        public void onScreenCaptured() {
          // Add logic to take action in your app.
         }
       };
    
  2. ActivityonStart() 办法中,注册截图回调。

    留意: 考虑到每个屏幕截图检测信号都会显现一个告诉,开发者应该在用户开端运用屏幕截图检测api的活动时向用户供给上下文告诉,这样体系告诉就不会让用户感到意外。

    @Override
    protected void onStart() {
      super.onStart();
      // Pass in the callback created in the previous step 
      // and the intended callback executor (e.g. Activity's mainExecutor).
      registerScreenCaptureCallback(executor, screenCaptureCallback);
    }
    
  3. ActivityonStop() 办法中,刊出截图回调:

    @Override
    protected void onStop() {
      super.onStop();
      unregisterScreenCaptureCallback(screenCaptureCallback);
    }
    

控制捕获屏幕截图能力

假如你不期望一个运用程序的活动的内容呈现在屏幕截图,或在非安全显现,能够设置’ FLAG_SECURE ‘显现标志。

activity.getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);

Android 14 中的企业功用新改变

联络人

Android 14 增加了以下两个字段:

  • ContactsContract.Contacts#ENTERPRISE_CONTENT_URI
  • ContactsContract.CommonDataKinds.Phone#ENTERPRISE_CONTENT_URI

这两个字段一起可让具有 READ_CONTACTS 权限的个人运用列出一切工作材料联络人和电话号码,条件是 DevicePolicyManager 中的跨材料联络人方针答应这么做。

跨材料拜访联络人

能够运用 DevicePolicyManager 中的以下办法设置和查询该方针,这些办法指定了答应哪些软件包从个人材料中拜访工作联络人:

  • setManagedProfileContactsAccessPolicy()
  • getManagedProfileContactsAccessPolicy()

这些办法可向后兼容,应改用这些办法,而不是现在已抛弃的下列办法:

  • setCrossProfileContactsSearchDisabled()
  • getCrossProfileContactsSearchDisabled()

跨材料来电显现查找

相同,Android 14 还针对跨材料来电显现查找增加了以下办法:

  • setManagedProfileCallerIdAccessPolicy()
  • getManagedProfileCallerIdAccessPolicy()

这些办法可向后兼容,应改用这些办法,而不是现在已抛弃的下列办法:

  • getCrossProfileCallerIdDisabled()
  • setCrossProfileCallerIdDisabled()

超宽带

超宽带 (UWB) 是一种无线技能,在很大一部分射频频谱内,都能运用十分低的能量水平进行短距离、高带宽通信。

从 Android 14 开端,设备或材料一切者能够经过 DevicePolicyManager.addUserRestriction() 运用 DISALLOW_ULTRA_WIDEBAND_RADIO 用户约束,对安排一切的设备制止运用 UWB。

抛弃

Android 14 抛弃了以下 API,值得引起留意:

  • 抛弃了 DevicePolicyManager#setCrossProfileCalendarPackagesDevicePolicyManager#getCrossProfileCalendarPackages

    日历运用应迁移到关联的运用,设备方针控制器 (DPC) 应改为运用 DevicePolicyManager#setCrossProfilePackages

  • 以下办法已抛弃:

    • DevicePolicyManager#setCrossProfileContactsSearchDisabled
    • DevicePolicyManager#getCrossProfileContactsSearchDisabled
    • DevicePolicyManager#setCrossProfileCallerIdDisabled
    • DevicePolicyManager#getCrossProfileCallerIdDisabled

    DPC 应运用上文联络人部分中所述的代替办法。

总结

尽管现在 Android 14 还没有发布稳定版版,但现在现已是 Beta 版别了,之后 API 这些也不会进行大的变化的,剩下的应该便是性能上的一些优化了,我们能够定心进行检查。其实上面描绘的都能够在官方文档中找到,我只是做了一些整理,便利我们进行检查装备。

OK,就到这儿吧,假如内容对你有帮助,别忘了点个赞!