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

Android 12 มีการเปลี่ยนแปลงลักษณะการทำงานที่อาจส่งผลต่อแอปเช่นเดียวกับรุ่นก่อนหน้า การเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้มีผลเฉพาะกับแอปที่กำหนดเป้าหมายเป็น Android 12 ขึ้นไปเท่านั้น หากแอปกำหนดเป้าหมายเป็น Android 12 คุณควรแก้ไขแอปให้รองรับลักษณะการทำงานเหล่านี้อย่างเหมาะสม (หากมี)

นอกจากนี้ โปรดดูรายการการเปลี่ยนแปลงลักษณะการทำงานที่ส่งผลต่อแอปทั้งหมดที่ทำงานใน Android 12 ด้วย

ประสบการณ์ของผู้ใช้

การแจ้งเตือนที่กำหนดเอง

Android 12 เปลี่ยนรูปลักษณ์และลักษณะการทำงานของการแจ้งเตือนที่กำหนดเองอย่างเต็มรูปแบบ ก่อนหน้านี้ การแจ้งเตือนที่กำหนดเองจะใช้พื้นที่การแจ้งเตือนทั้งหมด รวมถึงระบุเลย์เอาต์และรูปแบบของตัวเองได้ ส่งผลให้เกิดรูปแบบที่ไม่แนะนำซึ่งอาจทำให้ผู้ใช้สับสนหรือทำให้เกิดปัญหาความเข้ากันได้ของเลย์เอาต์ในอุปกรณ์ต่างๆ

สำหรับแอปที่กำหนดเป้าหมายเป็น Android 12 การแจ้งเตือนที่มีมุมมองเนื้อหาที่กำหนดเองจะไม่ใช้พื้นที่การแจ้งเตือนแบบเต็มอีกต่อไป แต่จะใช้เทมเพลตมาตรฐานแทน เทมเพลตนี้จะดูแลให้การแจ้งเตือนที่กำหนดเองมีการตกแต่งเหมือนกับการแจ้งเตือนอื่นๆ ในทุกสถานะ เช่น ไอคอนของการแจ้งเตือนและความสามารถในการขยาย (ในสถานะยุบ) และไอคอนของการแจ้งเตือน ชื่อแอป และการยุบจำนวน (ในสถานะการขยาย) ลักษณะการทํางานนี้เกือบจะเหมือนกับลักษณะการทํางานของ Notification.DecoratedCustomViewStyle

วิธีนี้ทำให้ Android 12 แสดงการแจ้งเตือนทั้งหมดอย่างสอดคล้องกันทางสายตาและง่ายต่อการสแกน พร้อมการขยายการแจ้งเตือนที่ผู้ใช้ค้นพบได้และคุ้นเคย

ภาพประกอบต่อไปนี้แสดงการแจ้งเตือนที่กำหนดเองในเทมเพลตมาตรฐาน

ตัวอย่างต่อไปนี้แสดงวิธีที่การแจ้งเตือนที่กําหนดเองจะแสดงผลในสถานะแบบยุบและแบบขยาย

การเปลี่ยนแปลงใน Android 12 จะส่งผลต่อแอปที่กำหนดคลาสย่อยที่กำหนดเองของ Notification.Style หรือใช้เมธอดของ Notification.Builder ซึ่งได้แก่ setCustomContentView(RemoteViews), setCustomBigContentView(RemoteViews) และ setCustomHeadsUpContentView(RemoteViews)

หากแอปใช้การแจ้งเตือนที่กำหนดเองอย่างเต็มรูปแบบ เราขอแนะนำให้ทดสอบกับเทมเพลตใหม่โดยเร็วที่สุด

  1. เปิดใช้การเปลี่ยนแปลงการแจ้งเตือนที่กำหนดเอง

    1. เปลี่ยน targetSdkVersion ของแอปเป็น S เพื่อเปิดใช้ลักษณะการทำงานใหม่
    2. คอมไพล์อีกครั้ง
    3. ติดตั้งแอปในอุปกรณ์หรือโปรแกรมจำลองที่ใช้ Android 12
  2. ทดสอบการแจ้งเตือนทั้งหมดที่ใช้มุมมองที่กำหนดเอง ตรวจสอบให้แน่ใจว่าการแจ้งเตือนมีลักษณะตามที่คุณคาดหวังในหน้าต่าง ขณะทำการทดสอบ ให้พิจารณาสิ่งต่อไปนี้ และทำการปรับเปลี่ยนที่จำเป็น

    • มีการเปลี่ยนแปลงมิติข้อมูลของมุมมองที่กำหนดเอง โดยทั่วไปแล้ว ความสูงที่กําหนดให้กับการแจ้งเตือนที่กําหนดเองจะน้อยกว่าก่อนหน้านี้ ในสภาวะยุบ ความสูงสูงสุดของเนื้อหาที่กําหนดเองลดลงจาก 106 dp เป็น 48 dp และมีพื้นที่ในแนวนอนน้อยกว่า

    • การแจ้งเตือนทั้งหมดจะขยายได้สำหรับแอปที่กำหนดเป้าหมายเป็น Android 12 โดยทั่วไปแล้ว หมายความว่าหากคุณใช้ setCustomContentView ก็ควรใช้ setBigCustomContentView ด้วยเพื่อให้สถานะแบบยุบและแบบขยายสอดคล้องกัน

    • อย่าลืมเพิ่มความสำคัญของช่องทางการแจ้งเตือนเป็น "สูง" (ปรากฏบนหน้าจอ) เพื่อให้สถานะ "แจ้งเตือน" ปรากฏตามที่คาดไว้

