Android 14 มีการเปลี่ยนแปลงลักษณะการทำงานที่อาจส่งผลต่อรุ่นก่อนหน้านี้ แอปของคุณ การเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้มีผลเฉพาะกับแอปที่ ที่กำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไป หากแอปกำหนดเป้าหมายเป็น Android 14 ขึ้นไป คุณควรแก้ไขแอปให้รองรับลักษณะการทำงานเหล่านี้อย่างเหมาะสม หากมี
นอกจากนี้ โปรดตรวจสอบรายการการเปลี่ยนแปลงลักษณะการทำงานที่ส่งผลต่อแอปทั้งหมดที่ทำงานใน Android 14 โดยไม่คำนึงถึง targetSdkVersion
ของแอป
ฟังก์ชันหลัก
ต้องระบุประเภทบริการที่ทำงานอยู่เบื้องหน้า
หากแอปกำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไป แอปต้องระบุประเภทบริการที่ทำงานอยู่เบื้องหน้าอย่างน้อย 1 ประเภทสำหรับบริการที่ทำงานอยู่เบื้องหน้าแต่ละรายการภายในแอป คุณควรเลือกประเภทบริการที่ทำงานอยู่เบื้องหน้าที่แสดงถึง Use Case ของแอป ระบบคาดหวังว่าบริการที่ทำงานอยู่เบื้องหน้าซึ่งมีประเภทหนึ่งๆ จะเป็นไปตาม Use Case ที่เฉพาะเจาะจง
หากกรณีการใช้งานในแอปของคุณไม่เกี่ยวข้องกับประเภทใดเลย เราขอแนะนำให้ย้ายข้อมูลตรรกะของคุณเพื่อใช้ WorkManager หรือการโอนข้อมูลที่เริ่มต้นโดยผู้ใช้
การบังคับใช้สิทธิ์ BLUETOOTH_CONNECT ใน BluetoothAdapter
Android 14 จะบังคับใช้สิทธิ์ BLUETOOTH_CONNECT
เมื่อเรียกใช้เมธอด getProfileConnectionState()
ของ BluetoothAdapter
สำหรับแอปที่กำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไป
วิธีนี้ต้องใช้สิทธิ์ BLUETOOTH_CONNECT
อยู่แล้ว แต่ไม่มีการบังคับใช้ ตรวจสอบว่าแอปประกาศ BLUETOOTH_CONNECT
ในไฟล์ AndroidManifest.xml
ของแอปตามที่แสดงในข้อมูลโค้ดต่อไปนี้ และตรวจสอบว่าผู้ใช้ได้ให้สิทธิ์แล้วก่อนที่จะเรียกใช้ getProfileConnectionState
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
ข้อมูลอัปเดตเกี่ยวกับ OpenJDK 17
Android 14 ยังคงปรับปรุงไลบรารีหลักของ Android ให้สอดคล้องกับฟีเจอร์ใน OpenJDK LTS เวอร์ชันล่าสุด ซึ่งรวมถึงทั้งการอัปเดตไลบรารีและการรองรับภาษา Java 17 สําหรับนักพัฒนาแอปและแพลตฟอร์ม
การเปลี่ยนแปลงบางอย่างอาจส่งผลต่อความเข้ากันได้ของแอป
- การเปลี่ยนแปลงนิพจน์ทั่วไป: ตอนนี้ระบบไม่อนุญาตให้ใช้การอ้างอิงกลุ่มที่ไม่ถูกต้องเพื่อให้สอดคล้องกับความหมายของ OpenJDK มากขึ้น คุณอาจเห็นกรณีใหม่ซึ่งคลาส
java.util.regex.Matcher
แสดงข้อยกเว้นIllegalArgumentException
ดังนั้นโปรดทดสอบแอปในส่วนที่ใช้นิพจน์ทั่วไป หากต้องการเปิดหรือปิดใช้การเปลี่ยนแปลงนี้ขณะทดสอบ ให้สลับ FlagDISALLOW_INVALID_GROUP_REFERENCE
โดยใช้เครื่องมือเฟรมเวิร์กความเข้ากันได้ - การจัดการ UUID: ตอนนี้เมธอด
java.util.UUID.fromString()
จะตรวจสอบอย่างเข้มงวดมากขึ้นเมื่อตรวจสอบอาร์กิวเมนต์อินพุต คุณจึงอาจเห็นIllegalArgumentException
ระหว่างการแปลงข้อมูลย้อนกลับ หากต้องการเปิดหรือปิดใช้การเปลี่ยนแปลงนี้ขณะทดสอบ ให้สลับ FlagENABLE_STRICT_VALIDATION
โดยใช้เครื่องมือเฟรมเวิร์กความเข้ากันได้ - ปัญหาเกี่ยวกับ ProGuard: ในบางกรณี การเพิ่มคลาส
java.lang.ClassValue
จะทำให้เกิดปัญหาหากคุณพยายามบีบอัด สร้างความสับสน และเพิ่มประสิทธิภาพแอปโดยใช้ ProGuard ปัญหานี้เกิดจากไลบรารี Kotlin ที่เปลี่ยนลักษณะการทํางานรันไทม์โดยขึ้นอยู่กับว่าClass.forName("java.lang.ClassValue")
แสดงผลคลาสหรือไม่ หากแอปของคุณพัฒนาขึ้นโดยใช้รันไทม์เวอร์ชันเก่าที่ไม่มีคลาสjava.lang.ClassValue
อยู่ การเพิ่มประสิทธิภาพเหล่านี้อาจนําเมธอดcomputeValue
ออกจากคลาสที่มาจากjava.lang.ClassValue
JobScheduler เสริมการทำงานแบบเรียกกลับและเครือข่าย
自从引入后,JobScheduler 期望您的应用从
onStartJob
或 onStopJob
。在 Android 14 之前,如果作业运行时间过长,系统会停止作业并静默失败。如果您的应用以 Android 14(API 级别 34)或更高版本为目标平台,
超过在主线程上授予的时间,应用会触发 ANR
显示“没有响应 onStartJob
”错误消息或
“onStopJob
没有回复”。
此 ANR 可能是由以下 2 种情况造成的:
1.有工作阻塞主线程,阻止回调 onStartJob
或者onStopJob
在预期时间内执行并完成。
2. 开发者在 JobScheduler 中运行阻塞工作
回调 onStartJob
或 onStopJob
,阻止从
在预期的时限内完成
要解决第 1 个问题,您需要进一步调试阻塞主线程的因素
您可以使用以下代码
ApplicationExitInfo#getTraceInputStream()
,用于获取 Tombstone
ANR 发生时的跟踪信息如果您能够手动重现 ANR 问题
您可以录制系统轨迹,并使用
Android Studio 或 Perfetto,以便更好地了解应用上运行的
在发生 ANR 时调用主线程
请注意,直接使用 JobScheduler API 或使用 androidx 库 WorkManager 时可能会发生这种情况。
如需解决问题 2,请考虑迁移到 WorkManager,它支持将 onStartJob
或 onStopJob
中的任何处理封装在异步线程中。
JobScheduler
还引入了一项要求,即如果使用 setRequiredNetworkType
或 setRequiredNetwork
约束条件,则必须声明 ACCESS_NETWORK_STATE
权限。如果您的应用未声明
ACCESS_NETWORK_STATE
权限
Android 14 或更高版本,则会导致 SecurityException
。
Tiles Launch API
สำหรับแอปที่กำหนดเป้าหมายเป็น Android 14 ขึ้นไป ระบบจะเลิกใช้งาน TileService#startActivityAndCollapse(Intent)
และตอนนี้จะแสดงข้อยกเว้นเมื่อเรียกใช้ หากแอปเปิดกิจกรรมจากการ์ด ให้ใช้
TileService#startActivityAndCollapse(PendingIntent)
แทน
ความเป็นส่วนตัว
การเข้าถึงรูปภาพและวิดีโอบางส่วน
Android 14 เปิดตัวการเข้าถึงรูปภาพที่เลือก ซึ่งช่วยให้ผู้ใช้สามารถให้สิทธิ์แอปเข้าถึงรูปภาพและวิดีโอที่เฉพาะเจาะจงในคลังได้ แทนที่จะให้สิทธิ์เข้าถึงสื่อทั้งหมดในประเภทหนึ่งๆ
การเปลี่ยนแปลงนี้จะเปิดใช้ก็ต่อเมื่อแอปกำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไปเท่านั้น หากคุณยังไม่ได้ใช้เครื่องมือเลือกรูปภาพ เราขอแนะนำให้ติดตั้งใช้งานในแอปเพื่อให้ผู้ใช้ได้รับประสบการณ์ที่สม่ำเสมอในการเลือกรูปภาพและวิดีโอ รวมถึงช่วยเพิ่มความเป็นส่วนตัวของผู้ใช้โดยไม่ต้องขอสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล
หากคุณดูแลรักษาเครื่องมือเลือกแกลเลอรีของคุณเองโดยใช้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลและต้องการควบคุมการติดตั้งใช้งานอย่างเต็มรูปแบบ ให้ปรับการติดตั้งใช้งานเพื่อใช้สิทธิ์ READ_MEDIA_VISUAL_USER_SELECTED
ใหม่ หากแอปของคุณไม่ได้ใช้สิทธิ์ใหม่ ระบบจะเรียกใช้แอปในโหมดความเข้ากันได้
ประสบการณ์ของผู้ใช้
รับการแจ้งเตือน Intent แบบเต็มหน้าจอที่ปลอดภัย
ใน Android 11 (API ระดับ 30) แอปใดก็ได้ที่จะใช้ Notification.Builder.setFullScreenIntent
เพื่อส่ง Intent แบบเต็มหน้าจอได้ขณะที่โทรศัพท์ล็อกอยู่ คุณสามารถให้สิทธิ์นี้โดยอัตโนมัติเมื่อติดตั้งแอปโดยประกาศสิทธิ์ USE_FULL_SCREEN_INTENT
ใน AndroidManifest
การแจ้งเตือน Intent แบบเต็มหน้าจอออกแบบมาเพื่อแจ้งเตือนที่มีลำดับความสำคัญสูงมากซึ่งต้องการให้ผู้ใช้สนใจในทันที เช่น การโทรเข้าหรือการตั้งค่านาฬิกาปลุกที่ผู้ใช้กำหนดค่าไว้ สำหรับแอปที่กำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไป แอปที่ได้รับอนุญาตให้ใช้สิทธิ์นี้จะจำกัดไว้เฉพาะแอปที่มีการโทรและการปลุกเท่านั้น Google Play Store จะเพิกถอนสิทธิ์ USE_FULL_SCREEN_INTENT
เริ่มต้นสำหรับแอปที่ไม่ตรงกับโปรไฟล์นี้ กำหนดเวลาสำหรับการเปลี่ยนแปลงนโยบายเหล่านี้คือ31 พฤษภาคม 2024
สิทธิ์นี้จะยังคงเปิดใช้อยู่สำหรับแอปที่ติดตั้งในโทรศัพท์ก่อนที่ผู้ใช้จะอัปเดตเป็น Android 14 ผู้ใช้จะเปิดหรือปิดสิทธิ์นี้ได้
คุณสามารถใช้ API ใหม่ NotificationManager.canUseFullScreenIntent
เพื่อตรวจสอบว่าแอปของคุณมีสิทธิ์หรือไม่ หากไม่มี แอปจะใช้ Intent ใหม่ ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
เพื่อเปิดหน้าการตั้งค่าที่ผู้ใช้สามารถให้สิทธิ์ได้
ความปลอดภัย
ข้อจํากัดของ Intent ที่ไม่ชัดแจ้งและที่รอดำเนินการ
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,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,则系统会抛出 ActivityNotFoundException
异常:
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION "))
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION "));
如需启动非导出的 activity,应用应改用显式 intent:
// This makes the intent explicit. val explicitIntent = Intent("com.example.action.APP_ACTION ") explicitIntent.apply { package = context.packageName } context.startActivity(explicitIntent)
// This makes the intent explicit. Intent explicitIntent = new Intent("com.example.action.APP_ACTION ") explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent);
Broadcast Receiver ที่ลงทะเบียนรันไทม์ต้องระบุลักษณะการส่งออก
แอปและบริการที่กำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไปและใช้ตัวรับที่ลงทะเบียนตามบริบทต้องระบุ Flag เพื่อระบุว่าควรส่งออกตัวรับไปยังแอปอื่นๆ ทั้งหมดในอุปกรณ์หรือไม่ โดยจะใช้ RECEIVER_EXPORTED
หรือ RECEIVER_NOT_EXPORTED
ตามลำดับ
ข้อกำหนดนี้ช่วยปกป้องแอปจากช่องโหว่ด้านความปลอดภัยด้วยการใช้ฟีเจอร์สำหรับรีซีฟเวอร์เหล่านี้ซึ่งเปิดตัวใน Android 13
ข้อยกเว้นสำหรับผู้รับที่รับเฉพาะการออกอากาศของระบบ
หากแอปลงทะเบียนตัวรับสำหรับการออกอากาศของระบบผ่านContext#registerReceiver
วิธีต่างๆ เท่านั้น เช่น Context#registerReceiver()
ก็ไม่ควรระบุ Flag เมื่อลงทะเบียนตัวรับ
การโหลดโค้ดแบบไดนามิกที่ปลอดภัยยิ่งขึ้น
หากแอปกำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไปและใช้การโหลดโค้ดแบบไดนามิก (DCL) คุณต้องทําเครื่องหมายไฟล์ที่โหลดแบบไดนามิกทั้งหมดเป็นแบบอ่านอย่างเดียว มิฉะนั้น ระบบจะแสดงข้อยกเว้น เราขอแนะนำให้แอปหลีกเลี่ยงการโหลดโค้ดแบบไดนามิกทุกครั้งที่ทำได้ เนื่องจากการดำเนินการดังกล่าวจะเพิ่มความเสี่ยงอย่างมากที่แอปจะเกิดการประนีประนอมจากการแทรกโค้ดหรือการดัดแปลงโค้ด
หากต้องโหลดโค้ดแบบไดนามิก ให้ใช้แนวทางต่อไปนี้เพื่อตั้งค่าไฟล์ที่โหลดแบบไดนามิก (เช่น ไฟล์ DEX, JAR หรือ APK) เป็นอ่านอย่างเดียวทันทีที่เปิดไฟล์และก่อนที่จะมีการเขียนเนื้อหา
val jar = File("DYNAMICALLY_LOADED_FILE .jar")
val os = FileOutputStream(jar)
os.use {
// Set the file to read-only first to prevent race conditions
jar.setReadOnly()
// Then write the actual file content
}
val cl = PathClassLoader(jar, parentClassLoader)
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 (API ระดับ 34) ขึ้นไป ระบบจะจำกัดเพิ่มเติมว่าแอปจะได้รับอนุญาตให้เริ่มกิจกรรมจากเบื้องหลังเมื่อใด
- เมื่อแอปส่ง
PendingIntent
โดยใช้PendingIntent#send()
หรือวิธีการที่คล้ายกัน แอปต้องเลือกใช้หากต้องการมอบสิทธิ์การเริ่มกิจกรรมเบื้องหลังของตนเองเพื่อเริ่ม Intent ที่รอดำเนินการ หากต้องการเลือกใช้ แอปควรส่งActivityOptions
Bundle ที่มีsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
- เมื่อแอปที่มองเห็นได้เชื่อมโยงบริการของแอปอื่นที่อยู่ในเบื้องหลังโดยใช้เมธอด
bindService()
ตอนนี้แอปที่มองเห็นได้ต้องเลือกใช้หากต้องการมอบสิทธิ์การเริ่มกิจกรรมเบื้องหลังของตนเองให้กับบริการที่เชื่อมโยง หากต้องการเลือกใช้ แอปควรระบุ FlagBIND_ALLOW_ACTIVITY_STARTS
เมื่อเรียกใช้เมธอดbindService()
การเปลี่ยนแปลงเหล่านี้จะขยายชุดข้อจำกัดที่มีอยู่เพื่อปกป้องผู้ใช้โดยการป้องกันการที่แอปที่เป็นอันตรายจะละเมิด API เพื่อเริ่มกิจกรรมที่รบกวนจากเบื้องหลัง
Zip Path Traversal
สําหรับแอปที่กําหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไป Android จะป้องกันช่องโหว่ Path Traversal ของไฟล์ ZIP ดังนี้
ZipFile(String)
และ
ZipInputStream.getNextEntry()
จะแสดงข้อผิดพลาด ZipException
หากชื่อรายการไฟล์ ZIP มี ".." หรือขึ้นต้นด้วย "/"
แอปสามารถเลือกไม่ใช้การตรวจสอบนี้ได้โดยเรียกใช้ dalvik.system.ZipPathValidator.clearCallback()
ต้องได้รับความยินยอมจากผู้ใช้ในเซสชันการจับภาพการฉายภาพสื่อแต่ละเซสชัน
สำหรับแอปที่กำหนดเป้าหมายเป็น Android 14 (API ระดับ 34) ขึ้นไป SecurityException
จะแสดงขึ้นโดย MediaProjection#createVirtualDisplay
ในกรณีต่อไปนี้
- แอปของคุณจะแคช
Intent
ที่แสดงผลจากMediaProjectionManager#createScreenCaptureIntent
และส่งIntent
นั้นให้กับMediaProjectionManager#getMediaProjection
หลายครั้ง - แอปของคุณเรียกใช้
MediaProjection#createVirtualDisplay
หลายครั้งในMediaProjection
อินสแตนซ์เดียวกัน
แอปของคุณต้องขอให้ผู้ใช้ให้ความยินยอมก่อนเซสชันการจับภาพแต่ละครั้ง เซสชันการบันทึกเดียวคือการเรียกใช้ MediaProjection#createVirtualDisplay
ครั้งเดียว และต้องใช้อินสแตนซ์ MediaProjection
แต่ละรายการเพียงครั้งเดียว
จัดการการเปลี่ยนแปลงการกำหนดค่า
หากแอปของคุณต้องการเรียกใช้ MediaProjection#createVirtualDisplay
เพื่อจัดการการเปลี่ยนแปลงการกำหนดค่า (เช่น การวางแนวหน้าจอหรือการเปลี่ยนแปลงขนาดหน้าจอ) ให้ทำตามขั้นตอนต่อไปนี้เพื่ออัปเดต VirtualDisplay
สำหรับอินสแตนซ์ MediaProjection
ที่มีอยู่
- เรียกใช้
VirtualDisplay#resize
โดยใช้ความกว้างและความสูงใหม่ - ระบุ
Surface
ใหม่ที่มีความกว้างและความสูงใหม่ให้กับVirtualDisplay#setSurface
ลงทะเบียนการโทรกลับ
แอปของคุณควรลงทะเบียนการเรียกกลับเพื่อจัดการกรณีที่ผู้ใช้ไม่ให้ความยินยอมในการบันทึกเซสชันต่อไป โดยให้ใช้ Callback#onStop
และแอปของคุณเผยแพร่ทรัพยากรที่เกี่ยวข้อง (เช่น VirtualDisplay
และ Surface
)
หากแอปไม่ได้ลงทะเบียนการเรียกกลับนี้ MediaProjection#createVirtualDisplay
จะแสดง IllegalStateException
เมื่อแอปเรียกใช้
ข้อจำกัดที่ไม่ใช่ SDK ที่อัปเดต
Android 14 มีรายการอินเทอร์เฟซที่ไม่ใช่ SDK ซึ่งถูกจำกัดซึ่งอัปเดตแล้วโดยอิงตามการทำงานร่วมกันกับนักพัฒนาแอป Android และการทดสอบภายในครั้งล่าสุด เราจะตรวจสอบว่ามีทางเลือกสาธารณะให้ใช้งานก่อนที่จะจำกัดอินเทอร์เฟซที่ไม่ใช่ SDK ทุกครั้งที่ทำได้
หากแอปไม่ได้กำหนดเป้าหมายเป็น Android 14 การเปลี่ยนแปลงบางอย่างเหล่านี้ อาจไม่ส่งผลกระทบต่อคุณโดยทันที อย่างไรก็ตาม แม้ว่าขณะนี้คุณสามารถใช้ อินเทอร์เฟซที่ไม่ใช่ SDK (ขึ้นอยู่กับ API เป้าหมายของแอปคุณ ระดับ) การใช้เมธอดหรือฟิลด์ที่ไม่ใช่ SDK มีความเสี่ยงสูงเสมอที่จะทำให้ แอป
หากไม่แน่ใจว่าแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK หรือไม่ คุณสามารถทดสอบแอปเพื่อดูข้อมูลดังกล่าว หากแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK คุณควรเริ่มวางแผน การย้ายข้อมูลไปใช้ทางเลือก SDK อย่างไรก็ตาม เราเข้าใจดีว่าบางแอป กรณีการใช้งานที่ถูกต้องสำหรับการใช้อินเทอร์เฟซที่ไม่ใช่ SDK หากไม่พบวิธีอื่นแทนการใช้อินเทอร์เฟซที่ไม่ใช่ SDK สำหรับฟีเจอร์ในแอป คุณควรขอ API สาธารณะใหม่
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงใน Android เวอร์ชันนี้ได้ที่การอัปเดตข้อจํากัดอินเทอร์เฟซที่ไม่ใช่ SDK ใน Android 14 ดูข้อมูลเพิ่มเติมเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK โดยทั่วไปได้ที่ข้อจำกัดเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK