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

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

หาก targetSdkVersion ของแอปคือ 29 ขึ้นไป คุณจะต้องรองรับการเปลี่ยนแปลงเพิ่มเติมด้วย โปรดอ่านรายละเอียดการเปลี่ยนแปลงลักษณะการทำงานของแอปที่กำหนดเป้าหมายเป็น 29

หมายเหตุ: นอกเหนือจากการเปลี่ยนแปลงที่แสดงในหน้านี้แล้ว Android 10 ยังมีการเปลี่ยนแปลงและข้อจำกัดด้านความเป็นส่วนตัวจำนวนมาก ซึ่งรวมถึงสิ่งต่อไปนี้

  • การเข้าถึงตำแหน่งอุปกรณ์เมื่ออยู่เบื้องหลัง
  • การเริ่มต้นกิจกรรมในเบื้องหลัง
  • ข้อมูลความสนิทสนมของรายชื่อติดต่อ
  • การสุ่มที่อยู่ MAC
  • ข้อมูลเมตาของกล้อง
  • โมเดลสิทธิ์

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

ข้อจำกัดของอินเทอร์เฟซที่ไม่ใช่ SDK

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

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

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

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

การไปยังส่วนต่างๆ ด้วยท่าทางสัมผัส

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

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

NDK

Android 10 มีการเปลี่ยนแปลง NDK ต่อไปนี้

ออบเจ็กต์ที่แชร์ต้องไม่มีการย้ายตำแหน่งข้อความ

Android 6.0 (ระดับ API 23) ไม่อนุญาตให้ใช้การย้ายตำแหน่งข้อความในออบเจ็กต์ที่ใช้ร่วมกัน ต้องโหลดโค้ดตามที่เป็นอยู่และต้องไม่มีการแก้ไข การเปลี่ยนแปลงนี้จะช่วยปรับปรุงเวลาในการโหลดและความปลอดภัยของแอป

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

การเปลี่ยนแปลงไลบรารี Bionic และเส้นทาง Linker แบบไดนามิก

ตั้งแต่ Android 10 เป็นต้นไป เส้นทางหลายเส้นทางจะเป็นลิงก์สัญลักษณ์แทนไฟล์ปกติ แอปที่อาศัยเส้นทางที่เป็นไฟล์ปกติอาจใช้งานไม่ได้

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

การเปลี่ยนแปลงเหล่านี้จะมีผลกับตัวแปร 64 บิตของไฟล์ด้วย โดย lib/ จะแทนที่ด้วย lib64/

ระบบจะระบุ Symlink ไว้ที่เส้นทางเดิมเพื่อให้ใช้งานร่วมกันได้ เช่น /system/lib/libc.so เป็นลิงก์สัญลักษณ์ไปยัง /apex/com.android.runtime/lib/bionic/libc.so ดังนั้น dlopen(“/system/lib/libc.so”) จะยังคงทำงานต่อไป แต่แอปจะพบความแตกต่างเมื่อพยายามตรวจสอบไลบรารีที่โหลดโดยการอ่าน /proc/self/maps หรือที่คล้ายกัน ซึ่งไม่ใช่เรื่องปกติ แต่เราพบว่าแอปบางแอปทำเช่นนั้นเป็นส่วนหนึ่งของกระบวนการต่อต้านการแฮ็ก หากเป็นเช่นนั้น ควรเพิ่มเส้นทาง /apex/… เป็นเส้นทางที่ถูกต้องสำหรับไฟล์ Bionic

ไบนารี/ไลบรารีของระบบที่แมปกับหน่วยความจำแบบ Execute-Only