ในแอปที่กำหนดเป้าหมายเป็น Android 12 ขึ้นไป ระบบจะทำการเปลี่ยนแปลงหลายอย่างเกี่ยวกับวิธียืนยัน App Link ของ Android การเปลี่ยนแปลงเหล่านี้จะช่วยเพิ่มความน่าเชื่อถือของประสบการณ์การลิงก์แอปและช่วยให้นักพัฒนาแอปและผู้ใช้ปลายทางควบคุมสิ่งต่างๆ ได้มากขึ้น

หากคุณใช้การยืนยัน App Link ของ Android เพื่อเปิดเว็บลิงก์ในแอป ให้ตรวจสอบว่าคุณใช้รูปแบบที่ถูกต้องเมื่อเพิ่มตัวกรอง Intent สำหรับการยืนยัน App Link ของ Android โดยเฉพาะอย่างยิ่ง ให้ตรวจสอบว่าตัวกรอง Intent เหล่านี้มีหมวดหมู่ BROWSABLE และรองรับรูปแบบ https

นอกจากนี้ คุณยังยืนยันลิงก์ของแอปด้วยตนเองเพื่อทดสอบความน่าเชื่อถือของการประกาศได้ด้วย

การปรับปรุงลักษณะการทำงานของการแสดงภาพซ้อนภาพ

Android 12 ปรับปรุงลักษณะการทำงานสำหรับโหมดการแสดงภาพซ้อนภาพ (PIP) และแนะนำการปรับปรุงรูปลักษณ์สำหรับการเปลี่ยนภาพเคลื่อนไหวทั้งสำหรับการนำทางด้วยท่าทางสัมผัสและการนำทางตามองค์ประกอบ

ดูข้อมูลเพิ่มเติมได้ที่การปรับปรุงการแสดงภาพซ้อนภาพ

การออกแบบใหม่ของข้อความโทสต์

ใน Android 12 มีการออกแบบมุมมองขนมปังใหม่ ตอนนี้ข้อความโทสต์จะมีข้อความได้ไม่เกิน 2 บรรทัด และแสดงไอคอนแอปพลิเคชันถัดจากข้อความ

รูปภาพอุปกรณ์ Android แสดงป๊อปอัปข้อความ "กำลังส่งข้อความ" ข้างไอคอนแอป

ดูรายละเอียดเพิ่มเติมได้ที่ภาพรวมของข้อความโทสต์

ความปลอดภัยและความเป็นส่วนตัว

ตำแหน่งโดยประมาณ

ในอุปกรณ์ที่ใช้ Android 12 ขึ้นไป ผู้ใช้สามารถขอ ความแม่นยําของตําแหน่งโดยประมาณสําหรับแอปของคุณได้

คุกกี้ SameSite ที่ทันสมัยใน WebView

คอมโพเนนต์ WebView ของ Android ใช้ Chromium ซึ่งเป็นโปรเจ็กต์โอเพนซอร์สที่ขับเคลื่อนเบราว์เซอร์ Chrome ของ Google Chromium ได้เปิดตัวการเปลี่ยนแปลงการจัดการคุกกี้ของบุคคลที่สามเพื่อเพิ่มความปลอดภัยและความเป็นส่วนตัว ตลอดจนเพิ่มความโปร่งใสและการควบคุมให้แก่ผู้ใช้ ตั้งแต่ Android 12 เป็นต้นไป การเปลี่ยนแปลงเหล่านี้จะรวมอยู่ใน WebView ด้วยเมื่อแอปกำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป

แอตทริบิวต์ SameSite ของคุกกี้จะควบคุมว่าจะส่งคุกกี้ไปกับคำขอใดก็ได้ หรือจะส่งไปกับคำขอในเว็บไซต์เดียวกันเท่านั้น การเปลี่ยนแปลงต่อไปนี้ซึ่งช่วยปกป้องความเป็นส่วนตัวจะช่วยปรับปรุงการจัดการคุกกี้ของบุคคลที่สามโดยค่าเริ่มต้นและช่วยป้องกันไม่ให้มีการแชร์ข้อมูลข้ามเว็บไซต์โดยไม่ตั้งใจ

  • ระบบจะถือว่าคุกกี้ที่ไม่มีแอตทริบิวต์ SameSite เป็น SameSite=Lax
  • คุกกี้ที่มี SameSite=None จะต้องระบุแอตทริบิวต์ Secure ด้วย ซึ่งหมายความว่าต้องมีบริบทที่ปลอดภัยและควรส่งผ่าน HTTPS
  • ตอนนี้ลิงก์ระหว่างเวอร์ชัน HTTP และ HTTPS ของเว็บไซต์จะถือว่าเป็นคำขอข้ามเว็บไซต์ ดังนั้นจะไม่มีการส่งคุกกี้เว้นแต่จะมีการทำเครื่องหมายเป็น SameSite=None; Secure อย่างเหมาะสม

