기능 및 API 개요

Android 15에는 개발자를 위한 훌륭한 새로운 기능과 API가 도입되었습니다. 다음 섹션에는 관련 API를 시작하는 데 도움이 되는 이러한 기능이 요약되어 있습니다.

새로운 API, 수정된 API 및 삭제된 API에 관한 자세한 목록은 API 차이점 보고서를 참고하세요. 새로운 API에 관한 자세한 내용은 Android API 참조를 확인하세요. 새로운 API는 눈에 잘 띄도록 강조 표시됩니다. 또한 플랫폼 변경사항이 앱에 영향을 미칠 수 있는 분야에 관해 알아보려면 Android 15 Android 15를 타겟팅할 때 앱에 영향을 미치는 동작 변경사항targetSdkVersion와 관계없이 모든 앱에 영향을 미치는 동작 변경사항을 검토하세요.

카메라 및 미디어

Android 15에는 카메라 및 미디어 환경을 개선하고 크리에이터가 Android에서 비전을 실현할 수 있도록 지원하는 도구와 하드웨어에 액세스할 수 있는 다양한 기능이 포함되어 있습니다.

Android 미디어 및 카메라를 위한 최신 기능과 개발자 솔루션에 관한 자세한 내용은 Google I/O의 최신 Android 미디어 및 카메라 환경 빌드 강연을 참고하세요.

저조도 증폭

Android 15에서는 카메라 2야간 모드 카메라 확장 프로그램에서 모두 사용할 수 있는 새로운 자동 노출 모드인 어두운 조명 증폭을 도입합니다. Low Light Boost는 어두운 환경에서 미리보기 스트림의 노출을 조정합니다. 이는 야간 모드 카메라 확장 프로그램에서 정지 이미지를 만드는 방법과 다릅니다. 야간 모드는 사진 버스트를 결합하여 향상된 단일 이미지를 만들기 때문입니다. 야간 모드는 정지 이미지를 만드는 데 매우 효과적이지만 연속적인 프레임 스트림을 만들 수는 없지만 Low Light Boost는 만들 수 있습니다. 따라서 Low Light Boost는 다음과 같은 새로운 카메라 기능을 지원합니다.

  • 사용자가 어두운 사진의 프레임을 더 잘 조정할 수 있도록 개선된 이미지 미리보기를 제공합니다.
  • 어두운 곳에서 QR 코드 스캔 중

어두운 조명 부스트를 사용 설정하면 조명 수준이 낮을 때 자동으로 켜지고 조명이 더 많으면 자동으로 꺼집니다.

앱은 조명이 어두운 환경에서 미리보기 스트림을 녹화하여 밝게 된 동영상을 저장할 수 있습니다.

자세한 내용은 어두운 조명 부스트를 참고하세요.

인앱 카메라 제어

Android 15 添加了一个新扩展,用于在支持的设备上更好地控制相机硬件及其算法:

  • 高级闪光灯强度调整,可让您在拍摄照片时精确控制 SINGLETORCH 模式下的闪光强度。

HDR 헤드룸 제어

Android 15 会选择适合底层设备功能和面板的位深的 HDR 余量。对于包含大量 SDR 内容的页面(例如显示单个 HDR 缩略图的即时通讯应用),此行为最终可能会对 SDR 内容的感知亮度产生不利影响。Android 15 允许您使用 setDesiredHdrHeadroom 控制 HDR 余量,以在 SDR 和 HDR 内容之间取得平衡。

左侧屏幕上 SDR 界面元素的亮度似乎比右侧屏幕的亮度更均匀,这模拟了混合 HDR 和 SDR 内容时可能出现的余量问题。通过调整 HDR 余量,您可以在 SDR 和 HDR 内容之间更好地平衡。

음량 조절

Android 15 引入了对 CTA-2075 音量标准的支持,以帮助您避免音频音量不一致,并确保用户在切换内容时无需不断调整音量。系统利用输出设备(耳机和扬声器)的已知特征以及 AAC 音频内容中提供的音量元数据来智能地调整音频音量和动态范围压缩级别。

如需启用此功能,您需要确保 AAC 内容中有音量元数据,并在您的应用中启用平台功能。为此,您可以使用关联的 AudioTrack 中的音频会话 ID 调用其 create 工厂方法,从而实例化此对象;此方法会自动开始应用音频更新。LoudnessCodecController您可以传递 OnLoudnessCodecUpdateListener 以在将音量参数应用于 MediaCodec 之前修改或过滤这些参数。

// Media contains metadata of type MPEG_4 OR MPEG_D
val mediaCodec = …
val audioTrack = AudioTrack.Builder()
                                .setSessionId(sessionId)
                                .build()
...
// Create new loudness controller that applies the parameters to the MediaCodec
try {
   val lcController = LoudnessCodecController.create(mSessionId)
   // Starts applying audio updates for each added MediaCodec
}

AndroidX media3 ExoPlayer 也将更新,以使用 LoudnessCodecController API 实现无缝应用集成。

가상 MIDI 2.0 기기

Android 13에서는 범용 MIDI 패킷 (UMP)을 사용하여 통신하는 USB를 사용하여 MIDI 2.0 기기에 연결할 수 있는 지원을 추가했습니다. Android 15는 가상 MIDI 앱으로 UMP 지원을 확장하여 컴포지션 앱이 USB MIDI 2.0 기기와 마찬가지로 가상 MIDI 2.0 기기로 신시사이저 앱을 제어할 수 있도록 합니다.