ตั้งแต่ Android 10 เป็นต้นไป ส่วนที่เรียกใช้ได้ของไบนารีและไลบรารีของระบบจะได้รับการแมปเข้ากับหน่วยความจำแบบเรียกใช้เท่านั้น (อ่านไม่ได้) เพื่อเป็นเทคนิคการเสริมความแข็งแกร่งในการป้องกันการโจมตีด้วยการใช้โค้ดซ้ำ หากแอปของคุณดำเนินการอ่านในส่วนหน่วยความจำที่ทำเครื่องหมายเป็นแบบดำเนินการเท่านั้น ไม่ว่าจะมาจากข้อบกพร่อง ช่องโหว่ หรือการตรวจสอบหน่วยความจำโดยเจตนา ระบบจะส่งสัญญาณ SIGSEGV ไปยังแอปของคุณ

คุณสามารถระบุได้ว่าลักษณะการทำงานนี้ทำให้เกิดข้อขัดข้องหรือไม่โดยตรวจสอบไฟล์ Tombstone ที่เกี่ยวข้องใน /data/tombstones/ ข้อขัดข้องที่เกี่ยวข้องกับการดำเนินการเท่านั้นจะมีข้อความการยกเลิกต่อไปนี้

Cause: execute-only (no-read) memory access error; likely due to data in .text.

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

ความปลอดภัย

Android 10 มีการเปลี่ยนแปลงด้านความปลอดภัยต่อไปนี้

เปิดใช้ TLS 1.3 โดยค่าเริ่มต้น

ใน Android 10 ขึ้นไป ระบบจะเปิดใช้ TLS 1.3 โดยค่าเริ่มต้นสำหรับการเชื่อมต่อ TLS ทั้งหมด รายละเอียดสำคัญเกี่ยวกับการใช้งาน TLS 1.3 มีดังนี้

  • คุณปรับแต่งชุดการเข้ารหัส TLS 1.3 ไม่ได้ ชุดการเข้ารหัส TLS 1.3 ที่รองรับจะเปิดใช้อยู่เสมอเมื่อเปิดใช้ TLS 1.3 ระบบจะไม่สนใจความพยายามปิดใช้โดยการเรียกใช้ setEnabledCipherSuites()
  • เมื่อมีการเจรจา TLS 1.3 ระบบจะเรียกใช้ออบเจ็กต์ HandshakeCompletedListener ก่อนที่จะเพิ่มเซสชันลงในแคชเซสชัน (ใน TLS 1.2 และเวอร์ชันก่อนหน้าอื่นๆ ระบบจะเรียกออบเจ็กต์เหล่านี้หลังจากเพิ่มเซสชันลงในแคชเซสชัน)
  • ในบางสถานการณ์ที่อินสแตนซ์ SSLEngine แสดง SSLHandshakeException ใน Android เวอร์ชันก่อนหน้า อินสแตนซ์เหล่านี้จะแสดง SSLProtocolException แทนใน Android 10 ขึ้นไป
  • ไม่รองรับโหมด 0-RTT

หากต้องการ คุณสามารถรับ SSLContext ที่ปิดใช้ TLS 1.3 ได้โดยเรียกใช้ SSLContext.getInstance("TLSv1.2") นอกจากนี้ คุณยังเปิดหรือปิดใช้เวอร์ชันโปรโตคอลตามการเชื่อมต่อแต่ละรายการได้โดยเรียกใช้ setEnabledProtocols() ในออบเจ็กต์ที่เหมาะสม

ใบรับรองที่ลงนามด้วย SHA-1 ไม่น่าเชื่อถือใน TLS

ใน Android 10 ใบรับรองที่ใช้อัลกอริทึมแฮช SHA-1 จะไม่ได้รับความเชื่อถือในการเชื่อมต่อ TLS CA รูทไม่ได้ออกใบรับรองดังกล่าวตั้งแต่ปี 2016 และ Chrome หรือเบราว์เซอร์หลักอื่นๆ ไม่เชื่อถือใบรับรองดังกล่าวอีกต่อไป

การพยายามเชื่อมต่อจะล้มเหลวหากเป็นการเชื่อมต่อกับเว็บไซต์ที่แสดงใบรับรองที่ใช้ SHA-1

การเปลี่ยนแปลงและการปรับปรุงลักษณะการทำงานของ KeyChain