สําหรับนักพัฒนาซอฟต์แวร์ หลักเกณฑ์ทั่วไปคือให้ระบุความเชื่อมโยงของคุกกี้ข้ามเว็บไซต์ในเส้นทางของผู้ใช้ที่สําคัญ และตรวจสอบว่าได้ตั้งค่าแอตทริบิวต์ SameSite อย่างชัดเจนด้วยค่าที่เหมาะสมตามที่ต้องการ คุณต้องระบุคุกกี้ที่อนุญาตให้ทํางานในเว็บไซต์ต่างๆ หรือในการนําทางในเว็บไซต์เดียวกันซึ่งเปลี่ยนจาก HTTP เป็น HTTPS อย่างชัดเจน

ดูคำแนะนำที่สมบูรณ์สำหรับนักพัฒนาเว็บเกี่ยวกับการเปลี่ยนแปลงเหล่านี้ได้ที่คำอธิบายเกี่ยวกับคุกกี้ SameSite และ Schemeful SameSite

ทดสอบลักษณะการทำงานของ SameSite ในแอปของคุณ

หากแอปของคุณใช้ WebView หรือคุณจัดการเว็บไซต์หรือบริการที่ใช้คุกกี้ เราขอแนะนำให้ทดสอบขั้นตอนใน WebView ของ Android 12 หากพบปัญหา คุณอาจต้องอัปเดตคุกกี้ให้รองรับลักษณะการทํางานของ SameSite แบบใหม่

ตรวจสอบปัญหาในการเข้าสู่ระบบและเนื้อหาที่ฝัง รวมถึงขั้นตอนการลงชื่อเข้าใช้ การซื้อ และขั้นตอนการตรวจสอบสิทธิ์อื่นๆ ที่ผู้ใช้เริ่มต้นในหน้าเว็บที่ไม่ปลอดภัยและเปลี่ยนไปใช้หน้าเว็บที่ปลอดภัย

หากต้องการทดสอบแอปกับ WebView คุณต้องเปิดใช้ลักษณะการทำงาน SameSite แบบใหม่สำหรับแอปที่ต้องการทดสอบ โดยทำตามขั้นตอนใดขั้นตอนหนึ่งต่อไปนี้

โปรดดูข้อมูลเกี่ยวกับการแก้ไขข้อบกพร่องระยะไกลสำหรับ WebView บน Android ที่หัวข้อเริ่มต้นใช้งานการแก้ไขข้อบกพร่องระยะไกลสำหรับอุปกรณ์ Android

ทรัพยากรอื่นๆ

ดูข้อมูลเพิ่มเติมเกี่ยวกับลักษณะการทำงานที่ทันสมัยของ SameSite และการเปิดตัวใน Chrome และ WebView ได้ที่หน้าการอัปเดต Chromium SameSite หากพบข้อบกพร่องใน WebView หรือ Chromium คุณสามารถรายงานได้ในเครื่องมือติดตามปัญหา Chromium สาธารณะ

เซ็นเซอร์ตรวจจับการเคลื่อนไหวมีการจำกัดอัตราคำขอ

หากแอปของคุณกำหนดเป้าหมายเป็น Android 12 ขึ้นไป ระบบจะจำกัดอัตราการรีเฟรชข้อมูลจากเซ็นเซอร์การเคลื่อนไหวและเซ็นเซอร์ตำแหน่งบางประเภทเพื่อปกป้องข้อมูลที่ละเอียดอ่อนที่อาจเกี่ยวกับผู้ใช้

ดูข้อมูลเพิ่มเติมเกี่ยวกับการจำกัดอัตราการส่งข้อมูลเซ็นเซอร์

การพักใช้งานแอป

Android 12 ขยายลักษณะการรีเซ็ตสิทธิ์โดยอัตโนมัติซึ่งเปิดตัวใน Android 11 (API ระดับ 30) หากแอปกำหนดเป้าหมายเป็น Android 12 และผู้ใช้ไม่ได้โต้ตอบกับแอปเป็นเวลา 2-3 เดือน ระบบจะรีเซ็ตสิทธิ์ที่ได้รับอนุญาตและทำให้แอปอยู่ในสถานะไฮเบอร์เนตโดยอัตโนมัติ

ดูข้อมูลเพิ่มเติมในคู่มือเกี่ยวกับโหมดพักของแอป

การประกาศการระบุแหล่งที่มาในการตรวจสอบการเข้าถึงข้อมูล

API การตรวจสอบการเข้าถึงข้อมูลซึ่งเปิดตัวใน Android 11 (API ระดับ 30) ช่วยให้คุณสร้างแท็กการระบุแหล่งที่มาตาม Use Case ของแอปได้ แท็กเหล่านี้ช่วยให้คุณระบุส่วนที่แอปทำการเข้าถึงข้อมูลประเภทหนึ่งๆ ได้ง่ายขึ้น

หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป คุณต้องประกาศแท็กการระบุแหล่งที่มาเหล่านี้ในไฟล์ Manifest ของแอป

ข้อจำกัดการสำรองข้อมูล ADB

