แพลตฟอร์ม Android 17 มีการเปลี่ยนแปลงลักษณะการทำงานที่อาจส่งผลต่อแอปของคุณ
การเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้จะมีผลกับแอปทั้งหมดเมื่อทำงานบน Android 17
โดยไม่คำนึงถึง targetSdkVersion คุณควรทดสอบแอป แล้วแก้ไข
ตามที่จำเป็นเพื่อรองรับการเปลี่ยนแปลงเหล่านี้ หากเกี่ยวข้อง
อย่าลืมตรวจสอบรายการการเปลี่ยนแปลงลักษณะการทำงานที่มีผลกับแอปที่กำหนดเป้าหมายเป็น Android 17 เท่านั้นด้วย
ฟังก์ชันหลัก
Android 17 (API ระดับ 37) มีการเปลี่ยนแปลงต่อไปนี้ซึ่งแก้ไขหรือขยายความสามารถหลักต่างๆ ของระบบ Android
ขีดจำกัดหน่วยความจำของแอป
Android 17 มีการจำกัดหน่วยความจำของแอปตาม RAM ทั้งหมดของอุปกรณ์ เพื่อสร้างสภาพแวดล้อมที่เสถียรและกำหนดได้มากขึ้นสำหรับแอปและ ผู้ใช้ Android ใน Android 17 มีการกำหนดขีดจำกัดอย่างรอบคอบเพื่อสร้างพื้นฐานของระบบ โดยมุ่งเป้าไปที่ปัญหาหน่วยความจำรั่วไหลที่รุนแรงและค่าผิดปกติอื่นๆ ก่อนที่จะทำให้ระบบไม่เสถียรในวงกว้าง ส่งผลให้ 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 (Process ID) ที่ระบุ ข้อจำกัดด้านหน่วยความจำจะระบุเป็นจำนวนเต็ม หน่วยเป็น MB เช่น การส่ง
30จะระบุว่ากระบวนการนี้จำกัด หน่วยความจำไว้ที่ 30 MB การส่งmaxจะนำข้อจำกัดด้านหน่วยความจำทั้งหมดในกระบวนการนั้นออก การส่งnoneจะนำข้อจำกัดที่ตั้งค่าด้วยตนเองในกระบวนการออก และคืนค่า ขีดจำกัดเริ่มต้นของระบบ (หากมี)statusรายงานสถานะปัจจุบันของตัวจำกัดหน่วยความจำ สถานะประกอบด้วย ขีดจำกัดหน่วยความจำที่กำหนดไว้สำหรับกระบวนการที่มองเห็นได้และมองไม่เห็น
ความเป็นส่วนตัว
Android 17 มีการเปลี่ยนแปลงต่อไปนี้เพื่อปรับปรุงความเป็นส่วนตัวของผู้ใช้
การป้องกัน OTP ทาง SMS
ตั้งแต่ Android 17 เป็นต้นไป Android จะขยายการปกป้อง ข้อความ SMS ที่มีรหัสผ่านที่สามารถใช้งานได้เพียงครั้งเดียว (OTP)
ใน Android เวอร์ชันก่อนหน้า การป้องกันนี้มุ่งเน้นไปที่รูปแบบ ตัวดึงข้อมูล SMS เป็นหลัก การนำส่งข้อความที่มีแฮชตัวดึงข้อมูล SMS จะ ล่าช้าสำหรับแอปส่วนใหญ่เป็นเวลา 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 สำหรับ
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);
ขีดจำกัดของที่เก็บคีย์ต่อแอป
แอปควรหลีกเลี่ยงการสร้างคีย์จำนวนมากเกินไปใน 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
บล็อกการรับส่งข้อมูลแบบวนรอบข้ามโปรไฟล์
ตั้งแต่ 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 ขอแนะนำการจับคู่ใหม่ด้วยตัวเอง ซึ่งเป็นการปรับปรุงระดับระบบที่ออกแบบมาเพื่อแก้ไขการสูญเสียการเชื่อมต่อ Bluetooth โดยอัตโนมัติ
ก่อนหน้านี้ หากการเชื่อมต่อขาดหายไป ผู้ใช้ต้องไปที่การตั้งค่าเพื่อยกเลิกการจับคู่และจับคู่กับอุปกรณ์ต่อพ่วงอีกครั้งด้วยตนเอง ฟีเจอร์นี้สร้างขึ้นจากการปรับปรุงความปลอดภัยของ Android 16 โดยอนุญาตให้ระบบสร้างการเชื่อมต่อใหม่ในเบื้องหลังโดยไม่กำหนดให้ผู้ใช้ไปที่การตั้งค่าเพื่อยกเลิกการจับคู่และจับคู่กับอุปกรณ์ต่อพ่วงอีกครั้งด้วยตนเอง
แม้ว่าแอปส่วนใหญ่จะไม่ต้องมีการเปลี่ยนแปลงโค้ด แต่นักพัฒนาแอปควรทราบถึงการเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้ในสแต็ก Bluetooth
- บริบทการจับคู่ใหม่: ตอนนี้
ACTION_PAIRING_REQUESTมีส่วนเพิ่มเติมEXTRA_PAIRING_CONTEXTซึ่งช่วยให้แอปแยกแยะระหว่างคำขอการจับคู่มาตรฐานกับความพยายามในการจับคู่ใหม่ที่ระบบเริ่มต้นเองได้ - การอัปเดตคีย์แบบมีเงื่อนไข: ระบบจะแทนที่คีย์ความปลอดภัยที่มีอยู่ก็ต่อเมื่อการจับคู่ใหม่สำเร็จและการเชื่อมต่อใหม่มีระดับความปลอดภัยเท่ากับหรือสูงกว่าการเชื่อมต่อก่อนหน้า
- การกำหนดเวลา Intent ที่แก้ไข: ตอนนี้ระบบจะออกอากาศ Intent
ACTION_KEY_MISSINGก็ต่อเมื่อความพยายามในการจับคู่ใหม่ด้วยตัวเองล้มเหลว ซึ่งจะช่วยลดการจัดการข้อผิดพลาดที่ไม่จำเป็นในแอปหากระบบกู้คืนการเชื่อมต่อในเบื้องหลังได้สำเร็จ - การแจ้งเตือนผู้ใช้: ระบบจะจัดการการจับคู่ใหม่ผ่านการแจ้งเตือนและกล่องโต้ตอบ UI ใหม่ ระบบจะแจ้งให้ผู้ใช้ยืนยันความพยายามในการจับคู่ใหม่เพื่อให้ผู้ใช้ทราบถึงการเชื่อมต่อใหม่
ผู้ผลิตอุปกรณ์ต่อพ่วงและนักพัฒนาแอปที่ใช้ร่วมกันควรตรวจสอบว่าฮาร์ดแวร์และแอปจัดการการเปลี่ยนการเชื่อมต่อได้อย่างราบรื่น หากต้องการทดสอบลักษณะการทำงานนี้ ให้จำลองการสูญเสียการเชื่อมต่อระยะไกลโดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
- นำข้อมูลการเชื่อมต่อออกจากอุปกรณ์ต่อพ่วงด้วยตนเอง
- ยกเลิกการจับคู่อุปกรณ์ด้วยตนเองในส่วนการตั้งค่า > อุปกรณ์ที่เชื่อมต่อ