เบราว์เซอร์บางรายการ เช่น Google Chrome อนุญาตให้ผู้ใช้เลือกใบรับรองเมื่อเซิร์ฟเวอร์ TLS ส่งข้อความคำขอใบรับรองเป็นส่วนหนึ่งของแฮนด์เชค TLS ตั้งแต่ Android 10 เป็นต้นมา ออบเจ็กต์ KeyChain จะเป็นไปตามผู้ออกและพารามิเตอร์ข้อกำหนดคีย์เมื่อเรียกใช้ KeyChain.choosePrivateKeyAlias() เพื่อแสดงข้อความแจ้งการเลือกใบรับรองแก่ผู้ใช้ โดยเฉพาะอย่างยิ่ง พรอมต์นี้ไม่มีตัวเลือกที่ไม่เป็นไปตามข้อกำหนดของเซิร์ฟเวอร์

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

นอกจากนี้ ใน Android 10 ขึ้นไป คุณไม่จำเป็นต้องล็อกหน้าจออุปกรณ์เพื่อนำเข้าคีย์หรือใบรับรอง CA ไปยังออบเจ็กต์ KeyChain

การเปลี่ยนแปลงอื่นๆ เกี่ยวกับ TLS และวิทยาการเข้ารหัส

มีการเปลี่ยนแปลงเล็กน้อยหลายรายการในไลบรารี TLS และวิทยาการเข้ารหัสที่มีผลใน Android 10 ดังนี้

  • การเข้ารหัส AES/GCM/NoPadding และ ChaCha20/Poly1305/NoPadding จะแสดงผลขนาดบัฟเฟอร์ที่แม่นยำยิ่งขึ้นจาก getOutputSize()
  • ระบบจะละเว้นชุดการเข้ารหัส TLS_FALLBACK_SCSV จากการพยายามเชื่อมต่อที่มีโปรโตคอลสูงสุดเป็น TLS 1.2 ขึ้นไป เนื่องจากการปรับปรุงการใช้งานเซิร์ฟเวอร์ TLS เราจึงไม่แนะนำให้พยายามใช้ TLS-external เป็นทางเลือกสำรอง เราขอแนะนำให้ใช้การเจรจาต่อรองเวอร์ชัน TLS แทน
  • ChaCha20-Poly1305 เป็นชื่อแทนของ ChaCha20/Poly1305/NoPadding
  • ชื่อโฮสต์ที่มีจุดต่อท้ายไม่ถือว่าเป็นชื่อโฮสต์ SNI ที่ถูกต้อง
  • ระบบจะใช้ส่วนขยาย supported_signature_algorithms ใน CertificateRequest เมื่อเลือกคีย์การรับรองสำหรับการตอบกลับใบรับรอง
  • คีย์การรับรองแบบทึบแสง เช่น คีย์จาก Android Keystore สามารถใช้กับลายเซ็น RSA-PSS ใน TLS ได้

การออกอากาศ Wi-Fi Direct

ใน Android 10 การออกอากาศต่อไปนี้ที่เกี่ยวข้องกับ Wi-Fi Direct จะไม่ติดหนึบ

หากแอปของคุณอาศัยการรับการออกอากาศเหล่านี้เมื่อลงทะเบียนเนื่องจากเป็นแบบติดหนึบ ให้ใช้เมธอด get() ที่เหมาะสมในการเริ่มต้นเพื่อรับข้อมูลแทน

ความสามารถของ Wi-Fi Aware

Android 10 เพิ่มการรองรับเพื่อช่วยให้สร้างซ็อกเก็ต TCP/UDP ได้ง่ายขึ้นโดยใช้เส้นทางข้อมูล Wi-Fi Aware หากต้องการสร้างซ็อกเก็ต TCP/UDP ที่เชื่อมต่อกับ ServerSocket อุปกรณ์ไคลเอ็นต์ต้องทราบที่อยู่ IPv6 และพอร์ตของเซิร์ฟเวอร์ ก่อนหน้านี้ต้องสื่อสารข้อมูลนี้แบบ Out-of-Band เช่น โดยใช้การรับส่งข้อความเลเยอร์ 2 ของ BT หรือ Wi-Fi Aware หรือค้นพบแบบ In-Band โดยใช้โปรโตคอลอื่นๆ เช่น mDNS ใน Android 10 ข้อมูลนี้จะสื่อสารได้โดยเป็นส่วนหนึ่งของการตั้งค่าเครือข่าย