Android 12 เปลี่ยนลักษณะการทำงานเริ่มต้นของคำสั่ง adb backup เพื่อช่วยปกป้องข้อมูลส่วนตัวของแอป สำหรับแอปที่กำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป เมื่อผู้ใช้เรียกใช้คำสั่ง adb backup ระบบจะยกเว้นข้อมูลแอปจากข้อมูลระบบอื่นๆ ที่ส่งออกจากอุปกรณ์

หากเวิร์กโฟลว์การทดสอบหรือการพัฒนาของคุณใช้ข้อมูลแอปโดยใช้ adb backup ตอนนี้คุณเลือกใช้การส่งออกข้อมูลของแอปได้โดยการตั้งค่า android:debuggable เป็น true ในไฟล์ Manifest ของแอป

การส่งออกคอมโพเนนต์ที่ปลอดภัยยิ่งขึ้น

หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไปและมี กิจกรรม, บริการ หรือเครื่องรับการออกอากาศที่ใช้ตัวกรอง intent คุณต้องประกาศแอตทริบิวต์ android:exported สำหรับคอมโพเนนต์ของแอปเหล่านี้อย่างชัดเจน

หากคอมโพเนนต์ของแอปมีหมวดหมู่ LAUNCHER ให้ตั้งค่า android:exported เป็น true ในกรณีอื่นๆ ส่วนใหญ่ ให้ตั้งค่า android:exported เป็น false

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างของบริการที่มีตัวกรอง Intent ที่ตั้งค่าแอตทริบิวต์ android:exported เป็น false

<service android:name="com.example.app.backgroundService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.example.app.START_BACKGROUND" />
    </intent-filter>
</service>

ข้อความใน Android Studio

หากแอปมีกิจกรรม บริการ หรือ Broadcast Receiver ที่ใช้ตัวกรอง Intent แต่ไม่ได้ประกาศ android:exported ระบบจะแสดงข้อความเตือนต่อไปนี้ ทั้งนี้ขึ้นอยู่กับเวอร์ชัน Android Studio ที่คุณใช้

Android Studio 2020.3.1 Canary 11 ขึ้นไป

ข้อความต่อไปนี้จะปรากฏขึ้น

  1. คำเตือนของ Lint ต่อไปนี้จะปรากฏในไฟล์ Manifest

    When using intent filters, please specify android:exported as well
    
  2. เมื่อพยายามคอมไพล์แอป ข้อความแสดงข้อผิดพลาดต่อไปนี้จะปรากฏขึ้น

    Manifest merger failed : Apps targeting Android 12 and higher are required \
    to specify an explicit value for android:exported when the corresponding \
    component has an intent filter defined.
    
Android Studio เวอร์ชันเก่า

หากคุณพยายามติดตั้งแอป Logcat จะแสดงข้อความแสดงข้อผิดพลาดต่อไปนี้

Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
[0] '.../build/outputs/apk/debug/app-debug.apk'
Installation failed due to: 'null'

การเปลี่ยนแปลงของ Intent ที่รอดำเนินการ

หากแอปกำหนดเป้าหมายเป็น Android 12 คุณต้องระบุการเปลี่ยนแปลงของออบเจ็กต์ PendingIntent แต่ละรายการที่แอปสร้างขึ้น ข้อกำหนดเพิ่มเติมนี้จะช่วยปรับปรุงความปลอดภัยของแอป

ทดสอบการเปลี่ยนแปลงการเปลี่ยนแปลงของ Intent ที่รอดำเนินการ

หากต้องการทราบว่าแอปไม่มีการประกาศการเปลี่ยนแปลงหรือไม่ ให้มองหาคำเตือนของ Lint ต่อไปนี้ใน Android Studio

Warning: Missing PendingIntent mutability flag [UnspecifiedImmutableFlag]

การเปิดตัว Intent ที่ไม่ปลอดภัย

Android 12 ขึ้นไปมีฟีเจอร์การแก้ไขข้อบกพร่องที่ตรวจหาการเปิด Intent ที่ไม่เป็นอันตราย เพื่อปรับปรุงความปลอดภัยของแพลตฟอร์ม เมื่อระบบตรวจพบการเปิดที่ไม่ปลอดภัยดังกล่าว ระบบจะละเมิด StrictMode เกิดขึ้น

ประสิทธิภาพ

การจำกัดการเปิดบริการที่ทำงานอยู่เบื้องหน้า

แอปที่กำหนดเป้าหมายเป็น Android 12 ขึ้นไปจะเริ่มต้นบริการที่ทำงานอยู่เบื้องหน้าขณะทำงานในเบื้องหลังไม่ได้ ยกเว้นกรณีพิเศษ 2-3 รายการ หากแอปพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้าขณะทำงานอยู่เบื้องหลัง ระบบจะยกเว้น (ยกเว้นบางกรณีที่พิเศษ)

ลองใช้ WorkManager เพื่อตั้งเวลาและเริ่มการทํางานแบบเร่งด่วนขณะที่แอปทํางานอยู่เบื้องหลัง หากต้องการดำเนินการที่ขึ้นอยู่กับเวลาซึ่งผู้ใช้ร้องขอ ให้เริ่มบริการที่ทำงานอยู่เบื้องหน้าภายในการปลุกที่เจาะจง