보다 효율적인 AV1 소프트웨어 디코딩

dav1d 徽标

dav1d(VideoLAN 中广受欢迎的 AV1 软件解码器)现已可用于在硬件中不支持 AV1 解码的 Android 设备。dav1d 的性能比旧版 AV1 软件解码器的性能高 3 倍,可让更多用户(包括一些中低层级的设备)播放高清 AV1 视频。

目前,您的应用需要通过调用 dav1d 名称 "c2.android.av1-dav1d.decoder" 来选择使用 dav1d。在后续更新中,dav1d 将成为默认的 AV1 软件解码器。这项支持已标准化,并向后移植到接收 Google Play 系统更新的 Android 11 设备。

개발자 생산성 및 도구

생산성을 개선하기 위한 Google의 작업은 대부분 Android 스튜디오, Jetpack Compose, Android Jetpack 라이브러리와 같은 도구를 중심으로 진행되지만, Google은 항상 플랫폼에서 개발자가 비전을 더 쉽게 실현할 수 있는 방법을 찾고 있습니다.

OpenJDK 17 업데이트

Android 15 会继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。

其中包含以下主要功能和改进:

这些 API 通过 Google Play 系统更新在超过 10 亿台搭载 Android 12(API 级别 31)及更高版本的设备上进行了更新,让您能够以最新的编程功能为目标平台。

PDF 개선사항

Android 15 对 PdfRenderer API 进行了重大改进。应用可以整合一些高级功能,例如渲染受密码保护的文件、注解、表单编辑搜索和通过复制进行选择。支持线性 PDF 优化,以加快本地 PDF 的查看速度并减少资源使用量。

针对 PDF 渲染功能的最新更新包括搜索嵌入式 PDF 文件等功能。

PdfRenderer 已移至一个模块,此模块可使用与平台版本无关的 Google Play 系统更新来进行更新,并且我们将通过创建兼容的 API Surface 低于 Android 15 的版本(称为 PdfRendererPreV)来支持在 Android 11(API 级别 30)中更新这些变更。

我们非常重视您对 PdfRenderer API 接口的增强功能的反馈,我们计划通过即将推出的 Android Jetpack 库,让开发者能更轻松地将这些 API 整合到您的应用中。

자동 언어 전환 상세검색

Android 14 增加了设备端音频中的多语言识别功能,可在语言之间自动切换,但这可能会导致单词丢失,尤其是在语言切换时,两种话语之间的停顿较少时。Android 15 添加了额外的控件,可帮助应用根据其用例调整此切换。EXTRA_LANGUAGE_SWITCH_INITIAL_ACTIVE_DURATION_TIME_MILLIS 会将自动切换限制为仅在音频会话开始时进行,而 EXTRA_LANGUAGE_SWITCH_MATCH_SWITCHES 则会在指定次数的切换后停用语言切换。如果您希望自动检测到会话期间只讲一种语言,这些选项特别有用。

개선된 OpenType 가변 글꼴 API

Android 15 提高了 OpenType 可变字体的易用性。您现在可以使用可变字体创建 FontFamily 实例,而无需使用 buildVariableFamily API 指定粗细轴。文本渲染程序会覆盖 wght 轴的值以匹配显示的文本。

使用新的 API,这大大简化了创建 Typeface 的代码:

Kotlin

val newTypeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(assets, "RobotoFlex.ttf").build())
                    .buildVariableFamily())
    .build()

Java

Typeface newTypeface = Typeface.CustomFallbackBuilder(
            new FontFamily.Builder(
                new Font.Builder(assets, "RobotoFlex.ttf").build())
                    .buildVariableFamily())
    .build();

以前,如需创建相同的 Typeface,您需要更多代码:

Kotlin

val oldTypeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(assets, "RobotoFlex.ttf")
                    .setFontVariationSettings("'wght' 400")
                    .setWeight(400)
                    .build())
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 100")
                        .setWeight(100)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 200")
                        .setWeight(200)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 300")
                        .setWeight(300)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 500")
                        .setWeight(500)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 600")
                        .setWeight(600)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 700")
                        .setWeight(700)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 800")
                        .setWeight(800)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 900")
                        .setWeight(900)
                        .build()
                ).build()
        ).build()

Java

Typeface oldTypeface = new Typeface.CustomFallbackBuilder(
    new FontFamily.Builder(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 400")
            .setWeight(400)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 100")
            .setWeight(100)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 200")
            .setWeight(200)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 300")
            .setWeight(300)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 500")
            .setWeight(500)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 600")
            .setWeight(600)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 700")
            .setWeight(700)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 800")
            .setWeight(800)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 900")
            .setWeight(900)
            .build()
    )
    .build()
).build();

以下示例展示了同时使用新旧 API 创建的 Typeface 如何呈现:

使用新旧 API 时 Typeface 渲染有何不同的示例

在此示例中,使用旧 API 创建的 Typeface 无法为 350、450、550 和 650 Font 实例创建准确的字体粗细,因此渲染程序会回退到最接近的粗细。因此,在此例中,会渲染 300 而不是 350,渲染 400 而不是 450,依此类推。相比之下,使用新 API 创建的 Typeface 会为给定权重动态创建 Font 实例,因此也会为 350、450、550 和 650 呈现准确的权重。

