การเปลี่ยนแปลงลักษณะการทำงาน: แอปที่กำหนดเป้าหมายเป็น 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) และแนะนําการปรับปรุงภาพเคลื่อนไหวการเปลี่ยนผ่านทั้งสำหรับการไปยังส่วนต่างๆ ด้วยท่าทางสัมผัสและไปยังส่วนต่างๆ ตามองค์ประกอบ

ดูข้อมูลเพิ่มเติมเกี่ยวกับการปรับปรุงฟีเจอร์ภาพในภาพ

การออกแบบใหม่ของข้อความ Toast

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

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

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

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

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

ในอุปกรณ์ที่ใช้ 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 และ SameSite แบบมีรูปแบบ

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

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

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

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

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

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับลักษณะการทำงานสมัยใหม่ของ SameSite และการเปิดตัวใน Chrome และ WebView ได้ที่หน้าอัปเดต SameSite ของ Chromium หากพบข้อบกพร่องใน 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 ขึ้นไป และมี activity, service หรือ broadcast receiver ที่ใช้ Intent Filter คุณต้องประกาศแอตทริบิวต์ 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>

Messages ใน 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 แต่ละรายการที่แอปสร้างขึ้น ข้อกำหนดเพิ่มเติมนี้จะช่วยปรับปรุงความปลอดภัยของแอป

ทดสอบการเปลี่ยนแปลงความสามารถในการเปลี่ยนแปลงของ PendingIntent

หากต้องการตรวจสอบว่าแอปของคุณขาดการประกาศความสามารถในการเปลี่ยนแปลงหรือไม่ ให้มองหาคำเตือนเกี่ยวกับ Lint ต่อไปนี้ใน Android Studio

Warning: Missing PendingIntent mutability flag [UnspecifiedImmutableFlag]

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

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

ประสิทธิภาพ

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

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

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

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

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

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

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

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

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

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

    adb shell am compat disable REQUIRE_EXACT_ALARM_PERMISSION PACKAGE_NAME
    

ข้อจํากัดของ Trampoline การแจ้งเตือน

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

แอปที่กําหนดเป้าหมายเป็น Android 12 ขึ้นไปจะไม่สามารถเริ่มกิจกรรมจากบริการหรือ Broadcast Receiver ที่ใช้เป็นตัวกระตุ้นการแจ้งเตือน เพื่อปรับปรุงประสิทธิภาพของแอปและ UX กล่าวคือ หลังจากผู้ใช้แตะการแจ้งเตือนหรือปุ่มดำเนินการภายในการแจ้งเตือน แอปของคุณจะเรียก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

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

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

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

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

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

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

การเปลี่ยนแปลงฟังก์ชันการโอน 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 เครือข่ายและแอปการโทรเรียกให้เชื่อมต่อแบบ peer-to-peer ระบบจะแสดง WifiInfo ที่สอดคล้องกับอุปกรณ์ของคู่สนทนา
  • หากมีเครือข่าย Wi-Fi มากกว่า 1 เครือข่ายและแอปการโทรไม่ได้ทริกเกอร์การเชื่อมต่อแบบ peer-to-peer ระบบจะแสดง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 และหยุดการทำงานหลังจากนั้น เพื่อลดการใช้แบตเตอรี่

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

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

ไลบรารีที่ใช้ร่วมกันแบบเนทีฟที่ผู้ให้บริการระบุ

ไลบรารีที่แชร์แบบเนทีฟที่ไม่ใช่ 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