เซิร์ฟเวอร์สามารถดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้

  • เริ่มต้น ServerSocket และตั้งค่าหรือรับพอร์ตที่จะใช้
  • ระบุข้อมูลพอร์ตเป็นส่วนหนึ่งของคำขอเครือข่าย Wi-Fi Aware

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีระบุข้อมูลพอร์ตเป็นส่วนหนึ่งของคำขอเครือข่าย

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Java

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(“some-password”)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

จากนั้นไคลเอ็นต์จะส่งคำขอเครือข่าย Wi-Fi Aware เพื่อรับ IPv6 และพอร์ตที่เซิร์ฟเวอร์ระบุ ดังนี้

Kotlin

val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Java

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

SYSTEM_ALERT_WINDOW ในอุปกรณ์ Go

แอปที่ทำงานในอุปกรณ์ Android 10 (รุ่น Go) จะไม่ได้รับสิทธิ์ SYSTEM_ALERT_WINDOW เนื่องจากการวาดหน้าต่างวางซ้อนใช้หน่วยความจำมากเกินไป ซึ่งส่งผลเสียต่อประสิทธิภาพของอุปกรณ์ Android ที่มีหน่วยความจำต่ำ

หากแอปที่ทำงานในอุปกรณ์ Go Edition ที่ใช้ Android 9 หรือต่ำกว่าได้รับสิทธิ์ SYSTEM_ALERT_WINDOW แอปจะยังคงมีสิทธิ์ดังกล่าวแม้ว่าอุปกรณ์จะอัปเกรดเป็น Android 10 ก็ตาม อย่างไรก็ตาม แอปที่ยังไม่มีสิทธิ์ดังกล่าวจะไม่ได้รับสิทธิ์หลังจากอัปเกรดอุปกรณ์

หากแอปในอุปกรณ์ Go ส่ง Intent ที่มีการดำเนินการ ACTION_MANAGE_OVERLAY_PERMISSION ระบบจะปฏิเสธคำขอโดยอัตโนมัติ และนำผู้ใช้ไปยังหน้าจอการตั้งค่าซึ่งระบุว่าไม่อนุญาตสิทธิ์เนื่องจากจะทำให้อุปกรณ์ทำงานช้าลง หากแอปในอุปกรณ์ Go เรียกใช้ Settings.canDrawOverlays() เมธอดจะแสดงผลเป็นเท็จเสมอ ขอย้ำอีกครั้งว่าข้อจำกัดเหล่านี้ไม่มีผลกับแอปที่ได้รับสิทธิ์ SYSTEM_ALERT_WINDOW ก่อนที่อุปกรณ์จะอัปเกรดเป็น Android 10

คำเตือนสำหรับแอปที่กำหนดเป้าหมายเป็น Android เวอร์ชันเก่า

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

เนื่องจากข้อกำหนด API เป้าหมายของ Google Play ผู้ใช้จะเห็นคำเตือนเหล่านี้ก็ต่อเมื่อเรียกใช้แอปที่ไม่ได้อัปเดตเมื่อเร็วๆ นี้ สำหรับแอปที่จัดจำหน่ายผ่าน Store อื่นๆ ข้อกำหนดระดับ API เป้าหมายที่คล้ายกันจะมีผลบังคับใช้ในปี 2019 ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อกำหนดเหล่านี้ได้ที่การขยายข้อกำหนดเกี่ยวกับระดับ API เป้าหมายในปี 2019

นำชุดการเข้ารหัส SHA-2 CBC ออกแล้ว

ระบบได้นำชุดการเข้ารหัส SHA-2 CBC ต่อไปนี้ออกจากแพลตฟอร์มแล้ว

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

ชุดการเข้ารหัสเหล่านี้มีความปลอดภัยน้อยกว่าชุดการเข้ารหัสที่คล้ายกันซึ่งใช้ GCM และเซิร์ฟเวอร์ส่วนใหญ่รองรับทั้งตัวแปร GCM และ CBC ของชุดการเข้ารหัสเหล่านี้หรือไม่รองรับทั้ง 2 อย่าง

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

Android 10 มีการเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้ที่เกี่ยวข้องกับการใช้งานแอป

  • การปรับปรุงการใช้งานแอป UsageStats - Android 10 ติดตามการใช้งานแอปด้วย UsageStats ได้อย่างแม่นยำเมื่อใช้แอปในโหมดแยกหน้าจอหรือโหมดการแสดงภาพซ้อนภาพ นอกจากนี้ Android 10 ยังติดตามการใช้งาน Instant App ได้อย่างถูกต้องด้วย

  • โทนสีเทาต่อแอป - Android 10 สามารถตั้งค่าโหมดการแสดงผลโทนสีเทาต่อแอปได้

  • สถานะการรบกวนต่อแอป - Android 10 สามารถเลือกตั้งค่าแอปให้อยู่ใน "สถานะการรบกวน" ซึ่งจะระงับการแจ้งเตือนของแอปและไม่แสดงเป็นแอปที่แนะนำ

  • การระงับและการเล่น - ใน Android 10 แอปที่ถูกระงับจะเล่นเสียงไม่ได้

การเปลี่ยนแปลงการเชื่อมต่อ HTTPS

หากแอปที่ใช้ Android 10 ส่ง null ไปยัง setSSLSocketFactory() จะเกิด IllegalArgumentException ขึ้น ในเวอร์ชันก่อนหน้า การส่ง null ไปยัง setSSLSocketFactory() จะมีผลเหมือนกับการส่ง default factory ปัจจุบัน

เลิกใช้งานไลบรารี android.preference แล้ว

ไลบรารี android.preference เลิกใช้งานแล้วตั้งแต่ Android 10 นักพัฒนาแอปควรใช้ไลบรารีค่ากำหนด AndroidX ซึ่งเป็นส่วนหนึ่งของ Android Jetpack แทน หากต้องการแหล่งข้อมูลเพิ่มเติมเพื่อช่วยในการย้ายข้อมูลและการพัฒนา โปรดดูคู่มือการตั้งค่าที่อัปเดตแล้ว รวมถึงแอปตัวอย่างสาธารณะและเอกสารอ้างอิง

การเปลี่ยนแปลงไลบรารียูทิลิตีไฟล์ ZIP

Android 10 มีการเปลี่ยนแปลงต่อไปนี้ในคลาสในแพ็กเกจ java.util.zip ซึ่งจัดการไฟล์ ZIP การเปลี่ยนแปลงเหล่านี้ทำให้ลักษณะการทำงานของไลบรารีมีความสอดคล้องกันมากขึ้นระหว่าง Android และแพลตฟอร์มอื่นๆ ที่ใช้ java.util.zip

Inflater

ในเวอร์ชันก่อนหน้า เมธอดบางรายการในคลาส Inflater จะแสดง IllegalStateException หากมีการเรียกใช้หลังจากเรียก end() ใน Android 10 เมธอดเหล่านี้จะแสดง NullPointerException แทน

ZipFile

ใน Android 10 ขึ้นไป ตัวสร้างสำหรับ ZipFile ที่รับอาร์กิวเมนต์ประเภท File, int และ Charset จะไม่แสดง ZipException หากไฟล์ ZIP ที่ระบุไม่มีไฟล์ใดๆ

ZipOutputStream

ใน Android 10 ขึ้นไป เมธอด finish() ใน ZipOutputStream จะไม่แสดง ZipException หากพยายามเขียนสตรีมเอาต์พุตสำหรับไฟล์ ZIP ที่ไม่มีไฟล์ใดๆ

การเปลี่ยนแปลงกล้อง

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

แอปพลิเคชันที่กำหนดเป้าหมายเป็นระดับ API เป้าหมาย 24 ขึ้นไปควรตั้งค่า android:resizeableActivity อย่างชัดเจนและมีฟังก์ชันการทำงานที่จำเป็นเพื่อจัดการกับการทำงานแบบหลายหน้าต่าง

การติดตามการใช้งานแบตเตอรี่

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

ก่อน Android 10 สถิติการใช้งานแบตเตอรี่จะรีเซ็ตทุกครั้งที่ถอดปลั๊กอุปกรณ์ ไม่ว่าระดับแบตเตอรี่จะเปลี่ยนแปลงไปเพียงใดก็ตาม

การเลิกใช้งาน Android Beam

ใน Android 10 เราจะเลิกใช้งาน Android Beam อย่างเป็นทางการ ซึ่งเป็นฟีเจอร์เก่าสำหรับการเริ่มแชร์ข้อมูลในอุปกรณ์ต่างๆ ผ่าน Near Field Communication (NFC) นอกจากนี้ เรายังเลิกใช้งาน NFC API ที่เกี่ยวข้องหลายรายการด้วย Android Beam ยังคงเป็นตัวเลือกสำหรับพาร์ทเนอร์ผู้ผลิตอุปกรณ์ที่ต้องการใช้ แต่จะไม่มีการพัฒนาอีกต่อไป อย่างไรก็ตาม Android จะยังคงรองรับความสามารถและ API อื่นๆ ของ NFC ต่อไป และกรณีการใช้งานต่างๆ เช่น การอ่านจากแท็กและการชำระเงินจะยังคงทำงานตามที่คาดไว้

การเปลี่ยนแปลงลักษณะการทำงานของ java.math.BigDecimal.stripTrailingZeros()

BigDecimal.stripTrailingZeros() จะไม่เก็บเลขศูนย์ต่อท้ายเป็นกรณีพิเศษอีกต่อไปหากค่าอินพุตเป็นศูนย์

การเปลี่ยนแปลงลักษณะการทำงานของ java.util.regex.Matcher และ Pattern