สิทธิ์การปลุกในเวลาที่แน่นอน

แอปที่กำหนดเป้าหมายเป็น Android 12 ขึ้นไปและมีการปลุกในเวลาที่แน่นอนต้องมีสิทธิ์เข้าถึงความสามารถ "การปลุกและการช่วยเตือน" ที่ปรากฏในหน้าจอสิทธิ์เข้าถึงพิเศษของแอปในการตั้งค่าระบบเพื่อกระตุ้นให้แอปประหยัดทรัพยากรของระบบ

หากต้องการรับสิทธิ์เข้าถึงแอปพิเศษนี้ ให้ขอสิทธิ์ SCHEDULE_EXACT_ALARM ในไฟล์ Manifest

ควรใช้การปลุกในเวลาที่แน่นอนสำหรับฟีเจอร์ที่แสดงต่อผู้ใช้เท่านั้น ดูข้อมูลเพิ่มเติมเกี่ยวกับกรณีการใช้งานที่ยอมรับได้สำหรับการตั้งค่าการปลุกในเวลาที่แน่นอน

ปิดใช้การเปลี่ยนแปลงลักษณะการทำงาน

ขณะเตรียมแอปให้กำหนดเป้าหมายเป็น Android 12 คุณจะปิดใช้การเปลี่ยนแปลงลักษณะการทำงานในเวอร์ชันสร้างที่แก้ไขข้อบกพร่องได้ชั่วคราวเพื่อวัตถุประสงค์ในการทดสอบได้ โดยทำตามขั้นตอนต่อไปนี้

  • ในหน้าจอการตั้งค่าตัวเลือกสำหรับนักพัฒนาแอป ให้เลือกการเปลี่ยนแปลงความเข้ากันได้ของแอป ในหน้าจอที่ปรากฏขึ้น ให้แตะชื่อแอป แล้วปิด REQUIRE_EXACT_ALARM_PERMISSION
  • ในหน้าต่างเทอร์มินัลบนเครื่องพัฒนา ให้เรียกใช้คำสั่งต่อไปนี้

    adb shell am compat disable REQUIRE_EXACT_ALARM_PERMISSION PACKAGE_NAME
    

ข้อจำกัดแทรมโพลีนการแจ้งเตือน

เมื่อผู้ใช้โต้ตอบกับการแจ้งเตือน แอปบางแอปจะตอบสนองต่อการแตะเพื่อแจ้งเตือนด้วยการเปิดตัวองค์ประกอบของแอปที่จะเริ่มกิจกรรมที่ผู้ใช้เห็นและโต้ตอบด้วยในที่สุด คอมโพเนนต์แอปนี้เรียกว่าแทรมโปลีนการแจ้งเตือน

หากต้องการปรับปรุงประสิทธิภาพของแอปและ UX แอปที่กำหนดเป้าหมายเป็น Android 12 ขึ้นไปจะไม่สามารถเริ่มต้นกิจกรรมจากบริการหรือเครื่องรับสัญญาณประกาศที่ใช้เป็นแทรมโพลีนการแจ้งเตือนได้ กล่าวคือ หลังจากผู้ใช้แตะการแจ้งเตือนหรือปุ่มดำเนินการภายในการแจ้งเตือน แอปของคุณจะเรียกstartActivity()ภายในบริการหรือตัวรับการออกอากาศไม่ได้

เมื่อแอปพยายามเริ่มกิจกรรมจากบริการหรือตัวรับการออกอากาศที่ทำหน้าที่เป็นแทรมโพลีนการแจ้งเตือน ระบบจะป้องกันไม่ให้กิจกรรมเริ่มต้น และข้อความต่อไปนี้จะปรากฏใน Logcat

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

ระบุคอมโพเนนต์ของแอปที่ทำหน้าที่เป็นแทรมโปลีนการแจ้งเตือน

เมื่อทดสอบแอป หลังจากแตะการแจ้งเตือนแล้ว คุณจะระบุได้ว่าบริการหรือเครื่องรับสัญญาณออกอากาศใดที่ทำหน้าที่เป็นแทรมโพลีนการแจ้งเตือนในแอป โดยให้ดูเอาต์พุตของคำสั่งเทอร์มินัลต่อไปนี้

adb shell dumpsys activity service \
  com.android.systemui/.dump.SystemUIAuxiliaryDumpService

ส่วนของเอาต์พุตมีข้อความ "NotifInteractionLog" ส่วนนี้มีข้อมูลที่จำเป็นต่อการระบุคอมโพเนนต์ที่เริ่มต้นหลังจากที่แตะการแจ้งเตือน

อัปเดตแอป

หากแอปเริ่มกิจกรรมจากบริการหรือตัวรับการออกอากาศที่ทำหน้าที่เป็นแทรมโพลีนการแจ้งเตือน ให้ทำตามขั้นตอนการย้ายข้อมูลต่อไปนี้

  1. สร้างออบเจ็กต์ PendingIntent ที่เชื่อมโยงกับกิจกรรมที่ผู้ใช้เห็นหลังจากแตะการแจ้งเตือน
  2. ใช้ออบเจ็กต์ PendingIntent ที่สร้างไว้ในขั้นตอนก่อนหน้าเป็นส่วนหนึ่งของการสร้างการแจ้งเตือน

