แพลตฟอร์ม Android 17 มีการเปลี่ยนแปลงลักษณะการทำงานที่อาจส่งผลต่อแอปของคุณ
การเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้จะมีผลกับแอปทั้งหมดเมื่อทำงานใน Android 17 โดยไม่คำนึงถึง targetSdkVersion คุณควรทดสอบแอปแล้วแก้ไขตามความจำเป็นเพื่อรองรับการเปลี่ยนแปลงเหล่านี้ (หากมี)
อย่าลืมตรวจสอบรายการการเปลี่ยนแปลงลักษณะการทำงานที่มีผลกับแอปที่กำหนดเป้าหมายเป็น Android 17 เท่านั้นด้วย
ฟังก์ชันหลัก
Android 17 (API ระดับ 37) มีการเปลี่ยนแปลงต่อไปนี้ซึ่งปรับเปลี่ยนหรือขยายความสามารถหลักต่างๆ ของระบบ Android
การจำกัดการใช้หน่วยความจำของแอป
Android 17 มีการจำกัดหน่วยความจำของแอปตาม RAM ทั้งหมดของอุปกรณ์เพื่อสร้างสภาพแวดล้อมที่เสถียรและกำหนดได้มากขึ้นสำหรับแอปและผู้ใช้ Android ขีดจำกัดเหล่านี้มุ่งเน้นที่หน่วยความจำรั่วไหลและค่าผิดปกติอื่นๆ ก่อนที่จะทำให้ระบบทั้งหมดไม่เสถียร ซึ่งส่งผลให้ UI กระตุก แบตเตอรี่หมดเร็วขึ้น และแอปถูกปิด แม้ว่าเราคาดว่าจะมีผลกระทบน้อยมากต่อเซสชันแอปส่วนใหญ่ แต่เราขอแนะนำให้ทำตามแนวทางปฏิบัติแนะนำเกี่ยวกับหน่วยความจำต่อไปนี้ ซึ่งรวมถึงการสร้างเกณฑ์พื้นฐานสำหรับหน่วยความจำ
คุณสามารถตรวจสอบว่าเซสชันของแอปได้รับผลกระทบหรือไม่โดยเรียกใช้ getDescription ใน ApplicationExitInfo หากแอปได้รับผลกระทบ เหตุผลในการออกจะเป็น REASON_OTHER และคำอธิบายจะมีสตริง "MemoryLimiter:AnonSwap" พร้อมกับข้อมูลอื่นๆ นอกจากนี้ คุณยังใช้การทำโปรไฟล์ตามทริกเกอร์กับ TRIGGER_TYPE_ANOMALY เพื่อรับฮีปดัมป์ที่รวบรวมไว้เมื่อถึงขีดจำกัดหน่วยความจำได้ด้วย
เอกสารประกอบจัดการหน่วยความจำของแอปให้ข้อมูลที่จะช่วยคุณวินิจฉัยปัญหาเกี่ยวกับหน่วยความจำของแอปและเพิ่มประสิทธิภาพการใช้ทรัพยากร
ทดสอบลักษณะการทำงานของแอปภายใต้ข้อจำกัดด้านหน่วยความจำ
คุณสามารถใช้ Android Debug Bridge (adb) เพื่อปรับหรือปิดใช้ขีดจำกัดหน่วยความจำในอุปกรณ์ที่กำหนดขีดจำกัดดังกล่าวได้ คำสั่ง Shell am มีคำสั่งย่อย 3 รายการเพื่อปรับขีดจำกัดหน่วยความจำ (คำสั่งเหล่านี้ไม่มีผลกับอุปกรณ์ที่ไม่ได้กำหนดขีดจำกัดหน่วยความจำ)
am memory-limiter ignore <uid>|none|allam memory-limiter manual <pid> <limit>|max|noneam memory-limiter status
ignoreสั่งให้ตัวจำกัดหน่วยความจำละเว้นบางกระบวนการหรือทั้งหมด การส่ง UID (รหัสผู้ใช้ Android) จะสั่งให้ตัวจำกัดหน่วยความจำละเว้นการบังคับใช้กับกระบวนการทั้งหมดที่เชื่อมโยงกับ UID นั้น นอกจากนี้ คุณยังส่ง
all(ละเว้นแอปทั้งหมด) หรือnone(ไม่ละเว้นแอปใดๆ) ได้ด้วย การส่งnoneจะลบล้างการเรียกใช้am memory-limiter ignoreก่อนหน้านี้หากคุณสั่งให้ตัวจำกัดหน่วยความจำละเว้น UID คุณจะยังคงใช้ขีดจำกัดหน่วยความจำด้วยตนเองกับกระบวนการภายในแอปได้โดยเรียกใช้
am memory-limiter manualmanualสั่งให้ระบบกำหนดข้อจำกัดหน่วยความจำในกระบวนการด้วย PID (รหัสกระบวนการ) ที่ระบุ ข้อจำกัดของหน่วยความจำจะระบุเป็นจำนวนเต็มของ MB เช่น การส่ง
30จะระบุว่ากระบวนการถูกจำกัดไว้ที่หน่วยความจำ 30 MB การส่งmaxจะนำขีดจำกัดหน่วยความจำทั้งหมดในกระบวนการนั้นออก การส่งnoneจะนำขีดจำกัดที่ตั้งค่าด้วยตนเองในกระบวนการออก และคืนค่าขีดจำกัดเริ่มต้นของระบบ (หากมี)statusรายงานสถานะปัจจุบันของตัวจำกัดหน่วยความจำ สถานะจะรวมขีดจำกัดหน่วยความจำที่กำหนดไว้ในกระบวนการที่มองเห็นได้และมองไม่เห็น
ความเป็นส่วนตัว
Android 17 มีการเปลี่ยนแปลงต่อไปนี้เพื่อปรับปรุงความเป็นส่วนตัวของผู้ใช้
การป้องกัน OTP ทาง SMS
ตั้งแต่ Android 17 เป็นต้นไป Android จะขยายการปกป้องข้อความ SMS ที่มีรหัสผ่านแบบใช้ครั้งเดียว (OTP)
ใน Android เวอร์ชันก่อนหน้า การปกป้องนี้มุ่งเน้นไปที่รูปแบบ SMS Retriever เป็นหลัก การส่งข้อความที่มีแฮช SMS Retriever ล่าช้าเป็นเวลา 3 ชั่วโมงสำหรับแอปส่วนใหญ่ อย่างไรก็ตาม แอปบางแอป (เช่น เครื่องจัดการ SMS เริ่มต้น) ได้รับการยกเว้นจากความล่าช้า และแอปที่เป็นเจ้าของแฮชก็ได้รับการยกเว้นด้วย
ตั้งแต่ Android 17 เป็นต้นไป การปกป้องนี้จะมีผลกับข้อความรูปแบบ WebOTP ด้วย หากแอปมีสิทธิ์อ่านข้อความ SMS แต่ไม่ใช่ผู้รับที่ต้องการของข้อความ WebOTP (ตามที่กำหนดโดยการยืนยันโดเมน) แอปจะเข้าถึงข้อความไม่ได้จนกว่าจะผ่านไป 3 ชั่วโมงหลังจากได้รับข้อความ การเปลี่ยนแปลงนี้มีวัตถุประสงค์เพื่อปรับปรุงความปลอดภัยของผู้ใช้โดยตรวจสอบว่ามีเพียงแอปที่เชื่อมโยงกับโดเมนที่ระบุไว้ในข้อความเท่านั้นที่สามารถอ่านรหัสยืนยันแบบเป็นโปรแกรมได้
ในระหว่างการหน่วงเวลา 3 ชั่วโมงนี้ ระบบจะระงับการออกอากาศ SMS_RECEIVED_ACTION และกรองการค้นหาฐานข้อมูลผู้ให้บริการ SMS แอปเหล่านี้จะได้รับข้อความ SMS หลังจากเกิดความล่าช้า การเปลี่ยนแปลงนี้จะมีผลกับแอปทั้งหมด ไม่ว่าจะมีระดับ API เป้าหมายใดก็ตาม
แอปบางแอป เช่น แอปผู้ช่วย SMS เริ่มต้น แอปที่ใช้ร่วมกันของอุปกรณ์ที่เชื่อมต่อ ฯลฯ จะได้รับการยกเว้นจากความล่าช้านี้ แอปทั้งหมดที่อาศัยการอ่านข้อความ SMS เพื่อดึงข้อมูล OTP ควรเปลี่ยนไปใช้ API SMS Retriever หรือ SMS User Consent เพื่อให้ฟังก์ชันการทำงานยังคงใช้งานได้ต่อไป
ความปลอดภัย
Android 17 มีการปรับปรุงความปลอดภัยของอุปกรณ์และแอปดังต่อไปนี้
แผนการเลิกใช้งาน usesClearTraffic
เราวางแผนที่จะเลิกใช้งานองค์ประกอบ usesCleartextTraffic ในรุ่นถัดไป
แอปที่ต้องทำการเชื่อมต่อแบบไม่เข้ารหัส (HTTP) ควรย้ายข้อมูลไปใช้ไฟล์การกำหนดค่าการรักษาความปลอดภัยของเครือข่าย ซึ่งช่วยให้คุณระบุโดเมนที่แอปต้องทำการเชื่อมต่อแบบข้อความที่โอนหรือจัดเก็บได้โดยไม่ต้องเข้ารหัส
โปรดทราบว่าไฟล์การกำหนดค่าการรักษาความปลอดภัยของเครือข่ายใช้ได้ใน API ระดับ 24 ขึ้นไปเท่านั้น หากแอปมีระดับ API ขั้นต่ำต่ำกว่า 24 คุณควรทำทั้ง 2 อย่างต่อไปนี้
- ตั้งค่าแอตทริบิวต์
usesCleartextTrafficเป็นtrue - ใช้ไฟล์การกำหนดค่าเครือข่าย
หากระดับ API ขั้นต่ำของแอปคือ 24 ขึ้นไป คุณสามารถใช้ไฟล์การกำหนดค่าเครือข่ายและไม่จำเป็นต้องตั้งค่า usesCleartextTraffic
จำกัดการให้สิทธิ์ URI โดยนัย
ปัจจุบัน หากแอปเปิด Intent ด้วย URI ที่มีการดำเนินการ ACTION_SEND, ACTION_SEND_MULTIPLE หรือ ACTION_IMAGE_CAPTURE ระบบจะให้สิทธิ์ URI อ่านและเขียนแก่แอปเป้าหมายโดยอัตโนมัติ ตั้งแต่ Android 18 เป็นต้นไป ระบบจะไม่ให้สิทธิ์เหล่านี้โดยอัตโนมัติอีกต่อไป ด้วยเหตุนี้ เราขอแนะนำให้แอปให้สิทธิ์ URI ที่เกี่ยวข้องอย่างชัดเจนแทนที่จะพึ่งพาระบบในการให้สิทธิ์
หากต้องการตรวจหาการใช้งาน Intent เหล่านี้ในแอป ให้ใช้ StrictMode กับ detectImplicitUriPermissionGrant() เพื่อทริกเกอร์การละเมิด
Kotlin
val policy = StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build() StrictMode.setVmPolicy(policy)
Java
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build(); StrictMode.setVmPolicy(policy);
หรือจะตรวจสอบข้อยกเว้นที่บันทึกไว้ซึ่งมีข้อความ Please set the grant explicitly in the app ที่ปรากฏขึ้นเมื่อระบบตั้งค่าการให้สิทธิ์โดยนัยก็ได้ คุณตรวจสอบบันทึกเหล่านี้ได้โดยใช้คำสั่ง adb ต่อไปนี้
adb logcat | grep "Please set the grant explicitly in the app"
หากต้องการให้สิทธิ์ที่จำเป็นอย่างชัดแจ้ง ให้เพิ่มแฟล็ก FLAG_GRANT_READ_URI_PERMISSION ลงใน Intent ACTION_SEND และ ACTION_SEND_MULTIPLE ดังนี้
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
รวมทั้งแฟล็ก FLAG_GRANT_READ_URI_PERMISSION และ FLAG_GRANT_WRITE_URI_PERMISSION สำหรับ Intent ACTION_IMAGE_CAPTURE:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
ขีดจำกัด Keystore ต่อแอป
แอปควรหลีกเลี่ยงการสร้างคีย์จำนวนมากเกินไปใน Android Keystore เนื่องจากเป็นทรัพยากรที่แชร์สำหรับแอปทั้งหมดในอุปกรณ์ ตั้งแต่ Android 17 เป็นต้นไป ระบบจะจำกัดจำนวนคีย์ที่แอปเป็นเจ้าของได้ ขีดจำกัดคือ 50,000 คีย์สำหรับแอปที่ไม่ใช่แอประบบที่กำหนดเป้าหมายเป็น Android 17 (ระดับ API 37) ขึ้นไป และ 200,000 คีย์สำหรับแอปอื่นๆ ทั้งหมด แอปของระบบมีขีดจำกัดคีย์อยู่ที่ 200,000 คีย์ ไม่ว่าจะกำหนดเป้าหมายเป็นระดับ API ใดก็ตาม
หากแอปพยายามสร้างคีย์เกินขีดจำกัด การสร้างจะไม่สำเร็จและแสดงข้อผิดพลาด KeyStoreException สตริงข้อความของข้อยกเว้นจะมีข้อมูลเกี่ยวกับขีดจำกัดของคีย์ หากแอปเรียกใช้ getNumericErrorCode() ในข้อยกเว้น ค่าที่แสดงผลจะขึ้นอยู่กับระดับ API ที่แอปกำหนดเป้าหมาย ดังนี้
- แอปที่กำหนดเป้าหมายเป็น Android 17 (API ระดับ 37) ขึ้นไป:
getNumericErrorCode()จะแสดงผลค่าERROR_TOO_MANY_KEYSใหม่ - แอปอื่นๆ ทั้งหมด:
getNumericErrorCode()แสดงผลERROR_INCORRECT_USAGE
บล็อกการเข้าชมแบบ Loopback ข้ามโปรไฟล์
ตั้งแต่ Android 17 เป็นต้นไป ระบบจะไม่อนุญาตการรับส่งข้อมูลแบบ Loopback ข้ามโปรไฟล์โดยค่าเริ่มต้นอีกต่อไป การเข้าชมแบบ Loopback ภายในโปรไฟล์เดียวกันจะไม่ได้รับผลกระทบ การเปลี่ยนแปลงนี้มีผลกับแอปทั้งหมดที่ทำงานบน Android 17 ขึ้นไป ไม่ว่าแอปจะกำหนดเป้าหมายเป็นระดับ API ใดก็ตาม
ประสบการณ์ของผู้ใช้และ UI ของระบบ
Android 17 มีการเปลี่ยนแปลงต่อไปนี้ซึ่งมีจุดประสงค์เพื่อสร้างประสบการณ์ของผู้ใช้ที่สอดคล้องและใช้งานง่ายยิ่งขึ้น
การคืนค่าระดับการเข้าถึง IME เริ่มต้นหลังจากการหมุน
ตั้งแต่ Android 17 เป็นต้นไป เมื่อการกำหนดค่าของอุปกรณ์เปลี่ยนแปลง (เช่น ผ่านการหมุน) และแอปไม่ได้จัดการการเปลี่ยนแปลงนี้เอง ระบบจะไม่กู้คืนระดับการเข้าถึง IME ก่อนหน้า
หากแอปมีการเปลี่ยนแปลงการกำหนดค่าที่ไม่ได้จัดการ และแอปต้องการให้แป้นพิมพ์ปรากฏหลังจากการเปลี่ยนแปลง คุณต้องขออย่างชัดแจ้ง คุณส่งคำขอนี้ได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- ตั้งค่าแอตทริบิวต์
android:windowSoftInputModeเป็นstateAlwaysVisible - ขอแป้นพิมพ์เสมือนแบบเป็นโปรแกรมในเมธอด
onCreate()ของกิจกรรม หรือเพิ่มเมธอดonConfigurationChanged()
อินพุตจากมนุษย์
Android 17 มีการเปลี่ยนแปลงต่อไปนี้ซึ่งส่งผลต่อวิธีที่แอปโต้ตอบกับอุปกรณ์อินพุตของมนุษย์ เช่น แป้นพิมพ์และทัชแพด
ทัชแพดจะส่งเหตุการณ์ที่เกี่ยวข้องโดยค่าเริ่มต้นระหว่างการจับภาพเคอร์เซอร์
ตั้งแต่ Android 17 เป็นต้นไป หากแอปขอการจับตัวชี้โดยใช้ View.requestPointerCapture() และผู้ใช้ใช้ทัชแพด ระบบจะจดจำการเคลื่อนไหวของตัวชี้และท่าทางการเลื่อนจากการสัมผัสของผู้ใช้ และรายงานไปยังแอปในลักษณะเดียวกับการเคลื่อนไหวของตัวชี้และปุ่มลูกกลิ้งจากเมาส์ที่จับได้ ในกรณีส่วนใหญ่ วิธีนี้จะช่วยให้แอปที่รองรับเมาส์ที่ถูกจับไม่ต้องเพิ่มตรรกะการจัดการพิเศษสำหรับทัชแพด ดูรายละเอียดเพิ่มเติมได้ในเอกสารประกอบของ View.POINTER_CAPTURE_MODE_RELATIVE
ก่อนหน้านี้ ระบบไม่ได้พยายามจดจำท่าทางสัมผัสจากทัชแพด แต่จะส่งตำแหน่งนิ้วแบบสัมบูรณ์ดิบไปยังแอปในรูปแบบที่คล้ายกับการสัมผัสหน้าจอสัมผัสแทน หากแอปยังคงต้องการข้อมูลสัมบูรณ์นี้ แอปควรเรียกใช้เมธอด View.requestPointerCapture(int) ใหม่ด้วย View.POINTER_CAPTURE_MODE_ABSOLUTE แทน
สื่อ
Android 17 มีการเปลี่ยนแปลงต่อไปนี้ในลักษณะการทำงานของสื่อ
การเพิ่มความปลอดภัยของเสียงในเบื้องหลัง
ตั้งแต่ Android 17 เป็นต้นไป เฟรมเวิร์กเสียงจะบังคับใช้ข้อจำกัดเกี่ยวกับการโต้ตอบกับเสียงในเบื้องหลัง ซึ่งรวมถึงการเล่นเสียง คำขอโฟกัสเสียง และ API การเปลี่ยนแปลงระดับเสียง เพื่อให้มั่นใจว่าการเปลี่ยนแปลงเหล่านี้เริ่มต้นโดยเจตนาของผู้ใช้
หากแอปพยายามเรียกใช้ Audio API ขณะที่แอปไม่ได้อยู่ในวงจรที่ถูกต้อง API การเล่นเสียงและการเปลี่ยนแปลงระดับเสียงจะไม่ทำงานโดยไม่มีการแสดงข้อยกเว้นหรือข้อความแสดงข้อผิดพลาด API โฟกัสเสียงไม่สำเร็จโดยมีรหัสผลลัพธ์ AUDIOFOCUS_REQUEST_FAILED
ดูข้อมูลเพิ่มเติม รวมถึงกลยุทธ์การลดความเสี่ยงได้ที่การเพิ่มความปลอดภัยของเสียงในเบื้องหลัง
การเชื่อมต่อ
Android 17 มีการเปลี่ยนแปลงต่อไปนี้เพื่อปรับปรุงการเชื่อมต่ออุปกรณ์
การจับคู่อีกครั้งโดยอัตโนมัติเมื่อการเชื่อมต่อบลูทูธขาดหาย
Android 17 เปิดตัวการจับคู่ใหม่โดยอัตโนมัติ ซึ่งเป็นการปรับปรุงระดับระบบที่ออกแบบมาเพื่อแก้ไขปัญหาการสูญเสียการเชื่อมต่อบลูทูธโดยอัตโนมัติ
ก่อนหน้านี้ หากการเชื่อมต่อขาดหายไป ผู้ใช้ต้องไปที่การตั้งค่าด้วยตนเองเพื่อเลิกจับคู่ แล้วจับคู่อุปกรณ์ต่อพ่วงอีกครั้ง ฟีเจอร์นี้ต่อยอดจากการปรับปรุงด้านความปลอดภัยของ Android 16 โดยช่วยให้ระบบสร้างการเชื่อมโยงใหม่ในเบื้องหลังได้โดยที่ผู้ใช้ไม่ต้องไปที่การตั้งค่าเพื่อเลิกจับคู่และจับคู่อุปกรณ์ต่อพ่วงอีกครั้งด้วยตนเอง
แม้ว่าแอปส่วนใหญ่จะไม่ต้องทำการเปลี่ยนแปลงโค้ด แต่นักพัฒนาแอปควรทราบถึงการเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้ในสแต็กบลูทูธ
- บริบทการจับคู่ใหม่: ตอนนี้
ACTION_PAIRING_REQUESTมีEXTRA_PAIRING_CONTEXTเพิ่มเติม ซึ่งช่วยให้แอปแยกความแตกต่างระหว่างคำขอจับคู่มาตรฐานกับความพยายามในการจับคู่ใหม่ที่ระบบเริ่มต้นโดยอัตโนมัติได้ - การอัปเดตคีย์แบบมีเงื่อนไข: ระบบจะแทนที่คีย์ความปลอดภัยที่มีอยู่ก็ต่อเมื่อการจับคู่ใหม่สำเร็จและการเชื่อมต่อใหม่มีระดับการรักษาความปลอดภัยเท่ากับหรือสูงกว่าการเชื่อมต่อก่อนหน้า
- เวลาที่แก้ไข Intent: ตอนนี้ระบบจะประกาศ Intent
ACTION_KEY_MISSINGเฉพาะในกรณีที่การพยายามซ่อมแซมโดยอัตโนมัติไม่สำเร็จเท่านั้น ซึ่งจะช่วยลดการจัดการข้อผิดพลาดที่ไม่จำเป็นในแอปหากระบบกู้คืนการเชื่อมโยงในเบื้องหลังได้สำเร็จ - การแจ้งเตือนผู้ใช้: ระบบจะจัดการการจับคู่อีกครั้งผ่านการแจ้งเตือนและกล่องโต้ตอบ UI ใหม่ ระบบจะแจ้งให้ผู้ใช้ยืนยันการพยายามจับคู่อีกครั้งเพื่อให้แน่ใจว่าผู้ใช้ทราบถึงการเชื่อมต่อใหม่
ผู้ผลิตอุปกรณ์ต่อพ่วงและนักพัฒนาแอปที่ใช้ร่วมกันควรตรวจสอบว่าฮาร์ดแวร์และแอปจัดการการเปลี่ยนผ่านการเชื่อมโยงได้อย่างราบรื่น หากต้องการทดสอบลักษณะการทำงานนี้ ให้จำลองการสูญเสียการเชื่อมต่อระยะไกลโดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
- นำข้อมูลการเชื่อมโยงออกจากอุปกรณ์ต่อพ่วงด้วยตนเอง
- เลิกจับคู่อุปกรณ์ด้วยตนเองในการตั้งค่า > อุปกรณ์ที่เชื่อมต่อ