세밀한 줄바꿈 컨트롤

Android 15부터 TextView 및 기본 줄바꿈은 같은 줄의 지정된 텍스트 부분을 보존하여 가독성을 개선할 수 있습니다. 문자열 리소스 또는 createNoBreakSpan에서 <nobreak> 태그를 사용하여 이 줄바꿈 맞춤설정을 활용할 수 있습니다. 마찬가지로 <nohyphen> 태그 또는 createNoHyphenationSpan를 사용하여 하이픈이 있는 단어를 보존할 수 있습니다.

예를 들어 다음 문자열 리소스는 줄바꿈을 포함하지 않으며 'Pixel 8 Pro.'라는 텍스트가 바람직하지 않은 위치에 끊어져 렌더링됩니다.

<resources>
    <string name="pixel8pro">The power and brains behind Pixel 8 Pro.</string>
</resources>

반면 이 문자열 리소스에는 'Pixel 8 Pro'라는 문구를 래핑하고 줄바꿈을 방지하는 <nobreak> 태그가 포함되어 있습니다.

<resources>
    <string name="pixel8pro">The power and brains behind <nobreak>Pixel 8 Pro.</nobreak></string>
</resources>

이러한 문자열이 렌더링되는 방식의 차이점은 다음 이미지에 나와 있습니다.

'Pixel 8 Pro.' 문구가 <nobreak> 태그를 사용하여 래핑되지 않은 텍스트 줄의 레이아웃
'Pixel 8 Pro.' 문구가 <nobreak> 태그를 사용하여 래핑된 동일한 텍스트 줄의 레이아웃

앱 보관처리

Android 和 Google Play 去年宣布支持应用归档,这让用户可以通过从 Google Play 上使用 Android App Bundle 发布的部分不常用的应用来释放空间。Android 15 现在包含对应用归档和取消归档的操作系统级支持,因此所有应用商店都可以更轻松地实现此功能。

具有 REQUEST_DELETE_PACKAGES 权限的应用可以调用 PackageInstaller requestArchive 方法来请求归档已安装的应用软件包,此操作会移除 APK 和所有缓存的文件,但会保留用户数据。已归档的应用会通过 LauncherApps API 作为可显示的应用返回;用户会看到界面处理方式,以突出显示这些应用已归档。如果用户点按已归档的应用,相关安装程序将收到将其取消归档的请求,并且可以通过 ACTION_PACKAGE_ADDED 广播监控恢复过程。

그래픽

Android 15에서는 ANGLE과 캔버스 그래픽 시스템에 추가된 기능을 비롯한 최신 그래픽 개선사항을 제공합니다.

Android GPU 액세스 현대화

Vulkan 로고

코어 OS가 단일 CPU에서 실행되고 고정 기능 파이프라인을 기반으로 API를 사용하여 GPU에 액세스하던 초기부터 Android 하드웨어가 크게 발전했습니다. Vulkan® 그래픽 API는 Android 7.0 (API 수준 24)부터 NDK에서 사용할 수 있습니다. 여기에는 최신 GPU 하드웨어를 더 잘 반영하고 여러 CPU 코어를 지원하도록 확장되며 CPU 드라이버 오버헤드가 감소하여 앱 성능이 개선된 하위 수준 추상화가 포함됩니다. Vulkan은 모든 최신 게임 엔진에서 지원됩니다.

Vulkan은 GPU에 대해 Android에서 선호하는 인터페이스입니다. 따라서 Android 15에는 Vulkan에서 OpenGL® ES를 실행하기 위한 선택적 레이어로 ANGLE이 포함되어 있습니다. ANGLE로 이동하면 호환성이 개선되고 경우에 따라 성능이 향상되도록 Android OpenGL 구현이 표준화됩니다. Android 15의 설정 -> 시스템 -> 개발자 옵션 -> 실험용: ANGLE 사용 설정에서 개발자 옵션을 사용 설정하여 ANGLE에서 OpenGL ES 앱 안정성 및 성능을 테스트할 수 있습니다.

Vulkan의 Android ANGLE 로드맵

Android GPU API에 예정된 변경사항 로드맵

GPU 스택 간소화의 일환으로 앞으로 더 많은 새로운 기기에서 OpenGL 시스템 드라이버로 ANGLE을 제공할 예정이며, 향후 OpenGL/ES는 ANGLE을 통해서만 제공될 것으로 예상합니다. 하지만 모든 기기에서 OpenGL ES를 계속 지원할 계획입니다.

권장되는 다음 단계

개발자 옵션을 사용하여 OpenGL ES용 ANGLE 드라이버를 선택하고 앱을 테스트합니다. 새 프로젝트의 경우 C/C++용 Vulkan을 사용하는 것이 좋습니다.

캔버스 개선사항

Android 15 继续对 Android 的 Canvas 图形系统进行现代化改造,并增添了新功能:

  • Matrix44 提供了一个用于转换坐标的 4x4 矩阵,当您想要处理 3D 画布时,应使用此矩阵。
  • clipShader 将当前裁剪与指定着色器相交,而 clipOutShader 会将裁剪设置为当前裁剪和着色器的差异,其中各自将着色器视为 Alpha 蒙版。这有助于高效绘制复杂形状。

성능 및 배터리

Android는 개발자가 앱의 성능과 품질을 개선하는 데 도움을 주기 위해 끊임없이 노력하고 있습니다. Android 15에서는 앱의 작업을 더 효율적으로 실행하고 앱 성능을 최적화하며 앱에 관한 유용한 정보를 수집하는 데 도움이 되는 새로운 API를 도입합니다.

배터리 효율적인 권장사항, 네트워크 및 전력 사용량 디버깅, Android 15 및 최신 버전의 Android에서 백그라운드 작업의 배터리 효율성을 개선하는 방법에 관한 자세한 내용은 Google I/O의 Android에서 백그라운드 작업의 배터리 효율 개선 토론을 참고하세요.

ApplicationStartInfo API

在以前的 Android 版本中,应用启动有点神秘。在应用中确定应用是从冷状态、温状态还是热状态开始的过程很难确定。此外,我们也很难知道您的应用在不同发布阶段所用的时间:创建进程分支、调用 onCreate、绘制第一帧等。在实例化 Application 类时,您无法得知应用是从广播、content provider、作业、备份、启动完成、闹钟还是 Activity 启动的。

Android 15 上的 ApplicationStartInfo API 可提供所有这些功能以及更多其他功能。您甚至可以选择将自己的时间戳添加到流程中,以便在一个位置收集时间数据。除了收集指标之外,您还可以使用 ApplicationStartInfo 直接优化应用启动;例如,当应用因广播而启动时,您可以避免在 Application 类中实例化界面相关库的高成本。

자세한 앱 크기 정보

自 Android 8.0(API 级别 26)起,Android 就一直包含 StorageStats.getAppBytes API,该 API 将应用的安装大小汇总为一个字节,这些字节是 APK 大小、从 APK 中提取的文件的大小以及设备上生成的文件(例如预先 (AOT) 编译代码)的总和。就应用的存储空间使用情况而言,此数字并不富有见解。

Android 15 增加了 StorageStats.getAppBytesByDataType([type]) API,可让您深入了解应用如何使用所有空间,包括 APK 文件拆分、AOT 和加速相关代码、dex 元数据、库和引导式配置文件。

앱 관리 프로파일링

Android 15 包含全新的 ProfilingManager 类,可让您从应用内收集性能分析信息。我们计划使用 Android Jetpack API 封装该类,这将简化性能分析请求的构建过程,但核心 API 将允许收集堆转储、堆配置文件、堆栈采样等信息。它使用提供的标记为您的应用提供回调,用于标识输出文件,该文件将传递到应用的文件目录。该 API 会限制速率限制,以最大限度地降低对性能的影响。

SQLite 데이터베이스 개선

Android 15 introduces new SQLite APIs that expose advanced features from the underlying SQLite engine that target specific performance issues that can manifest in apps.