ในการระบุที่มาของกิจกรรม เพื่อดำเนินการบันทึก เช่น ใช้ข้อมูลเพิ่มเติมเมื่อโพสต์การแจ้งเตือน สำหรับการบันทึกแบบรวมศูนย์ ให้ใช้ ActivityLifecycleCallbacks หรือผู้สังเกตการณ์อายุการใช้งานของ Jetpack

สลับลักษณะการทำงาน

เมื่อทดสอบแอปเวอร์ชันที่แก้ไขข้อบกพร่องได้ คุณจะเปิดและปิดใช้ข้อจำกัดนี้ได้โดยใช้แฟล็กความเข้ากันได้ของแอป NOTIFICATION_TRAMPOLINE_BLOCK

การสำรองและคืนค่า

วิธีการทํางานของการสํารองและกู้คืนข้อมูลในแอปที่ทํางานบนและกำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) มีการเปลี่ยนแปลง การสำรองและกู้คืนข้อมูล Android มี 2 รูปแบบดังนี้

  • การสำรองข้อมูลในระบบคลาวด์: ระบบจะจัดเก็บข้อมูลผู้ใช้ไว้ใน Google ไดรฟ์ของผู้ใช้ เพื่อให้สามารถกู้คืนข้อมูลดังกล่าวในอุปกรณ์หรืออุปกรณ์เครื่องใหม่ได้ในภายหลัง
  • การโอนระหว่างอุปกรณ์ (D2D): ระบบจะส่งข้อมูลผู้ใช้จากอุปกรณ์เครื่องเก่าไปยังอุปกรณ์โดยตรง เช่น โดยใช้สาย

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสำรองและกู้คืนข้อมูล โปรดดูที่สำรองข้อมูลผู้ใช้ด้วยการสำรองข้อมูลอัตโนมัติและสำรองคู่คีย์-ค่าด้วย Android Backup Service

การเปลี่ยนแปลงฟังก์ชันการโอน D2D

สำหรับแอปที่ทำงานและกำหนดเป้าหมายเป็น Android 12 ขึ้นไป ให้ทำดังนี้

  • การระบุกฎรวมและยกเว้นด้วยกลไกการกําหนดค่า XML จะไม่ส่งผลต่อการโอน D2D แต่ยังคงส่งผลต่อการสํารองและคืนค่าในระบบคลาวด์ (เช่น การสำรองข้อมูล Google ไดรฟ์) หากต้องการระบุกฎสำหรับการโอน D2D คุณต้องใช้การกำหนดค่าใหม่ในส่วนถัดไป

  • ในอุปกรณ์จากผู้ผลิตอุปกรณ์บางราย การระบุ android:allowBackup="false" จะปิดการสำรองข้อมูลไปยัง Google ไดรฟ์ แต่จะไม่ปิดใช้การโอน D2D สำหรับแอป

รูปแบบ "รวม" และ "ยกเว้น" ใหม่

แอปที่ทำงานบนและกำหนดเป้าหมายเป็น Android 12 ขึ้นไปจะใช้รูปแบบอื่นในการกำหนดค่า XML รูปแบบนี้ทำให้ความแตกต่างระหว่างการสำรองข้อมูล Google ไดรฟ์กับการโอน D2D ชัดเจนโดยกำหนดให้คุณระบุกฎรวมและยกเว้นแยกกันสำหรับการสำรองข้อมูลระบบคลาวด์และการโอน D2D

นอกจากนี้ คุณยังใช้เพื่อระบุกฎสำหรับการสำรองข้อมูลได้ด้วย (ไม่บังคับ) ในกรณีนี้ ระบบจะไม่สนใจการกำหนดค่าที่ใช้ก่อนหน้านี้ในอุปกรณ์ที่ใช้ Android 12 ขึ้นไป อุปกรณ์ที่ใช้ Android 11 หรือต่ำกว่ายังคงต้องใช้การกำหนดค่าแบบเก่า

การเปลี่ยนแปลงรูปแบบ XML

ต่อไปนี้เป็นรูปแบบที่ใช้สำหรับการกำหนดค่าการสำรองและกู้คืนข้อมูลใน Android 11 และต่ำกว่า

<full-backup-content>
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root"] path="string"
    requireFlags=["clientSideEncryption" | "deviceToDeviceTransfer"] />
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root"] path="string" />
</full-backup-content>

ต่อไปนี้แสดงการเปลี่ยนแปลงในรูปแบบตัวหนา

<data-extraction-rules>
  <cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                        "root"] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                        "root"] path="string"/>
    ...
  </cloud-backup>
  <device-transfer>
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                        "root"] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                        "root"] path="string"/>
    ...
  </device-transfer>
</data-extraction-rules>

สำหรับข้อมูลเพิ่มเติม โปรดดูที่ส่วนที่เกี่ยวข้องในคำแนะนำในการสำรองข้อมูลผู้ใช้ด้วยการสำรองข้อมูลอัตโนมัติ

Flag ไฟล์ Manifest สำหรับแอป

