Android 9 (API ระดับ 28) มีการเปลี่ยนแปลงหลายอย่างในระบบ Android การเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้มีผลกับแอปทั้งหมดเมื่อทำงานบนแพลตฟอร์ม Android 9 โดยไม่คำนึงถึงระดับ API ที่กําหนดเป้าหมาย นักพัฒนาแอปทุกรายควรตรวจสอบการเปลี่ยนแปลงเหล่านี้และแก้ไขแอปให้รองรับการเปลี่ยนแปลงดังกล่าวอย่างเหมาะสม หากแอปมีการเปลี่ยนแปลงเหล่านี้
สำหรับการเปลี่ยนแปลงที่ส่งผลต่อแอปที่กำหนดเป้าหมายเป็น API ระดับ 28 ขึ้นไปเท่านั้น โปรดดูหัวข้อการเปลี่ยนแปลงลักษณะการทํางาน: แอปที่กําหนดเป้าหมายเป็น API ระดับ 28 ขึ้นไป
การจัดการพลังงาน
Android 9 เปิดตัวฟีเจอร์ใหม่ๆ เพื่อปรับปรุงการจัดการพลังงานของอุปกรณ์ การเปลี่ยนแปลงเหล่านี้พร้อมกับฟีเจอร์ที่มีอยู่แล้วก่อน Android 9 จะช่วยให้แอปที่ต้องใช้ทรัพยากรมากที่สุดได้รับทรัพยากรดังกล่าว
โปรดดูรายละเอียดที่หัวข้อการจัดการพลังงาน
การเปลี่ยนแปลงด้านความเป็นส่วนตัว
Android 9 เปิดตัวการเปลี่ยนแปลงลักษณะการทำงานหลายอย่างเพื่อเพิ่มความเป็นส่วนตัวของผู้ใช้ เช่น การจำกัดการเข้าถึงเซ็นเซอร์ของอุปกรณ์โดยแอปที่ทำงานอยู่เบื้องหลัง การจำกัดข้อมูลที่ดึงมาจากการสแกน Wi-Fi รวมถึงกฎและกลุ่มสิทธิ์ใหม่ที่เกี่ยวข้องกับการโทร สถานะโทรศัพท์ และการสแกน Wi-Fi
การเปลี่ยนแปลงเหล่านี้จะมีผลกับแอปทั้งหมดที่ทำงานบน Android 9 โดยไม่คำนึงถึงเวอร์ชัน SDK เป้าหมาย
การเข้าถึงเซ็นเซอร์ในเบื้องหลังแบบจำกัด
Android 9 จำกัดความสามารถของแอปที่ทำงานอยู่เบื้องหลังในการเข้าถึงข้อมูลป้อนเข้าของผู้ใช้และข้อมูลเซ็นเซอร์ หากแอปทำงานอยู่เบื้องหลังในอุปกรณ์ที่ใช้ Android 9 ระบบจะใช้ข้อจำกัดต่อไปนี้กับแอป
- แอปของคุณเข้าถึงไมโครโฟนหรือกล้องไม่ได้
- เซ็นเซอร์ที่ใช้โหมดการรายงานแบบต่อเนื่อง เช่น ตัวตรวจวัดความเร่งและเครื่องวัดการหมุน จะไม่รับเหตุการณ์
- เซ็นเซอร์ที่ใช้โหมดการรายงานเมื่อมีการเปลี่ยนแปลงหรือแบบครั้งเดียวจะไม่รับเหตุการณ์
หากแอปต้องตรวจหาเหตุการณ์ของเซ็นเซอร์ในอุปกรณ์ที่ใช้ Android 9 ให้ใช้บริการที่ทำงานอยู่เบื้องหน้า
จำกัดสิทธิ์เข้าถึงบันทึกการโทร
Android 9 เปิดตัวกลุ่มCALL_LOG
สิทธิ์ และย้ายสิทธิ์ READ_CALL_LOG
, WRITE_CALL_LOG
และ PROCESS_OUTGOING_CALLS
ไปไว้ในกลุ่มนี้ ใน Android เวอร์ชันก่อนหน้า สิทธิ์เหล่านี้จะอยู่ในกลุ่มสิทธิ์ PHONE
กลุ่มสิทธิ์ CALL_LOG
นี้ช่วยให้ผู้ใช้ควบคุมและมองเห็นแอปที่ต้องการเข้าถึงข้อมูลที่ละเอียดอ่อนเกี่ยวกับการโทรได้ดีขึ้น เช่น การอ่านบันทึกการโทรและระบุหมายเลขโทรศัพท์
หากแอปของคุณจำเป็นต้องเข้าถึงบันทึกการโทรหรือต้องประมวลผลการโทรออก คุณต้องขอสิทธิ์เหล่านี้จากกลุ่มสิทธิ์ CALL_LOG
อย่างชัดแจ้ง มิเช่นนั้น ระบบจะแสดง
SecurityException
หมายเหตุ: เนื่องจากสิทธิ์เหล่านี้มีการเปลี่ยนแปลงกลุ่มและได้รับสิทธิ์เมื่อรันไทม์ ผู้ใช้จึงอาจปฏิเสธไม่ให้แอปเข้าถึงข้อมูลบันทึกการโทรได้ ในกรณีนี้ แอปของคุณควรจัดการกับการไม่มีสิทธิ์เข้าถึงข้อมูลได้อย่างราบรื่น
หากแอปของคุณเป็นไปตามแนวทางปฏิบัติแนะนำเกี่ยวกับสิทธิ์รันไทม์อยู่แล้ว ก็จะจัดการกับการเปลี่ยนแปลงของกลุ่มสิทธิ์ได้
จำกัดสิทธิ์เข้าถึงหมายเลขโทรศัพท์
แอปที่ทำงานบน Android 9 จะอ่านหมายเลขโทรศัพท์หรือสถานะโทรศัพท์ไม่ได้หากไม่ได้รับสิทธิ์ READ_CALL_LOG
เพิ่มเติมจากสิทธิ์อื่นๆ ที่ Use Case ของแอปกำหนด
หมายเลขโทรศัพท์ที่เชื่อมโยงกับสายเรียกเข้าและโทรออกจะแสดงในการออกอากาศสถานะโทรศัพท์ เช่น สําหรับสายเรียกเข้าและโทรออก และเข้าถึงได้จากคลาส PhoneStateListener
อย่างไรก็ตาม หากไม่มีสิทธิ์ READ_CALL_LOG
ช่องหมายเลขโทรศัพท์ที่ระบุในการออกอากาศ PHONE_STATE_CHANGED
และผ่าน PhoneStateListener
จะว่างเปล่า
หากต้องการอ่านหมายเลขโทรศัพท์จากสถานะโทรศัพท์ ให้อัปเดตแอปเพื่อขอสิทธิ์ที่จําเป็นตาม Use Case ของคุณ
- หากต้องการอ่านตัวเลขจาก
PHONE_STATE
intent action คุณต้องมีทั้งสิทธิ์READ_CALL_LOG
และสิทธิ์READ_PHONE_STATE
- หากต้องการอ่านตัวเลขจาก
onCallStateChanged()
คุณต้องมีสิทธิ์READ_CALL_LOG
เท่านั้น คุณไม่จำเป็นต้องมีสิทธิ์READ_PHONE_STATE
จำกัดการเข้าถึงข้อมูลตำแหน่งและการเชื่อมต่อ Wi-Fi
ใน Android 9 ข้อกำหนดด้านสิทธิ์สำหรับแอปในการสแกน Wi-Fi จะเข้มงวดกว่าในเวอร์ชันก่อนหน้า โปรดดูรายละเอียดที่หัวข้อข้อจำกัดในการสแกน Wi-Fi
ข้อจํากัดที่คล้ายกันนี้ยังมีผลกับเมธอด getConnectionInfo()
ด้วย ซึ่งจะแสดงผลออบเจ็กต์ WifiInfo
ที่อธิบายการเชื่อมต่อ Wi-Fi ปัจจุบัน คุณจะใช้เมธอดของออบเจ็กต์นี้เพื่อดึงค่า SSID และ BSSID ได้ก็ต่อเมื่อแอปที่เรียกใช้มีสิทธิ์ต่อไปนี้
- ACCESS_FINE_LOCATION หรือ ACCESS_COARSE_LOCATION
- ACCESS_WIFI_STATE
การดึงข้อมูล SSID หรือ BSSID ยังกำหนดให้ต้องเปิดใช้บริการตำแหน่งในอุปกรณ์ด้วย (ในส่วนการตั้งค่า > ตำแหน่ง)
ข้อมูลที่นำออกจากวิธีการให้บริการ Wi-Fi
ใน Android 9 เหตุการณ์และการออกอากาศต่อไปนี้จะไม่รับข้อมูลเกี่ยวกับตำแหน่งของผู้ใช้หรือข้อมูลที่ระบุตัวบุคคลได้
- วิธีการจาก
WifiManager
ที่ใช้วิธีgetScanResults()
และgetConnectionInfo()
- วิธีการ
discoverServices()
และaddServiceRequest()
จากWifiP2pManager
- ประกาศ
NETWORK_STATE_CHANGED_ACTION
ระบบ NETWORK_STATE_CHANGED_ACTION
ที่ออกอากาศจาก Wi-Fi ไม่มี SSID (เดิมคือ EXTRA_SSID) อีกต่อไป รวมถึงไม่มี BSSID (เดิมคือ EXTRA_BSSID) หรือข้อมูลการเชื่อมต่อ (เดิมคือ EXTRA_NETWORK_INFO) หากแอปของคุณต้องใช้ข้อมูลนี้ ให้เรียกใช้ getConnectionInfo()
แทน
ตอนนี้ข้อมูลการโทรจะอิงตามการตั้งค่าตำแหน่งของอุปกรณ์
หากผู้ใช้ปิดใช้ตำแหน่งของอุปกรณ์ในอุปกรณ์ที่ใช้ Android 9 อยู่ วิธีการต่อไปนี้จะไม่ได้ผล
ข้อจำกัดในการใช้อินเทอร์เฟซที่ไม่ใช่ SDK
แพลตฟอร์มจะจํากัดการใช้เมธอดและช่องที่ไม่ใช่ SDK บางรายการเพื่อช่วยรักษาความเสถียรและความเข้ากันได้ของแอป ข้อจํากัดเหล่านี้จะมีผลไม่ว่าคุณจะพยายามเข้าถึงเมธอดและช่องเหล่านี้โดยตรง ผ่านรีเฟล็กชัน หรือใช้ JNI ใน Android 9 แอปจะยังเข้าถึงอินเทอร์เฟซที่จํากัดเหล่านี้ได้อยู่ โดยแพลตฟอร์มจะใช้ข้อความแจ้งและรายการบันทึกเพื่อแจ้งให้คุณทราบ หากแอปแสดงข้อความแจ้งดังกล่าว คุณควรใช้กลยุทธ์การติดตั้งใช้งานอื่นนอกเหนือจากอินเทอร์เฟซที่จํากัด หากรู้สึกว่าไม่มีกลยุทธ์อื่นที่ทำได้ คุณสามารถยื่นข้อบกพร่องเพื่อขอให้พิจารณาข้อจำกัดอีกครั้ง
ข้อจำกัดเกี่ยวกับอินเทอร์เฟซที่ไม่ใช่ SDK มีข้อมูลเพิ่มเติมที่สำคัญ คุณควรตรวจสอบเพื่อให้มั่นใจว่าแอปจะยังคงทำงานได้อย่างถูกต้อง
การเปลี่ยนแปลงลักษณะการทํางานด้านความปลอดภัย
การเปลี่ยนแปลงด้านความปลอดภัยของอุปกรณ์
Android 9 เพิ่มความสามารถหลายอย่างที่จะช่วยปรับปรุงความปลอดภัยของแอป ไม่ว่าแอปจะกำหนดเป้าหมายเป็นเวอร์ชันใดก็ตาม
การเปลี่ยนแปลงการใช้งาน TLS
การใช้งาน TLS ของระบบมีการเปลี่ยนแปลงหลายอย่างใน Android 9 ดังนี้
- หากอินสแตนซ์ของ
SSLSocket
เชื่อมต่อไม่สำเร็จขณะสร้าง ระบบจะแสดงข้อผิดพลาดIOException
แทนที่จะเป็นNullPointerException
- คลาส
SSLEngine
จัดการการแจ้งเตือนclose_notify
ที่เกิดขึ้นได้อย่างเรียบร้อย
ดูข้อมูลเพิ่มเติมเกี่ยวกับการส่งคำขอเว็บที่ปลอดภัยในแอป Android ได้ที่ตัวอย่าง HTTPS
ตัวกรอง SECCOMP ที่เข้มงวดมากขึ้น
Android 9 จำกัดการเรียกระบบที่พร้อมให้บริการแก่แอปเพิ่มเติม ลักษณะการทํางานนี้เป็นส่วนขยายของตัวกรอง SECCOMP ที่ Android 8.0 (API ระดับ 26) รวมไว้
การเปลี่ยนแปลงการเข้ารหัส
Android 9 มีการเปิดตัวการเปลี่ยนแปลงหลายอย่างในการใช้งานและการจัดการอัลกอริทึมการเข้ารหัส
การใช้งานพารามิเตอร์และอัลกอริทึมของ Conscrypt
Android 9 มีการใช้งานพารามิเตอร์อัลกอริทึมเพิ่มเติมใน Conscrypt ซึ่งได้แก่ AES, DESEDE, OAEP และ EC เราเลิกใช้งานพารามิเตอร์และอัลกอริทึมจำนวนมากในเวอร์ชัน Bouncy Castle ตั้งแต่ Android 9
หากแอปกำหนดเป้าหมายเป็น Android 8.1 (API ระดับ 27) หรือต่ำกว่า คุณจะได้รับคำเตือนเมื่อขอใช้ Bouncy Castle กับอัลกอริทึมใดอัลกอริทึมหนึ่งเหล่านี้ที่เลิกใช้งานแล้ว แต่หากคุณกำหนดเป้าหมายเป็น Android 9 คำขอเหล่านี้จะแสดง NoSuchAlgorithmException
การเปลี่ยนแปลงอื่นๆ
Android 9 ยังมีการเปลี่ยนแปลงอื่นๆ ที่เกี่ยวข้องกับการเข้ารหัสอีกหลายประการ ดังนี้
- เมื่อใช้คีย์ PBE หาก Bouncy Castle คาดหวังว่าจะมีเวกเตอร์การเริ่มต้น (IV) และแอปของคุณไม่ได้ระบุ คุณจะได้รับคำเตือน
- การใช้งานการเข้ารหัส ARC4 ของ Conscrypt ให้คุณระบุได้ว่าจะARC4/ECB/NoPadding หรือ ARC4/NONE/NoPadding
- นําผู้ให้บริการ Crypto Java Cryptography Architecture (JCA) ออกแล้ว ด้วยเหตุนี้ หากแอปเรียก
SecureRandom.getInstance("SHA1PRNG", "Crypto")
ระบบจะแสดงNoSuchProviderException
- หากแอปของคุณแยกวิเคราะห์คีย์ RSA จากบัฟเฟอร์ที่ใหญ่กว่าโครงสร้างคีย์ ข้อยกเว้นจะไม่เกิดขึ้นอีก
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ความสามารถด้านวิทยาการเข้ารหัสของ Android ได้ที่วิทยาการเข้ารหัส
ไม่รองรับไฟล์ที่เข้ารหัสอย่างปลอดภัยของ Android อีกต่อไป
Android 9 นำการรองรับไฟล์ที่เข้ารหัสอย่างปลอดภัยของ Android (ASEC) ออกโดยสมบูรณ์
ใน Android 2.2 (API ระดับ 8) Android ได้เปิดตัว ASEC เพื่อรองรับฟังก์ชันการทำงานบนการ์ด SD ใน Android 6.0 (API ระดับ 23) แพลตฟอร์มได้เปิดตัวเทคโนโลยีอุปกรณ์เก็บข้อมูลที่พร้อมใช้งานซึ่งนักพัฒนาแอปสามารถใช้แทน ASEC ได้
การอัปเดตไลบรารี ICU
Android 9 ใช้ไลบรารี ICU เวอร์ชัน 60 Android 8.0 (API ระดับ 26) และ Android 8.1 (API ระดับ 27) ใช้ ICU 58
ICU ใช้เพื่อให้บริการ API สาธารณะภายใต้ android.icu package
และใช้ภายในแพลตฟอร์ม Android เพื่อรองรับการปรับให้เหมาะกับหลายภาษา
เช่น ใช้เพื่อติดตั้งใช้งานคลาส Android ใน java.util
, java.text
และ android.text.format
การอัปเดต ICU 60 มีการเปลี่ยนแปลงเล็กๆ น้อยๆ ที่มีประโยชน์มากมาย รวมถึงการรองรับข้อมูล Emoji 5.0 และรูปแบบวันที่/เวลาที่ได้รับการปรับปรุง ตามที่ระบุไว้ในบันทึกประจำรุ่นของ ICU 59 และ ICU 60
การเปลี่ยนแปลงที่สำคัญในการอัปเดตนี้
- แพลตฟอร์มมีการเปลี่ยนแปลงวิธีจัดการเขตเวลา
- แพลตฟอร์มจัดการกับเขตเวลา GMT และ UTC ได้ดียิ่งขึ้น UTC จึงไม่ได้หมายถึงเขตเวลา GMT อีกต่อไป
ตอนนี้ ICU มีชื่อโซนที่แปลแล้วสำหรับ GMT และ UTC การเปลี่ยนแปลงนี้ส่งผลต่อ
android.icu
รูปแบบและลักษณะการแยกวิเคราะห์สำหรับเขตเวลา เช่น "GMT", "Etc/GMT", "UTC", "Etc/UTC" และ "Zulu" - ตอนนี้
java.text.SimpleDateFormat
ใช้ ICU เพื่อระบุชื่อที่แสดงสำหรับ UTC /GMT ซึ่งหมายความว่า- การจัดรูปแบบ
zzzz
จะสร้างสตริงที่แปลแล้วยาวๆ สำหรับหลายภาษา ก่อนหน้านี้ รูปแบบจะแสดง "UTC" สำหรับ UTC และสตริงอย่าง "GMT+00:00" สำหรับ GMT - การปั่น
zzzz
จะจดจำสตริง เช่น "เวลาสากลเชิงพิกัด" และ "เวลามาตรฐานกรีนิช" - แอปอาจพบปัญหาความเข้ากันได้หากคิดว่า "UTC" หรือ "GMT+00:00" เป็นเอาต์พุตสำหรับ
zzzz
ในทุกภาษา
- การจัดรูปแบบ
- ลักษณะการทํางานของ
java.text.DateFormatSymbols.getZoneStrings()
มีการเปลี่ยนแปลงดังนี้- ตอนนี้ UTC และ GMT มีชื่อแบบยาวเช่นเดียวกับ
SimpleDateFormat
ชื่อเขตเวลาสำหรับเขตเวลา UTC รูปแบบ DST เช่น "UTC", "Etc/UTC" และ "Zulu" จะเปลี่ยนเป็น GMT+00:00 ซึ่งเป็นค่ามาตรฐานสำรองเมื่อไม่มีชื่อแทนสตริงที่ฮาร์ดโค้ดUTC
- ระบบจะจดจำรหัสเขตบางรหัสเป็นคำพ้องความหมายของเขตอื่นๆ อย่างถูกต้อง เพื่อให้ Android ค้นหาสตริงสำหรับรหัสเขตแบบเก่า เช่น
Eire
ซึ่งก่อนหน้านี้ไม่สามารถแก้ไขได้
- ตอนนี้ UTC และ GMT มีชื่อแบบยาวเช่นเดียวกับ
- Asia/Hanoi ไม่ใช่โซนที่ระบบรู้จักอีกต่อไป ด้วยเหตุนี้
java.util.TimeZones.getAvailableIds()
จึงไม่แสดงค่านี้ และjava.util.TimeZone.getTimeZone()
ก็ไม่รู้จักค่านี้ ลักษณะการทํางานนี้สอดคล้องกับลักษณะการทํางานของandroid.icu
ที่มีอยู่
- แพลตฟอร์มจัดการกับเขตเวลา GMT และ UTC ได้ดียิ่งขึ้น UTC จึงไม่ได้หมายถึงเขตเวลา GMT อีกต่อไป
android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String)
วิธีการนี้อาจแสดงParseException
แม้ว่าจะแยกวิเคราะห์ข้อความสกุลเงินที่ถูกต้องก็ตาม หลีกเลี่ยงปัญหานี้โดยใช้NumberFormat.parseCurrency
ซึ่งพร้อมใช้งานตั้งแต่ Android 7.0 (API ระดับ 24) สำหรับข้อความสกุลเงินสไตล์PLURALCURRENCYSTYLE
การเปลี่ยนแปลงการทดสอบ Android
Android 9 มีการเปิดตัวการเปลี่ยนแปลงหลายอย่างในไลบรารีและโครงสร้างคลาสของเฟรมเวิร์กการทดสอบ Android การเปลี่ยนแปลงเหล่านี้ช่วยให้นักพัฒนาแอปใช้ API สาธารณะที่เฟรมเวิร์กรองรับได้ แต่การเปลี่ยนแปลงนี้ยังช่วยให้การสร้างและการทดสอบโดยใช้ไลบรารีของบุคคลที่สามหรือตรรกะที่กำหนดเองมีความยืดหยุ่นมากขึ้นด้วย
นำไลบรารีออกจากเฟรมเวิร์กแล้ว
Android 9 จัดระเบียบคลาสที่อิงตาม JUnit ใหม่เป็น 3 ไลบรารี ได้แก่ android.test.base, android.test.runner และ android.test.mock
การเปลี่ยนแปลงนี้ช่วยให้คุณทำการทดสอบกับ JUnit เวอร์ชันที่ทำงานร่วมกับทรัพยากรของโปรเจ็กต์ได้ดีที่สุด JUnit เวอร์ชันนี้อาจแตกต่างจากเวอร์ชันที่ android.jar
มีให้
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดระเบียบคลาสที่อิงตาม JUnit ไว้ในไลบรารีเหล่านี้ รวมถึงวิธีเตรียมโปรเจ็กต์ของแอปสำหรับการเขียนและเรียกใช้การทดสอบได้ที่ตั้งค่าโปรเจ็กต์สําหรับ Android Test
การเปลี่ยนแปลงบิลด์ชุดทดสอบ
ระบบได้นำเมธอด addRequirements()
ในคลาส TestSuiteBuilder
ออกแล้ว และเลิกใช้งานคลาส TestSuiteBuilder
ด้วย
เมธอด addRequirements()
กำหนดให้นักพัฒนาแอปต้องระบุอาร์กิวเมนต์ที่มีประเภทเป็น API ที่ซ่อนอยู่ ซึ่งทำให้ API ไม่ถูกต้อง
ตัวถอดรหัส UTF ของ Java
UTF-8 เป็นชุดอักขระเริ่มต้นใน Android อนุกรมไบต์ UTF-8 สามารถถอดรหัสได้โดยใช้ตัวสร้าง String
เช่น String(byte[] bytes)
ตัวถอดรหัส UTF-8 ใน Android 9 เป็นไปตามมาตรฐาน Unicode อย่างเข้มงวดกว่าในเวอร์ชันก่อนหน้า การเปลี่ยนแปลงดังกล่าวมีดังนี้
- ระบบจะถือว่ารูปแบบ UTF-8 ที่ไม่ใช่รูปแบบที่สั้นที่สุด เช่น
<C0, AF>
อยู่ในรูปแบบที่ไม่ถูกต้อง - ระบบจะถือว่ารูปแบบตัวแทนของ UTF-8 เช่น
U+D800
..U+DFFF
อยู่ในรูปแบบที่ไม่ถูกต้อง - ระบบจะแทนที่ส่วนย่อยสูงสุดด้วย
U+FFFD
เพียงตัวเดียว เช่น ในลำดับไบต์ "41 C0 AF 41 F4 80 80 41
" ชิ้นส่วนย่อยที่มีความยาวสูงสุดคือ "C0
" "AF
" และ "F4 80 80
" โดย "F4 80 80
" อาจเป็นอนุกรมย่อยเริ่มต้นของ "F4 80 80 80
" ได้ แต่ "C0
" ไม่สามารถเป็นอนุกรมย่อยเริ่มต้นของลำดับหน่วยโค้ดที่ถูกต้อง ดังนั้นเอาต์พุตควรเป็น "A\ufffd\ufffdA\ufffdA
" - หากต้องการถอดรหัสลำดับ UTF-8 / CESU-8 ที่แก้ไขแล้วใน Android 9 ขึ้นไป ให้ใช้วิธี
DataInputStream.readUTF()
หรือวิธีNewStringUTF()
JNI
การยืนยันชื่อโฮสต์โดยใช้ใบรับรอง
RFC 2818 อธิบายวิธีการ 2 วิธีในการจับคู่ชื่อโดเมนกับใบรับรอง โดยใช้ชื่อที่มีให้ภายในส่วนขยาย subjectAltName
(SAN
) หรือในกรณีที่ไม่มีส่วนขยาย SAN
ระบบจะใช้ส่วนขยาย commonName
(CN
) แทน
อย่างไรก็ตาม มีการเลิกใช้งานการกลับไปใช้ CN
ใน RFC 2818 ด้วยเหตุนี้ Android จึงไม่ได้เปลี่ยนไปใช้ CN
อีกต่อไป หากต้องการยืนยันชื่อโฮสต์ เซิร์ฟเวอร์ต้องแสดงใบรับรองที่มี SAN
ที่ตรงกัน ระบบจะไม่เชื่อถือใบรับรองที่ไม่มี SAN
ที่ตรงกับชื่อโฮสต์อีกต่อไป
การค้นหาที่อยู่เครือข่ายอาจทำให้เกิดการละเมิดเครือข่าย
การค้นหาที่อยู่เครือข่ายที่ต้องใช้การแก้ไขชื่ออาจเกี่ยวข้องกับ I/O ของเครือข่าย จึงถือว่าเป็นการดำเนินการที่บล็อก การดำเนินการที่บล็อกในเทรดหลักอาจทำให้ระบบหยุดชั่วคราวหรือกระตุก
คลาส StrictMode
เป็นเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ที่จะช่วยนักพัฒนาซอฟต์แวร์ตรวจหาปัญหาในโค้ด
ใน Android 9 ขึ้นไป StrictMode
จะตรวจหาการละเมิดเครือข่ายที่เกิดจากการค้นหาที่อยู่เครือข่ายซึ่งต้องใช้การแก้ไขชื่อ
คุณไม่ควรเผยแพร่แอปที่เปิดใช้ StrictMode
หากใช้ คุณจะพบข้อยกเว้นในแอป เช่น NetworkOnMainThreadException
เมื่อใช้วิธี detectNetwork()
หรือ detectAll()
เพื่อรับนโยบายที่ตรวจหาการละเมิดเครือข่าย
การแก้ไขที่อยู่ IP แบบตัวเลขไม่ถือว่าเป็นการดำเนินการบล็อก การแก้ไขที่อยู่ IP แบบตัวเลขจะทำงานเหมือนกับในเวอร์ชันก่อน Android 9
การติดแท็กซ็อกเก็ต
ในแพลตฟอร์มเวอร์ชันที่ต่ำกว่า Android 9 หากมีการติดแท็กซ็อกเก็ตโดยใช้เมธอด setThreadStatsTag()
ระบบจะนำการติดแท็กออกเมื่อส่งซ็อกเก็ตไปยังกระบวนการอื่นโดยใช้ binder IPC ที่มีคอนเทนเนอร์ ParcelFileDescriptor
ใน Android 9 ขึ้นไป ระบบจะเก็บแท็กซ็อกเก็ตไว้เมื่อส่งไปยังกระบวนการอื่นโดยใช้ Binder IPC การเปลี่ยนแปลงนี้อาจส่งผลต่อสถิติการเข้าชมเครือข่าย เช่น เมื่อใช้วิธีการ queryDetailsForUidTag()
หากต้องการคงลักษณะการทํางานของเวอร์ชันก่อนหน้าไว้ ซึ่งจะยกเลิกการติดแท็กซ็อกเก็ตที่ส่งไปยังกระบวนการอื่น คุณสามารถเรียกใช้ untagSocket()
ก่อนส่งซ็อกเก็ต
จำนวนไบต์ที่พร้อมใช้งานในซ็อกเก็ตที่รายงาน
เมธอด available()
จะแสดงผล 0
เมื่อมีการเรียกใช้หลังจากเรียกใช้เมธอด shutdownInput()
การรายงานความสามารถของเครือข่ายที่ละเอียดยิ่งขึ้นสำหรับ VPN
ใน Android 8.1 (API ระดับ 27) และต่ำกว่า คลาส NetworkCapabilities
จะรายงานเฉพาะชุดข้อมูลที่จํากัดสําหรับ VPN เช่น TRANSPORT_VPN
แต่จะไม่รายงาน NET_CAPABILITY_NOT_VPN
ข้อมูลที่จํากัดนี้ทําให้ระบุได้ยากว่าการใช้ VPN จะทําให้ผู้ใช้แอปถูกเรียกเก็บเงินหรือไม่ ตัวอย่างเช่น การตรวจสอบ NET_CAPABILITY_NOT_METERED
จะไม่ระบุว่าเครือข่ายพื้นฐานมีการวัดหรือไม่
ใน Android 9 ขึ้นไป เมื่อ VPN เรียกใช้วิธี setUnderlyingNetworks()
ระบบ Android จะผสานการขนส่งและความสามารถของเครือข่ายที่อยู่เบื้องหลัง และแสดงผลลัพธ์เป็นความสามารถของเครือข่ายที่มีประสิทธิภาพของเครือข่าย VPN
ใน Android 9 ขึ้นไป แอปที่ตรวจสอบNET_CAPABILITY_NOT_METERED
อยู่แล้วจะได้รับความสามารถของเครือข่าย VPN และเครือข่ายที่อยู่เบื้องหลัง
ไฟล์ในโฟลเดอร์ xt_qtaguid จะไม่พร้อมใช้งานสำหรับแอปอีกต่อไป
ตั้งแต่ Android 9 เป็นต้นไป แอปไม่ได้รับอนุญาตให้มีสิทธิ์เข้าถึงไฟล์ในโฟลเดอร์ /proc/net/xt_qtaguid
โดยตรง ทั้งนี้เพื่อให้มีความสอดคล้องกับอุปกรณ์บางรุ่นที่ไม่มีไฟล์เหล่านี้เลย
API สาธารณะที่ใช้ไฟล์เหล่านี้ TrafficStats
และ
NetworkStatsManager
จะยังคงทำงานต่อไปตามที่ต้องการ
อย่างไรก็ตาม ฟังก์ชัน cutils ที่ระบบไม่รองรับ เช่น qtaguid_tagSocket()
อาจไม่ทำงานตามที่คาดไว้หรืออาจไม่ทำงานเลยในอุปกรณ์ต่างๆ
ตอนนี้เราบังคับใช้ข้อกำหนด FLAG_ACTIVITY_NEW_TASK แล้ว
ใน Android 9 คุณจะไม่สามารถเริ่มกิจกรรมจากบริบทที่ไม่ใช่กิจกรรมได้ เว้นแต่คุณจะส่ง Flag Intent FLAG_ACTIVITY_NEW_TASK
หากคุณพยายามเริ่มกิจกรรมโดยไม่ส่ง Flag นี้ กิจกรรมจะไม่เริ่มต้น และระบบจะพิมพ์ข้อความไปยังบันทึก
การเปลี่ยนแปลงการหมุนหน้าจอ
ตั้งแต่ Android 9 เป็นต้นไป จะมีการทําการเปลี่ยนแปลงที่สําคัญในโหมดการหมุนแนวตั้ง ใน Android 8.0 (API ระดับ 26) ผู้ใช้สลับระหว่างโหมดการหมุนอัตโนมัติกับแนวตั้งได้โดยใช้การ์ดการตั้งค่าด่วนหรือการตั้งค่าการแสดงผล โหมดแนวตั้งเปลี่ยนชื่อเป็นการล็อกการหมุนแล้ว และจะทำงานเมื่อปิดการหมุนอัตโนมัติไว้ จะไม่มีการเปลี่ยนแปลงโหมดการหมุนอัตโนมัติ
เมื่ออุปกรณ์อยู่ในโหมดล็อกการหมุน ผู้ใช้จะล็อกหน้าจอให้อยู่ในการหมุนใดก็ได้ที่กิจกรรมที่มองเห็นได้ด้านบนรองรับ กิจกรรมไม่ควรถือว่าระบบจะแสดงผลในแนวตั้งเสมอ หากกิจกรรมยอดนิยมแสดงผลได้ด้วยการหมุนหลายรูปแบบในโหมดหมุนอัตโนมัติ ตัวเลือกเดียวกันนี้ควรมีให้ใช้งานในโหมดล็อกการหมุน โดยมีข้อยกเว้นบางประการตามการตั้งค่าscreenOrientation
ของกิจกรรม (ดูตารางด้านล่าง)
กิจกรรมที่ขอการวางแนวที่เจาะจง (เช่น screenOrientation=landscape
) จะละเว้นค่ากำหนดการล็อกของผู้ใช้และทำงานในลักษณะเดียวกับใน Android 8.0
คุณสามารถตั้งค่ากำหนดการวางแนวหน้าจอที่ระดับกิจกรรมใน Android Manifest หรือตั้งค่าแบบเป็นโปรแกรมด้วย setRequestedOrientation()
โหมดล็อกการหมุนจะทำงานโดยการตั้งค่าการหมุนของผู้ใช้ซึ่ง WindowManager จะใช้เมื่อจัดการการหมุนของกิจกรรม ค่ากำหนดการหมุนเวียนผู้ใช้อาจเปลี่ยนแปลงในกรณีต่อไปนี้ โปรดทราบว่าระบบมีแนวโน้มที่จะกลับไปใช้การหมุนตามปกติของอุปกรณ์ ซึ่งโดยปกติแล้วจะเป็นแนวตั้งสำหรับอุปกรณ์ที่มีรูปแบบของโทรศัพท์
- เมื่อผู้ใช้ยอมรับคำแนะนำการหมุน การตั้งค่าการหมุนจะเปลี่ยนเป็นคำแนะนำนั้น
- เมื่อผู้ใช้เปลี่ยนไปใช้แอปที่บังคับให้แสดงในแนวตั้ง (รวมถึงหน้าจอล็อกหรือตัวเปิดแอป) ค่ากำหนดการหมุนจะเปลี่ยนเป็นแนวตั้ง
ตารางต่อไปนี้สรุปลักษณะการหมุนสำหรับการวางแนวหน้าจอที่พบได้ทั่วไป
การวางแนวหน้าจอ | ลักษณะการทำงาน |
---|---|
ผู้ใช้ที่ไม่ระบุ | ในโหมดหมุนอัตโนมัติและโหมดล็อกการหมุน กิจกรรมจะแสดงผลในแนวตั้งหรือแนวนอน (และในทางกลับกัน) รองรับทั้งเลย์เอาต์แนวตั้งและแนวนอน |
userLandscape | ในโหมดหมุนอัตโนมัติและโหมดล็อกการหมุน กิจกรรมจะแสดงผลในแนวนอนหรือแนวนอนกลับก็ได้ คาดว่าจะรองรับเฉพาะเลย์เอาต์แนวนอน |
userPortrait | ในโหมดหมุนอัตโนมัติและโหมดล็อกการหมุน กิจกรรมจะแสดงผลเป็นภาพแนวตั้งหรือแนวตั้งกลับก็ได้ คาดว่าจะรองรับเฉพาะเลย์เอาต์แนวตั้ง |
fullUser | ในโหมดหมุนอัตโนมัติและโหมดล็อกการหมุน กิจกรรมจะแสดงผลในแนวตั้งหรือแนวนอน (และในทางกลับกัน) คาดว่าจะรองรับทั้งเลย์เอาต์แนวตั้งและแนวนอน ผู้ใช้ที่ล็อกการหมุนจะมีตัวเลือกในการล็อกเป็นแนวตั้งกลับหัว ซึ่งมักเป็น 180º |
sensor, fullSensor, sensorPortrait, sensorLandscape | ระบบจะไม่สนใจค่ากำหนดโหมดล็อกการหมุนและจะถือว่าการหมุนอัตโนมัติทำงานอยู่ ใช้เฉพาะในกรณีที่พิเศษและพิจารณา UX อย่างรอบคอบ |
การเลิกใช้งานไคลเอ็นต์ Apache HTTP จะส่งผลต่อแอปที่มี ClassLoader ที่ไม่เป็นไปตามมาตรฐาน
ใน Android 6.0 เราได้ยกเลิกการรองรับไคลเอ็นต์ HTTP ของ Apache
การเปลี่ยนแปลงนี้ไม่มีผลต่อแอปส่วนใหญ่ที่ไม่ได้กำหนดเป้าหมายเป็น Android 9 ขึ้นไป อย่างไรก็ตาม การเปลี่ยนแปลงนี้อาจส่งผลต่อแอปบางแอปที่ใช้โครงสร้าง ClassLoader
ที่ไม่เป็นไปตามมาตรฐาน แม้ว่าแอปจะไม่กำหนดเป้าหมายเป็น Android 9 ขึ้นไปก็ตาม
แอปอาจได้รับผลกระทบหากใช้ ClassLoader
ที่ไม่เป็นไปตามมาตรฐานซึ่งมอบสิทธิ์ให้กับ ClassLoader
ของระบบอย่างชัดเจน แอปเหล่านี้ต้องมอบสิทธิ์ให้ app
ClassLoader
แทนเมื่อค้นหาชั้นเรียนใน org.apache.http.*
หากแอปมอบสิทธิ์ให้ระบบ ClassLoader
แอปจะใช้งานไม่ได้ใน Android 9 ขึ้นไปด้วย NoClassDefFoundError
เนื่องจากระบบ ClassLoader
จะไม่รู้จักคลาสเหล่านั้นอีกต่อไป โดยทั่วไปแล้ว แอปควรโหลดคลาสผ่านแอป ClassLoader
แทนการเข้าถึงระบบ ClassLoader
โดยตรงเพื่อป้องกันไม่ให้เกิดปัญหาที่คล้ายกันในอนาคต
ระบุจำนวนกล้อง
แอปที่ทำงานในอุปกรณ์ Android 9 จะค้นพบกล้องที่พร้อมใช้งานทั้งหมดได้โดยเรียกใช้ getCameraIdList()
แอปไม่ควรสมมติว่าอุปกรณ์มีกล้องหลังเพียงตัวเดียวหรือกล้องหน้าเพียงตัวเดียว
เช่น หากแอปมีปุ่มสลับระหว่างกล้องหน้ากับกล้องหลัง อาจมีกล้องหน้าหรือกล้องหลังให้เลือกมากกว่า 1 ตัว คุณควรดูรายการกล้อง ตรวจสอบลักษณะของกล้องแต่ละตัว และตัดสินใจว่าจะแสดงกล้องใดต่อผู้ใช้