Developers should consult best practices for SQLite performance to get the most out of their SQLite database, especially when working with large databases or when running latency-sensitive queries.

  • Read-only deferred transactions: when issuing transactions that are read-only (don't include write statements), use beginTransactionReadOnly() and beginTransactionWithListenerReadOnly(SQLiteTransactionListener) to issue read-only DEFERRED transactions. Such transactions can run concurrently with each other, and if the database is in WAL mode, they can run concurrently with IMMEDIATE or EXCLUSIVE transactions.
  • Row counts and IDs: new APIs were added to retrieve the count of changed rows or the last inserted row ID without issuing an additional query. getLastChangedRowCount() returns the number of rows that were inserted, updated, or deleted by the most recent SQL statement within the current transaction, while getTotalChangedRowCount() returns the count on the current connection. getLastInsertRowId() returns the rowid of the last row to be inserted on the current connection.
  • Raw statements: issue a raw SQlite statement, bypassing convenience wrappers and any additional processing overhead that they may incur.

Android 동적 성능 프레임워크 업데이트

Android 15 继续投资开发 Android 动态性能框架 (ADPF),这是一组 API,可让游戏和性能密集型应用更直接地与 Android 设备的电源和散热系统进行互动。在受支持的设备上,Android 15 将添加新的 ADPF 功能:

  • 适用于提示会话的节能模式,用于指明其关联的线程应该优先考虑节能而非性能,非常适合长时间运行的后台工作负载。
  • 可以在提示会话中报告 GPU 和 CPU 的运行时长,从而使系统能够同时调整 CPU 和 GPU 频率,以便更好地满足工作负载需求。
  • 热余量阈值,用于根据余量预测来解释可能的热节流状态。

如需详细了解如何在应用和游戏中使用 ADPF,请参阅相关文档

개인 정보 보호

Android 15에는 앱 개발자가 사용자 개인 정보를 보호하는 데 도움이 되는 다양한 기능이 포함되어 있습니다.

화면 녹화 감지

Android 15 增加了对应用检测功能的支持,以检测其是否被录制。每当应用在屏幕录制中处于可见或不可见状态之间转换时,系统都会调用回调。如果系统正在记录注册进程的 UID 拥有的 activity,则应用会被视为可见。这样,如果您的应用正在执行敏感操作,您就可以告知用户系统正在记录这些操作。

val mCallback = Consumer<Int> { state ->
  if (state == SCREEN_RECORDING_STATE_VISIBLE) {
    // We're being recorded
  } else {
    // We're not being recorded
  }
}

override fun onStart() {
   super.onStart()
   val initialState =
      windowManager.addScreenRecordingCallback(mainExecutor, mCallback)
   mCallback.accept(initialState)
}

override fun onStop() {
    super.onStop()
    windowManager.removeScreenRecordingCallback(mCallback)
}

확장된 IntentFilter 기능

Android 15는 UriRelativeFilterGroup를 통해 더 정확한 Intent 변환을 지원합니다. 여기에는 URL 쿼리 매개변수, URL 프래그먼트, 차단 또는 제외 규칙 등 각각 충족해야 하는 Intent 일치 규칙 집합을 구성하는 일련의 UriRelativeFilter 객체가 포함됩니다.

이러한 규칙은 android:allow 태그를 선택적으로 포함할 수 있는 새 <uri-relative-filter-group> 태그를 사용하여 AndroidManifest XML 파일에서 정의할 수 있습니다. 이러한 태그에는 기존 데이터 태그 속성과 새 android:queryandroid:fragment 속성을 사용하는 <data> 태그가 포함될 수 있습니다.

다음은 AndroidManifest 문법의 예입니다.

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="http" />
  <data android:scheme="https" />
  <data android:domain="astore.com" />
  <uri-relative-filter-group>
    <data android:pathPrefix="/auth" />
    <data android:query="region=na" />
  </uri-relative-filter-group>
  <uri-relative-filter-group android:allow="false">
    <data android:pathPrefix="/auth" />
    <data android:query="mobileoptout=true" />
  </uri-relative-filter-group>
  <uri-relative-filter-group android:allow="false">
    <data android:pathPrefix="/auth" />
    <data android:fragmentPrefix="faq" />
  </uri-relative-filter-group>
</intent-filter>

비공개 스페이스

비공개 스페이스를 잠금 해제하고 잠글 수 있어 기기에서 민감한 앱을 표시하거나 숨길 수 있습니다.

비공개 공간을 사용하면 사용자는 추가 인증 레이어에 따라 민감한 앱을 눈에 띄지 않게 할 수 있는 별도의 공간을 기기에 만들 수 있습니다. 비공개 스페이스는 별도의 사용자 프로필을 사용합니다. 사용자가 비공개 스페이스를 잠그면 프로필이 일시중지되고 비공개 스페이스의 모든 앱이 더 이상 활성 상태가 아닙니다. 사용자는 비공개 공간에 기기 잠금을 사용하거나 별도의 잠금 계수를 사용하도록 선택할 수 있습니다.

비공개 스페이스의 앱은 런처의 별도의 컨테이너에 표시되며 비공개 스페이스가 잠겨 있을 때 최근 항목 뷰, 알림, 설정 및 다른 앱에 표시되지 않습니다. 사용자가 만들고 다운로드한 콘텐츠 (예: 미디어 또는 파일)와 계정은 비공개 공간과 기본 공간 간에 구분됩니다. 시스템 Sharesheet사진 선택 도구를 사용하면 비공개 스페이스가 잠금 해제될 때 앱이 스페이스의 콘텐츠에 액세스하도록 허용할 수 있습니다.

특히 앱이 다음 카테고리 중 하나에 속하는 경우 비공개 공간으로 앱을 테스트하여 앱이 예상대로 작동하는지 확인하는 것이 좋습니다.

선택한 사진 액세스 권한에 대해 가장 최근에 선택한 사용자를 쿼리합니다.

现在,授予媒体权限的部分访问权限后,应用可以仅突出显示最近选择的照片和视频。此功能可以改善频繁请求访问照片和视频的应用的用户体验。如需在您的应用中使用此功能,请在通过 ContentResolver 查询 MediaStore 时启用 QUERY_ARG_LATEST_SELECTION_ONLY 参数。

Kotlin

val externalContentUri = MediaStore.Files.getContentUri("external")

val mediaColumns = arrayOf(
   FileColumns._ID,
   FileColumns.DISPLAY_NAME,
   FileColumns.MIME_TYPE,
)

val queryArgs = bundleOf(
   // Return only items from the last selection (selected photos access)
   QUERY_ARG_LATEST_SELECTION_ONLY to true,
   // Sort returned items chronologically based on when they were added to the device's storage
   QUERY_ARG_SQL_SORT_ORDER to "${FileColumns.DATE_ADDED} DESC",
   QUERY_ARG_SQL_SELECTION to "${FileColumns.MEDIA_TYPE} = ? OR ${FileColumns.MEDIA_TYPE} = ?",
   QUERY_ARG_SQL_SELECTION_ARGS to arrayOf(
       FileColumns.MEDIA_TYPE_IMAGE.toString(),
       FileColumns.MEDIA_TYPE_VIDEO.toString()
   )
)

Java

Uri externalContentUri = MediaStore.Files.getContentUri("external");

String[] mediaColumns = {
    FileColumns._ID,
    FileColumns.DISPLAY_NAME,
    FileColumns.MIME_TYPE
};

Bundle queryArgs = new Bundle();
queryArgs.putBoolean(MediaStore.QUERY_ARG_LATEST_SELECTION_ONLY, true);
queryArgs.putString(MediaStore.QUERY_ARG_SQL_SORT_ORDER, FileColumns.DATE_ADDED + " DESC");
queryArgs.putString(MediaStore.QUERY_ARG_SQL_SELECTION, FileColumns.MEDIA_TYPE + " = ? OR " + FileColumns.MEDIA_TYPE + " = ?");
queryArgs.putStringArray(MediaStore.QUERY_ARG_SQL_SELECTION_ARGS, new String[] {
    String.valueOf(FileColumns.MEDIA_TYPE_IMAGE),
    String.valueOf(FileColumns.MEDIA_TYPE_VIDEO)
});

Android의 개인 정보 보호 샌드박스

Android 15 包含最新的 Android 广告服务扩展程序,以及最新版 Privacy Sandbox on Android。我们致力于开发新的技术,以便更好地保护用户隐私,并为移动应用打造有效的个性化广告体验。这项新功能是我们的工作的一部分。我们的隐私沙盒页面详细介绍了 Privacy Sandbox on Android 开发者预览版和 Beta 版计划,以帮助您开始使用。

헬스 커넥트

Android 15 集成了围绕 Health Connect by Android 的最新扩展程序。Health Connect by Android 是一个安全的集中式平台,用于管理和分享应用收集的健康与健身数据。此更新增加了对健身营养、体表温度、训练计划等领域的新数据类型的支持。

借助体表温度跟踪功能,用户可以从穿戴式设备或其他跟踪设备存储和分享更准确的体温数据。

训练计划是结构化的锻炼计划,可帮助用户实现健身目标。训练计划支持包括各种完成目标和绩效目标:

如需详细了解 Android 中 Health Connect 的最新更新,请观看 Google I/O 大会的利用 Android Health 打造适应性体验演讲。

부분 화면 공유

Android 15 支持局部屏幕共享,因此用户可以仅分享或录制应用窗口,而不是整个设备屏幕。此功能在 Android 14 QPR2 中首次启用,包含 MediaProjection 回调,可让您的应用自定义局部屏幕共享体验。请注意,对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,现在需要针对每个 MediaProjection 捕获会话征得用户同意

사용자 환경 및 시스템 UI

Android 15에서는 앱 개발자와 사용자가 필요에 따라 기기를 구성할 수 있도록 더 많은 제어와 유연성을 제공합니다.

Android 15의 최신 개선사항을 사용하여 앱의 사용자 환경을 개선하는 방법에 관한 자세한 내용은 Google I/O의 Android 앱의 사용자 환경 개선 대담을 참고하세요.

Generated Previews API로 더욱 풍부한 위젯 미리보기

在 Android 15 之前,提供 widget 选择器预览的唯一方法是指定静态图片或布局资源。这些预览通常会与实际 widget 放置在主屏幕上时的外观有明显差异。此外,无法使用 Jetpack Glance 创建静态资源,因此 Glance 开发者必须对其 widget 进行屏幕截图或创建 XML 布局,才能具有 widget 预览。

Android 15 增加了对生成的预览的支持。这意味着,应用 widget 提供程序可以生成 RemoteViews(而不是静态资源)来用作选择器预览。

应用可以为 widget 选择器提供远程视图,以便更新选择器中的内容,使其更能代表用户将看到的内容。

推送 API

应用可以通过推送 API 提供生成的预览。应用可以在其生命周期的任何时间点提供预览,而不会收到主机发送的关于提供预览的明确请求。预览会保留在 AppWidgetService 中,并且主机可以按需请求预览。以下示例会加载 XML widget 布局资源,并将其设置为预览:

AppWidgetManager.getInstance(appContext).setWidgetPreview(
   ComponentName(
       appContext,
       SociaLiteAppWidgetReceiver::class.java
   ),
   AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
   RemoteViews("com.example", R.layout.widget_preview)
)

预期的流程为:

  1. 任何时候,widget 提供程序都会调用 setWidgetPreview。提供的预览与其他提供程序信息一起保留在 AppWidgetService 中。
  2. setWidgetPreview 通过 AppWidgetHost.onProvidersChanged 回调将预览更新后通知主机。作为响应,widget 主机会重新加载其所有提供程序信息。
  3. 显示 widget 预览时,托管应用会检查 AppWidgetProviderInfo.generatedPreviewCategories,如果所选类别可用,则调用 AppWidgetManager.getWidgetPreview 以返回此提供程序的已保存预览。

何时调用 setWidgetPreview

由于没有用于提供预览的回调,因此应用在运行时可以选择随时发送预览。预览的更新频率取决于 widget 的用例。

以下列表介绍了预览用例的两大主要类别:

  • 在 widget 预览中显示真实数据(例如个性化或最新信息)的提供程序。用户登录应用或在应用中完成初始配置后,这些提供程序就可以设置预览。之后,他们可以设置一个定期任务,按所选频率更新预览。此类 widget 的示例包括照片、日历、天气或新闻 widget。
  • 在预览中显示静态信息的提供程序或不显示任何数据的快速操作 widget。这些提供程序可在应用首次启动时设置一次预览。此类微件的示例包括云端硬盘“快速操作”微件或 Chrome 快捷方式微件。

某些提供程序可能会在基座接入模式选择器上显示静态预览,但在主屏幕选择器上显示真实信息。这些提供程序应遵循针对这两种用例的指南来设置预览。

PIP 모드

Android 15 引入了对画中画 (PiP) 功能的新变更,可确保在进入画中画模式时能够更顺畅地过渡。这对于将界面元素叠加在其主界面之上的应用(将进入画中画模式)非常有用。

开发者使用 onPictureInPictureModeChanged 回调来定义用于切换叠加界面元素的可见性的逻辑。此回调会在画中画进入或退出动画播放完毕时触发。从 Android 15 开始,PictureInPictureUiState 类包含一个新状态。

借助这种新的界面状态,以 Android 15 为目标平台的应用会在画中画动画开始时立即观察到使用 isTransitioningToPip() 调用的 Activity#onPictureInPictureUiStateChanged 回调。在应用处于画中画模式时,有许多界面元素与应用无关,例如,包含建议、即将播出的视频、评分和标题等信息的视图或布局。当应用进入画中画模式时,使用 onPictureInPictureUiStateChanged 回调隐藏这些界面元素。当应用从画中画窗口进入全屏模式时,可以使用 onPictureInPictureModeChanged 回调来取消隐藏这些元素,如以下示例所示:

override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
        if (pipState.isTransitioningToPip()) {
          // Hide UI elements
        }
    }
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
        if (isInPictureInPictureMode) {
          // Unhide UI elements
        }
    }

这种可快速切换不相关界面元素(适用于画中画窗口)的可见性切换有助于确保画中画进入动画更加流畅且无闪烁。

방해 금지 모드 규칙 개선

AutomaticZenRule 可让应用自定义注意力管理(勿扰)规则,并决定何时启用或停用这些规则。Android 15 大幅增强了这些规则,以改善用户体验。其中包含以下增强功能:

  • 将类型添加到 AutomaticZenRule,允许系统对某些规则应用特殊处理。
  • AutomaticZenRule 添加了图标,有助于使模式更易于识别。
  • AutomaticZenRule 添加 triggerDescription 字符串,用于描述应在哪些条件下为用户启用规则。
  • AutomaticZenRule 添加了 ZenDeviceEffects,以允许规则触发灰度显示、夜间模式或调暗壁纸等功能。

알림 채널의 VibrationEffect 설정

Android 15는 NotificationChannel.setVibrationEffect를 사용하여 수신 알림에 다양한 진동 설정을 지원하므로 사용자가 기기를 보지 않고도 여러 유형의 알림을 구별할 수 있습니다.

대형 화면 및 폼 팩터

Android 15는 앱에서 대형 화면, 플립블, 폴더블을 비롯한 Android 폼 팩터를 최대한 활용할 수 있도록 지원합니다.