ชี้แอปไปยังการกำหนดค่า XML ใหม่โดยใช้แอตทริบิวต์ android:dataExtractionRules ในไฟล์ Manifest เมื่อชี้ไปที่การกำหนดค่า XML ใหม่ ระบบจะละเว้นแอตทริบิวต์ android:fullBackupContent ที่ชี้ไปยังการกำหนดค่าเก่าในอุปกรณ์ที่ใช้ Android 12 ขึ้นไป ตัวอย่างโค้ดต่อไปนี้จะแสดงรายการไฟล์ Manifest ใหม่

<application
    ...
    <!-- The below attribute is ignored. -->
    android:fullBackupContent="old_config.xml"
    <!-- You can point to your new configuration using the new
         dataExtractionRules attribute . -->
    android:dataExtractionRules="new_config.xml"
    ...>
</application>

การเชื่อมต่อ

สิทธิ์เข้าถึงบลูทูธ

Android 12 เปิดตัวสิทธิ์ BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE และ BLUETOOTH_CONNECT สิทธิ์เหล่านี้ช่วยให้แอปที่กำหนดเป้าหมายเป็น Android 12 โต้ตอบกับอุปกรณ์บลูทูธได้ง่ายขึ้น โดยเฉพาะอย่างยิ่งสำหรับแอปที่ไม่จำเป็นต้องเข้าถึงตำแหน่งของอุปกรณ์

อัปเดตตรรกะของแอปเพื่อเตรียมอุปกรณ์สำหรับการกำหนดเป้าหมายเป็น Android 12 ขึ้นไป แทนที่จะประกาศชุดสิทธิ์บลูทูธเดิม ให้ประกาศชุดสิทธิ์การใช้บลูทูธที่ทันสมัยกว่า

การเชื่อมต่อแบบเพียร์ทูเพียร์ + อินเทอร์เน็ตพร้อมกัน

สำหรับแอปที่กำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป อุปกรณ์ที่รองรับการเชื่อมต่อแบบ peer-to-peer และอินเทอร์เน็ตพร้อมกันจะรักษาการเชื่อมต่อ Wi-Fi กับอุปกรณ์เพียร์และเครือข่ายหลักที่ให้บริการอินเทอร์เน็ตพร้อมกันได้ ทำให้ประสบการณ์ของผู้ใช้ราบรื่นยิ่งขึ้น แอปที่กำหนดเป้าหมายเป็น Android 11 (API ระดับ 30) หรือต่ำกว่าจะยังคงพบการทำงานแบบเดิม ซึ่งก็คือการยกเลิกการเชื่อมต่อเครือข่าย Wi-Fi หลักก่อนที่จะเชื่อมต่อกับอุปกรณ์เพียร์

ความเข้ากันได้

WifiManager.getConnectionInfo() แสดงผล WifiInfo ได้สำหรับเครือข่ายเดียวเท่านั้น ด้วยเหตุนี้ ลักษณะการทํางานของ API จึงมีการเปลี่ยนแปลงในลักษณะต่อไปนี้ใน Android 12 ขึ้นไป

  • หากมีเครือข่าย Wi-Fi เพียงเครือข่ายเดียว ระบบจะแสดงผล WifiInfo ของเครือข่ายนั้น
  • หากมีเครือข่าย Wi-Fi มากกว่า 1 เครือข่ายและแอปการโทรเรียกใช้การเชื่อมต่อแบบเพียร์ทูเพียร์ ระบบจะส่งคืน WifiInfo ที่เกี่ยวข้องกับอุปกรณ์เพียร์
  • หากมีเครือข่าย Wi-Fi มากกว่า 1 เครือข่ายและแอปการโทรไม่เรียกใช้การเชื่อมต่อแบบเพียร์ทูเพียร์ ระบบจะแสดงผล WifiInfo ของการเชื่อมต่อที่ให้บริการอินเทอร์เน็ตหลัก

เราขอแนะนำให้แอปทั้งหมด (โดยเฉพาะแอปที่ทริกเกอร์การเชื่อมต่อแบบ peer-to-peer) เปลี่ยนไปใช้ NetworkCallback.onCapabilitiesChanged() แทนการเรียกใช้ WifiManager.getConnectionInfo() เพื่อรับออบเจ็กต์ WifiInfo ทั้งหมดที่ตรงกับ NetworkRequest ที่ใช้ลงทะเบียน NetworkCallback เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีขึ้นบนอุปกรณ์ที่รองรับเครือข่าย Wi-Fi 2 เครือข่ายพร้อมกัน getConnectionInfo() เลิกใช้งานแล้วตั้งแต่ Android 12

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีรับ WifiInfo ใน NetworkCallback

Kotlin

val networkCallback = object : ConnectivityManager.NetworkCallback() {
  ...
  override fun onCapabilitiesChanged(
           network : Network,
           networkCapabilities : NetworkCapabilities) {
    val transportInfo = networkCapabilities.getTransportInfo()
    if (transportInfo !is WifiInfo) return
    val wifiInfo : WifiInfo = transportInfo
    ...
  }
}

Java

final NetworkCallback networkCallback = new NetworkCallback() {
  ...
  @Override
  public void onCapabilitiesChanged(
         Network network,
         NetworkCapabilities networkCapabilities) {
    final TransportInfo transportInfo = networkCapabilities.getTransportInfo();
    if (!(transportInfo instanceof WifiInfo)) return;
    final WifiInfo wifiInfo = (WifiInfo) transportInfo;
    ...
  }
  ...
};