ผลลัพธ์ของ split() มีการเปลี่ยนแปลงให้ไม่ขึ้นต้นด้วย String ("") ที่ว่างเปล่าอีกต่อไปเมื่อมีการจับคู่ความกว้างเป็น 0 ที่จุดเริ่มต้นของอินพุต ซึ่งจะส่งผลต่อ String.split() ด้วย ตัวอย่างเช่น ตอนนี้ "x".split("") จะแสดงผล {"x"} ในขณะที่ก่อนหน้านี้จะแสดงผล {"", "x"} ใน Android เวอร์ชันเก่า ตอนนี้ "aardvark".split("(?=a)" จะแสดงผล {"a", "ardv", "ark"} แทน {"", "a", "ardv", "ark"}

นอกจากนี้ เรายังปรับปรุงลักษณะการทำงานของข้อยกเว้นสำหรับอาร์กิวเมนต์ที่ไม่ถูกต้องด้วย ดังนี้

  • ตอนนี้ appendReplacement(StringBuffer, String) จะแสดง IllegalArgumentException แทน IndexOutOfBoundsException หาก String ที่ใช้แทนลงท้ายด้วยแบ็กสแลชเดี่ยวๆ ซึ่งไม่ถูกต้อง ตอนนี้ระบบจะแสดงข้อยกเว้นเดียวกันหาก String ที่ใช้แทนลงท้ายด้วย $ ก่อนหน้านี้ ระบบไม่ได้แสดงข้อยกเว้นในสถานการณ์นี้
  • replaceFirst(null) จะไม่เรียกใช้ reset() ใน Matcher อีกต่อไปหากแสดง NullPointerException ตอนนี้ระบบจะแสดง NullPointerException ด้วยเมื่อไม่มีรายการที่ตรงกัน ก่อนหน้านี้ ระบบจะแสดงข้อผิดพลาดนี้เฉพาะเมื่อมีการจับคู่เท่านั้น
  • start(int group), end(int group) และ group(int group) จะแสดง IndexOutOfBoundsException ทั่วไปมากขึ้นหากดัชนีกลุ่มอยู่นอกขอบเขต ก่อนหน้านี้ เมธอดเหล่านี้แสดง ArrayIndexOutOfBoundsException

มุมเริ่มต้นสำหรับ GradientDrawable คือ TOP_BOTTOM

ใน Android 10 หากคุณกำหนด GradientDrawable ใน XML และไม่ได้ระบุการวัดมุม การวางแนวการไล่ระดับสีจะใช้ค่าเริ่มต้นเป็น TOP_BOTTOM ซึ่งแตกต่างจาก Android เวอร์ชันก่อนหน้าที่มีค่าเริ่มต้นเป็น LEFT_RIGHT

วิธีแก้ปัญหาคือ หากคุณอัปเดตเป็น AAPT2 เวอร์ชันล่าสุด เครื่องมือจะตั้งค่าการวัดมุมเป็น 0 สำหรับแอปเดิมหากไม่ได้ระบุการวัดมุมไว้

การบันทึกสำหรับออบเจ็กต์ที่เรียงลำดับโดยใช้ SUID เริ่มต้น

ตั้งแต่ Android 7.0 (ระดับ API 24) เป็นต้นไป แพลตฟอร์มได้แก้ไข serialVersionUID เริ่มต้นสำหรับออบเจ็กต์ที่ทำให้เป็นอนุกรมได้ การแก้ไขนี้ไม่ส่งผลต่อแอปที่กำหนดเป้าหมายเป็น API ระดับ 23 หรือต่ำกว่า

ตั้งแต่ Android 10 เป็นต้นไป หากแอปกำหนดเป้าหมายเป็น API ระดับ 23 หรือต่ำกว่า และใช้ serialVersionUID เริ่มต้นที่ไม่ถูกต้องแบบเก่า ระบบจะบันทึกคำเตือนและแนะนำการแก้ไขโค้ด

โดยเฉพาะอย่างยิ่ง ระบบจะบันทึกคำเตือนหากเป็นไปตามเงื่อนไขต่อไปนี้ทั้งหมด

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

ระบบจะบันทึกคำเตือนนี้ 1 ครั้งสำหรับแต่ละคลาสที่ได้รับผลกระทบ ข้อความเตือนจะมีการแก้ไขที่แนะนำ ซึ่งก็คือการตั้งค่า serialVersionUID เป็นค่าเริ่มต้นอย่างชัดเจน ซึ่งจะคำนวณหากแอปกำหนดเป้าหมายเป็น API ระดับ 24 ขึ้นไป การใช้การแก้ไขดังกล่าวจะช่วยให้มั่นใจได้ว่าหากออบเจ็กต์จากคลาสนั้นได้รับการแปลงเป็นอนุกรมในแอปที่กำหนดเป้าหมายเป็น API ระดับ 23 หรือต่ำกว่า แอปที่กำหนดเป้าหมายเป็น API ระดับ 24 ขึ้นไปจะอ่านออบเจ็กต์ได้อย่างถูกต้อง และในทางกลับกัน

การเปลี่ยนแปลง java.io.FileChannel.map()

ตั้งแต่ Android 10 เป็นต้นไป ระบบจะไม่รองรับ FileChannel.map() สำหรับไฟล์ที่ไม่ได้มาตรฐาน เช่น /dev/zero ซึ่งไม่สามารถเปลี่ยนขนาดได้โดยใช้ truncate() Android เวอร์ชันก่อนหน้าจะกลืน errno ที่แสดงผลโดย truncate() แต่ Android 10 จะแสดง IOException หากต้องการลักษณะการทำงานแบบเดิม คุณต้องใช้โค้ดแบบเนทีฟ