대형 화면 멀티태스킹 개선

Android 15 为用户提供了更好的在大屏设备上进行多任务处理的方式。例如,用户可以保存他们喜欢的分屏应用组合以快速访问,还可以固定屏幕上的任务栏以在应用之间快速切换。这意味着,确保应用具有自适应能力比以往任何时候都更加重要。

Google I/O 大会举办了有关构建自适应 Android 应用使用 Material 3 自适应库构建界面的会议,这对您有所帮助。我们的文档中包含更多可以帮助您针对大屏幕进行设计的文档。

커버 화면 지원

앱은 Android 15에서 지원되는 플립형 기기의 작은 커버 화면에 Application 또는 Activity가 표시되도록 하는 데 사용하는 속성을 선언할 수 있습니다. 이러한 화면은 Android 앱을 실행하기에 호환되는 타겟으로 간주하기에는 너무 작지만 앱이 이를 지원하도록 선택하여 더 많은 위치에서 앱을 사용할 수 있습니다.

연결

Android 15는 앱이 최신 통신 및 무선 기술에 액세스할 수 있도록 플랫폼을 업데이트합니다.

위성 지원

Android 15 继续扩展对卫星连接的平台支持,并添加了一些界面元素,以确保在卫星连接环境中提供一致的用户体验。

应用可以使用 ServiceState.isUsingNonTerrestrialNetwork() 检测设备何时连接到卫星,从而更好地了解为什么全网络服务不可用。此外,Android 15 支持短信和彩信应用以及预加载的 RCS 应用,以便使用卫星连接收发信息。

设备连接到卫星时显示通知。

더 원활한 NFC 환경

Android 15 正努力让感应式付款体验更加顺畅和可靠,同时继续支持 Android 强大的 NFC 应用生态系统。在受支持的设备上,应用可以请求 NfcAdapter 进入观察模式,在该模式下,设备会监听 NFC 读取器,但不响应 NFC 读取器,同时发送应用的 NFC 服务 PollingFrame 对象进行处理。PollingFrame 对象可用于在首次与 NFC 读取器通信之前进行身份验证,在许多情况下可实现一键交易。

此外,应用现在可以在受支持的设备上注册指纹,以便接收轮询循环活动的相关通知,从而实现通过多个可感知 NFC 的应用顺畅执行的操作。

월렛 역할

Android 15 引入了一个新的钱包角色,可让您与用户首选的钱包应用更紧密地集成。此角色取代了 NFC 默认的感应式付款设置。用户可以通过导航到设置 > 应用 > 默认应用来管理 Google 钱包角色持有者。

在为付款类别中注册的 AID 路由 NFC 触碰时,可使用“钱包”角色。除非已在前台运行为同一 AID 注册的另一个应用,否则点按操作会始终转到钱包角色持有者。