mDNSResponder Native API

Android 12 มีการเปลี่ยนแปลงเมื่อแอปโต้ตอบกับเดรัม mDNSResponder ได้โดยใช้ mDNSResponder Native API ก่อนหน้านี้ เมื่อแอปลงทะเบียนบริการในเครือข่ายและเรียกใช้เมธอด getSystemService() บริการ NSD ของระบบจะเริ่มทำงานของเดรัม mDNSResponder แม้ว่าแอปจะยังไม่ได้เรียกใช้เมธอด NsdManager ก็ตาม จากนั้นเดมอนจะสมัครใช้บริการอุปกรณ์ในกลุ่มมัลติแคสต์ของโหนดทั้งหมด ซึ่งทำให้ระบบตื่นขึ้นบ่อยขึ้นและใช้พลังงานมากขึ้น ใน Android 12 ขึ้นไป ระบบจะเริ่มการทำงานของเดรัม mDNSResponder เฉพาะเมื่อจำเป็นสำหรับเหตุการณ์ NSD และหยุดการทำงานหลังจากนั้น เพื่อลดการใช้แบตเตอรี่

เนื่องจากการเปลี่ยนแปลงนี้จะส่งผลต่อเวลาที่ Daemon ของ mDNSResponder พร้อมใช้งาน แอปที่คาดว่าดีมอน mDNSResponder จะเริ่มทำงานหลังจากเรียกใช้เมธอด getSystemService() อาจได้รับข้อความจากระบบที่ระบุว่าดีมอน mDNSResponder ไม่พร้อมใช้งาน แอปที่ใช้ NsdManager และไม่ได้ใช้ API แบบเนทีฟของ mDNSResponder จะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงนี้

คลังผู้ให้บริการ

ไลบรารีที่ใช้ร่วมกันแบบเนทีฟที่ผู้ให้บริการเป็นผู้จัดหา

ไลบรารีที่ใช้ร่วมกันแบบเนทีฟที่ไม่ใช่ NDK ที่ให้บริการโดยผู้ให้บริการซิลิคอนหรือผู้ผลิตอุปกรณ์จะเข้าถึงไม่ได้โดยค่าเริ่มต้นหากแอปกำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป คุณจะเข้าถึงไลบรารีได้ก็ต่อเมื่อมีคำขออย่างชัดแจ้งโดยใช้แท็ก <uses-native-library>

หากแอปกำหนดเป้าหมายเป็น Android 11 (API ระดับ 30) หรือต่ำกว่า ก็ไม่จำเป็นต้องใช้แท็ก <uses-native-library> ในกรณีนี้ คุณจะเข้าถึงไลบรารีที่ใช้ร่วมกันแบบเนทีฟได้ ไม่ว่าจะเป็นไลบรารี NDK หรือไม่ก็ตาม

ข้อจำกัดที่ไม่ใช่ SDK ที่อัปเดตแล้ว

Android 12 มีรายการอินเทอร์เฟซที่ไม่ใช่ SDK ซึ่งถูกจำกัดซึ่งอัปเดตแล้วโดยอิงตามการทำงานร่วมกันกับนักพัฒนาแอป Android และการทดสอบภายในครั้งล่าสุด ทุกครั้งที่เป็นไปได้ เราตรวจสอบว่ามีทางเลือกสาธารณะพร้อมใช้งานก่อนที่เราจะจำกัดอินเทอร์เฟซที่ไม่ใช่ SDK

หากแอปไม่ได้กำหนดเป้าหมายเป็น Android 12 การเปลี่ยนแปลงเหล่านี้บางส่วนอาจไม่ส่งผลกระทบต่อคุณในทันที อย่างไรก็ตาม แม้ว่าปัจจุบันคุณจะใช้อินเทอร์เฟซที่ไม่ใช่ SDK บางรายการได้ (ขึ้นอยู่กับระดับ API เป้าหมายของแอป) แต่การใช้เมธอดหรือฟิลด์ที่ไม่ใช่ SDK นั้นมักมีความเสี่ยงสูงที่จะทำให้แอปขัดข้อง

หากไม่แน่ใจว่าแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK หรือไม่ คุณสามารถทดสอบแอปเพื่อดูข้อมูลดังกล่าว หากแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK คุณควรเริ่มวางแผนการย้ายข้อมูลไปยังทางเลือก SDK อย่างไรก็ตาม เราเข้าใจว่าแอปบางแอปมี Use Case ที่ถูกต้องในการใช้อินเทอร์เฟซที่ไม่ใช่ SDK หากไม่พบทางเลือกอื่นในการใช้อินเทอร์เฟซที่ไม่ใช่ SDK สำหรับฟีเจอร์ในแอป คุณควรขอ API สาธารณะใหม่

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงใน Android รุ่นนี้ได้ที่การอัปเดตข้อจำกัดของอินเทอร์เฟซที่ไม่ใช่ SDK ใน Android 12 ดูข้อมูลเพิ่มเติมเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK โดยทั่วไปได้ที่ข้อจำกัดเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK