การเปลี่ยนแปลงลักษณะการทํางาน: แอปทั้งหมด

แพลตฟอร์ม 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|all
  • am memory-limiter manual <pid> <limit>|max|none
  • am memory-limiter status
ignore

สั่งให้ตัวจำกัดหน่วยความจำไม่สนใจบางกระบวนการหรือทั้งหมด การส่ง UID (รหัสผู้ใช้ Android) จะสั่งให้ตัวจำกัดหน่วยความจำ ไม่สนใจการบังคับใช้กับกระบวนการทั้งหมดที่เชื่อมโยงกับ UID นั้น คุณยังส่ง all (ไม่สนใจแอปทั้งหมด) หรือ none (ไม่สนใจแอปใดๆ) ได้ด้วย การส่ง none จะลบล้างการเรียก am memory-limiter ignore ก่อนหน้า

หากสั่งให้ตัวจำกัดหน่วยความจำไม่สนใจ UID คุณจะยังคงใช้ ขีดจำกัดหน่วยความจำด้วยตนเองกับกระบวนการภายในแอปได้ โดยเรียกใช้ am memory-limiter manual

manual

สั่งให้ระบบกำหนดข้อจำกัดด้านหน่วยความจำในกระบวนการที่มี 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 引入了自主重新配对功能,这是一项系统级增强功能,旨在自动解决蓝牙配对信息丢失问题。

以前,如果配对信息丢失,用户必须手动前往“设置”取消配对,然后重新配对外围设备。此功能以 Android 16 的安全改进为基础,允许系统在后台重新建立配对信息,而无需用户手动前往“设置”取消配对并重新配对外围设备。

虽然大多数应用不需要更改代码,但开发者应注意蓝牙堆栈中的以下行为变更:

  • 新的配对上下文ACTION_PAIRING_REQUEST 现在包含 EXTRA_PAIRING_CONTEXT extra,允许应用区分 标准配对请求和自主系统发起的重新配对尝试。
  • 有条件的密钥更新:只有在重新配对成功且新连接达到或超过之前配对信息的安全级别时,才会替换现有安全密钥。
  • 修改后的 intent 时间:现在,只有在自主重新配对尝试失败时,才会广播 ACTION_KEY_MISSING intent。如果系统在后台成功恢复配对信息,则可以减少应用中不必要的错误处理。
  • 用户通知:系统通过新的界面通知和对话框管理重新配对。系统会提示用户确认重新配对尝试,以确保用户了解重新连接。

外围设备制造商和配套应用开发者应验证硬件和应用是否能妥善处理配对信息转换。如需测试此行为,请使用以下任一方法模拟远程配对信息丢失:

  • 从外围设备中手动移除配对信息
  • 在“设置”>“已连接的设备”中手动取消配对设备