此角色还可用于确定钱包“快速访问”功能块在启用后应转到的位置。当角色设置为“无”时,“快速访问”功能块不可用,并且付款类别 NFC 触碰仅会传送到前台应用。

보안

Android 15는 앱의 보안을 강화하고 앱 데이터를 보호하며 사용자에게 데이터에 관한 더 높은 투명성과 제어 기능을 제공합니다. 사용자 보호 기능을 개선하고 새로운 위협으로부터 앱을 보호하기 위해 Google이 하고 있는 일을 자세히 알아보려면 Google I/O의 Android에서 사용자 보안 보호하기를 참고하세요.

엔드 투 엔드 암호화를 위한 키 관리

Android 15에 암호화 공개 키 저장을 위한 OS 수준 API를 제공하여 Android 앱의 엔드 투 엔드 암호화 (E2EE)를 용이하게 하는 E2eeContactKeysManager가 도입되었습니다.

E2eeContactKeysManager는 플랫폼 연락처 앱과 통합되도록 설계되어 사용자에게 연락처의 공개 키를 중앙에서 관리하고 확인하는 방법을 제공합니다.

콘텐츠 URI에 대한 권한 확인

Android 15 引入了一组可对内容 URI 执行权限检查的新 API:

접근성

Android 15에는 사용자의 접근성을 개선하는 기능이 추가되었습니다.

향상된 점자

Android 15에서는 TalkBack이 USB 및 보안 블루투스를 통해 HID 표준을 사용하는 점자 디스플레이를 지원할 수 있도록 했습니다.

마우스 및 키보드에서 사용하는 것과 매우 유사한 이 표준은 Android가 시간이 지남에 따라 더 다양한 점자 디스플레이를 지원하는 데 도움이 될 것입니다.

다국어 지원

Android 15에는 기기가 여러 언어로 사용될 때 사용자 환경을 보완하는 기능이 추가되었습니다.

CJK 가변 글꼴

从 Android 15 开始,中文、日语和韩语 (CJK) 语言的字体文件 NotoSansCJK 现已成为可变字体。可变字体为 CJK 语言的广告素材排版开辟了新的可能性。设计师可以探索更广泛的样式,并创建以前难以或无法实现的具有视觉冲击力的布局。

中文、日语和韩语 (CJK) 语言的可变字体在不同字体宽度下的显示效果。

문자 간 근거

从 Android 15 开始,可以使用 JUSTIFICATION_MODE_INTER_CHARACTER 利用字母间距将文本两端对齐。Android 8.0(API 级别 26)中首次引入了字词间对齐,而字符间对齐可为使用空格字符进行分割的语言(例如中文、日语等)提供类似的功能。

使用 JUSTIFICATION_MODE_NONE 的日语文本布局。
使用 JUSTIFICATION_MODE_NONE 的英语文本布局。


使用 JUSTIFICATION_MODE_INTER_WORD 的日语文本布局。
使用 JUSTIFICATION_MODE_INTER_WORD 的英语文本布局。


使用新版 JUSTIFICATION_MODE_INTER_CHARACTER 的日语文本布局。
使用新版 JUSTIFICATION_MODE_INTER_CHARACTER 的英语文本布局。

자동 줄바꿈 구성

Android 从 Android 13(API 级别 33)开始针对日语和韩语支持基于短语的换行符。不过,虽然基于短语的换行符可以提高短行文本的可读性,但不适用于较长的文本。在 Android 15 中,应用现在可以使用 LINE_BREAK_WORD_STYLE_AUTO 选项为短文本行应用基于短语的换行符。此选项用于选择最适合该文本的文字样式选项。

对于简短的文本行,使用基于短语的换行符,其功能与 LINE_BREAK_WORD_STYLE_PHRASE 相同,如下图所示:

对于简短的文本行,LINE_BREAK_WORD_STYLE_AUTO 会采用基于短语的换行符,以提高文本的可读性。 这与应用 LINE_BREAK_WORD_STYLE_PHRASE 相同。

对于较长的文本,LINE_BREAK_WORD_STYLE_AUTO 使用不换行的字词样式,其功能与 LINE_BREAK_WORD_STYLE_NONE 相同,如下图所示:

对于较长的文本,LINE_BREAK_WORD_STYLE_AUTO 不会应用换行字词样式,以提高文本的可读性。 这与应用 LINE_BREAK_WORD_STYLE_NONE 相同。

새로운 일본어 헨타이가나 글꼴

在 Android 15 中,默认情况下捆绑了旧版日语平假名(称为 Hentaigana)的新字体文件。形态独特的 Hentaigana 角色可为艺术作品或设计增添独特的风格,同时有助于准确传达和理解古代日本文献。

日语 Hentaigana 字体的字符和文字样式。

VideoLAN cone Copyright (c) 1996~2010 VideoLAN. 누구나 VideoLAN 프로젝트 또는 VideoLAN팀에서 개발한 제품을 언급하기 위해 이 로고 또는 수정된 버전을 사용하거나 수정할 수 있지만 프로젝트가 보증한다는 의미는 아닙니다.

Vulkan 및 Vulkan 로고는 Khronos Group Inc.의 등록 상표입니다.

OpenGL은 등록 상표이며 OpenGL ES 로고는 Khronos의 허가 하에 사용한 Hewlett Packard Enterprise의 상표입니다.