ระดับ API: 19
Android 4.4 (KITKAT
) เป็นเวอร์ชันใหม่สำหรับแพลตฟอร์ม Android ที่มาพร้อมฟีเจอร์ใหม่ๆ สำหรับผู้ใช้และนักพัฒนาแอป เอกสารนี้จะแนะนำ API ใหม่ที่โดดเด่นที่สุด
ในฐานะนักพัฒนาแอป คุณควรดาวน์โหลดภาพระบบ Android 4.4 และแพลตฟอร์ม SDK จาก SDK Manager โดยเร็วที่สุด หากไม่มีอุปกรณ์ที่ใช้ Android 4.4 ในการทดสอบแอป ให้ใช้ภาพระบบ Android 4.4 เพื่อทดสอบแอปในโปรแกรมจำลอง Android จากนั้นสร้างแอปสำหรับแพลตฟอร์ม Android 4.4 เพื่อเริ่มใช้ API เวอร์ชันล่าสุด
อัปเดตระดับ API เป้าหมาย
หากต้องการเพิ่มประสิทธิภาพแอปสำหรับอุปกรณ์ที่ใช้ Android 4.4 ให้ดีขึ้น คุณควรตั้งค่า targetSdkVersion
เป็น "19"
ติดตั้งในภาพระบบ Android 4.4 ทดสอบ แล้วเผยแพร่การอัปเดตที่มีการเปลี่ยนแปลงนี้
คุณสามารถใช้ API ใน Android 4.4 ไปพร้อมกับรองรับเวอร์ชันเก่าได้ด้วยการเพิ่มเงื่อนไขลงในโค้ดที่ตรวจสอบระดับ API ของระบบก่อนที่จะเรียกใช้ API ที่ minSdkVersion
ไม่รองรับ
ดูข้อมูลเพิ่มเติมเกี่ยวกับการคงความเข้ากันได้ย้อนหลังได้ที่การรองรับเวอร์ชันแพลตฟอร์มที่แตกต่างกัน
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของระดับ API ได้ที่ระดับ API คืออะไร
การเปลี่ยนแปลงที่สำคัญเกี่ยวกับลักษณะการทำงาน
หากคุณเคยเผยแพร่แอปสำหรับ Android โปรดทราบว่าแอปอาจได้รับผลกระทบจากการเปลี่ยนแปลงใน Android 4.4
หากแอปอ่านจากที่จัดเก็บข้อมูลภายนอก...
แอปของคุณจะอ่านไฟล์ที่แชร์ในที่จัดเก็บข้อมูลภายนอกไม่ได้เมื่อทำงานบน Android 4.4 เว้นแต่ว่าแอปจะมีสิทธิ์ READ_EXTERNAL_STORAGE
กล่าวคือ ไฟล์ภายในไดเรกทอรีที่ getExternalStoragePublicDirectory()
แสดงผลจะเข้าถึงไม่ได้อีกต่อไปหากไม่มีสิทธิ์ อย่างไรก็ตาม หากต้องการเข้าถึงเฉพาะไดเรกทอรีเฉพาะแอปที่ getExternalFilesDir()
ระบุไว้ คุณไม่จำเป็นต้องมีสิทธิ์ READ_EXTERNAL_STORAGE
หากแอปใช้ WebView
แอปอาจทำงานแตกต่างจากปกติเมื่อทำงานบน Android 4.4 โดยเฉพาะอย่างยิ่งเมื่อคุณอัปเดต targetSdkVersion
ของแอปเป็น "19" ขึ้นไป
โค้ดที่อยู่เบื้องหลังคลาส WebView
และ API ที่เกี่ยวข้องได้รับการอัปเกรดให้อิงตามสแนปชอตล่าสุดของซอร์สโค้ด Chromium ซึ่งจะนำมาซึ่งการปรับปรุงประสิทธิภาพที่หลากหลาย รองรับฟีเจอร์ HTML5 ใหม่ และรองรับการแก้ไขข้อบกพร่องจากระยะไกลของเนื้อหา WebView
ขอบเขตของการอัปเกรดนี้หมายความว่าหากแอปของคุณใช้ WebView
ลักษณะการทํางานของแอปอาจได้รับผลกระทบในบางกรณี แม้ว่าจะมีบันทึกการเปลี่ยนแปลงลักษณะการทำงานที่ทราบและส่วนใหญ่จะส่งผลต่อแอปของคุณก็ต่อเมื่อคุณอัปเดต targetSdkVersion
ของแอปเป็น "19" ขึ้นไป แต่ WebView
เวอร์ชันใหม่จะทำงานใน "โหมดการทำงานพิเศษ" เพื่อมอบฟังก์ชันการทำงานเดิมบางส่วนในแอปที่กำหนดเป้าหมายเป็น API ระดับ 18 และต่ำกว่า เป็นไปได้ว่าแอปของคุณอาจใช้ลักษณะการทำงานที่ไม่รู้จักจาก WebView
เวอร์ชันก่อนหน้า
ดังนั้นหากแอปที่มีอยู่ใช้ WebView
คุณควรทดสอบบน Android 4.4 โดยเร็วที่สุดและดูข้อมูลเกี่ยวกับผลกระทบที่อาจเกิดขึ้นกับแอปเมื่อคุณอัปเดต targetSdkVersion
เป็น "19" ขึ้นไปในการย้ายข้อมูลไปยัง WebView ใน Android 4.4
หากแอปใช้ AlarmManager
เมื่อคุณตั้งค่า targetSdkVersion
ของแอปเป็น "19" ขึ้นไป การปลุกที่คุณสร้างโดยใช้ set()
หรือ setRepeating()
จะมีความคลาดเคลื่อน
ตอนนี้ Android จะรวมการปลุกจากแอปทั้งหมดที่เกิดขึ้นในช่วงเวลาใกล้เคียงกันไว้ในกลุ่มเดียวกันเพื่อปรับปรุงประสิทธิภาพการใช้พลังงาน ระบบจึงจะปลุกอุปกรณ์เพียงครั้งเดียวแทนที่จะปลุกหลายครั้งเพื่อจัดการการปลุกแต่ละรายการ
หากการปลุกไม่ได้เชื่อมโยงกับเวลาของนาฬิกาที่แน่นอน แต่ยังคงต้องการให้ระบบเรียกใช้การปลุกในช่วงที่เจาะจง (เช่น ระหว่างเวลา 14:00 น. - 16:00 น.) คุณก็ใช้เมธอด setWindow()
ใหม่ได้ ซึ่งจะยอมรับเวลา "เร็วที่สุด" สำหรับการปลุกและ "กรอบเวลา" หลังจากเวลาเร็วที่สุดที่ระบบควรเรียกใช้การปลุก
หากการปลุกต้องปักหมุดไว้กับเวลาของนาฬิกาที่แน่นอน (เช่น สำหรับการช่วยเตือนกิจกรรมในปฏิทิน) คุณจะใช้เมธอด setExact()
ใหม่ได้
ลักษณะการรวมกลุ่มที่ไม่แน่นอนนี้มีผลกับแอปที่อัปเดตแล้วเท่านั้น หากคุณตั้งค่า targetSdkVersion
เป็น "18" หรือต่ำกว่า ระบบจะยังคงตั้งปลุกตามลักษณะการทำงานในเวอร์ชันก่อนหน้าเมื่อใช้ Android 4.4
หากแอปซิงค์ข้อมูลโดยใช้ ContentResolver
เมื่อคุณตั้งค่า targetSdkVersion
ของแอปเป็น "19" ขึ้นไป การสร้างการซิงค์ด้วย addPeriodicSync()
จะดำเนินการซิงค์ภายในช่วงเวลาแบบยืดหยุ่นเริ่มต้นประมาณ 4% ของระยะเวลาที่คุณระบุ ตัวอย่างเช่น หากความถี่ในการสำรวจคือ 24 ชั่วโมง การดำเนินการซิงค์อาจเกิดขึ้นภายในกรอบเวลาประมาณ 1 ชั่วโมงในแต่ละวันแทนที่จะดำเนินการในเวลาเดียวกันทุกวัน
หากต้องการระบุช่วงเวลาที่ยืดหยุ่นของคุณเองสําหรับการดำเนินการซิงค์ คุณควรเริ่มใช้เมธอด requestSync()
ใหม่ โปรดดูรายละเอียดเพิ่มเติมในส่วนด้านล่างเกี่ยวกับอะแดปเตอร์การซิงค์
ลักษณะการทำงานของช่วงเวลาแบบยืดหยุ่นนี้มีผลกับแอปที่อัปเดตแล้วเท่านั้น หากคุณตั้งค่า targetSdkVersion
เป็น "18" หรือต่ำกว่า คำขอซิงค์ที่มีอยู่จะยังคงทำงานเหมือนเดิมในเวอร์ชันก่อนหน้าเมื่อใช้ Android 4.4
เฟรมเวิร์กการพิมพ์
ตอนนี้ Android มีเฟรมเวิร์กครบถ้วนที่ช่วยให้ผู้ใช้พิมพ์เอกสารใดก็ได้โดยใช้เครื่องพิมพ์ที่เชื่อมต่อผ่าน Wi-Fi, บลูทูธ หรือบริการอื่นๆ ระบบจะจัดการธุรกรรมระหว่างแอปที่ต้องการพิมพ์เอกสารกับบริการที่ส่งงานพิมพ์ไปยังเครื่องพิมพ์ เฟรมเวิร์ก android.print
มี API ทั้งหมดที่จำเป็นในการระบุเอกสารที่จะพิมพ์และส่งไปยังระบบเพื่อพิมพ์ API ที่คุณต้องใช้จริงสำหรับงานพิมพ์หนึ่งๆ จะขึ้นอยู่กับเนื้อหาของคุณ
การพิมพ์เนื้อหาทั่วไป
หากต้องการพิมพ์เนื้อหาจาก UI เป็นเอกสาร คุณจะต้องสร้างคลาสย่อยของ PrintDocumentAdapter
ก่อน ในคลาสนี้ คุณต้องติดตั้งใช้งานเมธอดการเรียกกลับ 2-3 เมธอด ซึ่งรวมถึง onLayout()
เพื่อกำหนดเลย์เอาต์ตามพร็อพเพอร์ตี้การพิมพ์ที่ระบุ และ onWrite()
เพื่อจัดรูปแบบเนื้อหาที่พิมพ์ได้ให้เป็น ParcelFileDescriptor
หากต้องการเขียนเนื้อหาลงใน ParcelFileDescriptor
คุณต้องส่งไฟล์ PDF PdfDocument
API ใหม่นำเสนอวิธีที่สะดวกในการทำเช่นนี้โดยระบุ Canvas
จาก getCanvas()
ซึ่งคุณสามารถวาดเนื้อหาที่พิมพ์ได้ จากนั้นเขียน PdfDocument
ไปยัง ParcelFileDescriptor
โดยใช้วิธีการ writeTo()
เมื่อกำหนดการใช้งานสำหรับ PrintDocumentAdapter
แล้ว คุณจะดำเนินการพิมพ์ตามคำขอของผู้ใช้ได้โดยใช้เมธอด PrintManager
print()
ซึ่งใช้ PrintDocumentAdapter
เป็นอาร์กิวเมนต์รายการใดรายการหนึ่ง
การพิมพ์รูปภาพ
หากต้องการพิมพ์เฉพาะรูปภาพหรือบิตแมปอื่นๆ API ตัวช่วยในไลบรารีสนับสนุนจะทํางานทั้งหมดให้คุณ เพียงสร้างอินสแตนซ์ใหม่ของ PrintHelper
ตั้งค่าโหมดการปรับขนาดด้วย setScaleMode()
แล้วส่ง Bitmap
ไปยัง printBitmap()
เท่านี้เอง ไลบรารีจะจัดการการโต้ตอบที่เหลือทั้งหมดกับระบบเพื่อส่งบิตแมปไปยังเครื่องพิมพ์
บริการพิมพ์สำหรับอาคาร
ในฐานะ OEM ของเครื่องพิมพ์ คุณสามารถใช้เฟรมเวิร์ก android.printservice
เพื่อมอบความสามารถในการทำงานร่วมกันกับเครื่องพิมพ์จากอุปกรณ์ Android คุณสามารถสร้างและเผยแพร่บริการพิมพ์เป็น APK ซึ่งผู้ใช้จะติดตั้งลงในอุปกรณ์ได้ แอปบริการพิมพ์จะทํางานเป็นหลักในฐานะบริการแบบไม่มีส่วนหัวโดยการแยกคลาสย่อยของคลาส PrintService
ซึ่งจะรับงานพิมพ์จากระบบและสื่อสารงานกับเครื่องพิมพ์โดยใช้โปรโตคอลที่เหมาะสม
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีพิมพ์เนื้อหาแอปได้ที่การพิมพ์เนื้อหา
ผู้ให้บริการ SMS
ผู้ให้บริการเนื้อหา Telephony
("ผู้ให้บริการ SMS") อนุญาตให้แอปอ่านและเขียนข้อความ SMS และ MMS ในอุปกรณ์ ซึ่งรวมถึงตารางสำหรับข้อความ SMS และ MMS ที่ได้รับ ร่าง ส่ง รอดำเนินการ และอื่นๆ
ตั้งแต่ Android 4.4 การตั้งค่าระบบอนุญาตให้ผู้ใช้เลือก "แอปรับส่ง SMS เริ่มต้น" เมื่อเลือกแล้ว จะมีเพียงแอป SMS เริ่มต้นเท่านั้นที่เขียนไปยังผู้ให้บริการ SMS และจะมีเพียงแอป SMS เริ่มต้นเท่านั้นที่รับการออกอากาศ SMS_DELIVER_ACTION
เมื่อผู้ใช้ได้รับ SMS หรือรับการออกอากาศ WAP_PUSH_DELIVER_ACTION
เมื่อผู้ใช้ได้รับ MMS แอป SMS เริ่มต้นมีหน้าที่เขียนรายละเอียดไปยังผู้ให้บริการ SMS เมื่อได้รับหรือส่งข้อความใหม่
แอปอื่นๆ ที่ไม่ได้เลือกเป็นแอป SMS เริ่มต้นจะอ่านได้เฉพาะผู้ให้บริการ SMS แต่อาจได้รับการแจ้งเตือนเมื่อ SMS ใหม่มาถึงด้วยการฟังการออกอากาศ SMS_RECEIVED_ACTION
ซึ่งเป็นการออกอากาศที่หยุดกลางคันไม่ได้ซึ่งอาจส่งไปยังแอปหลายแอป การออกอากาศนี้มีไว้สำหรับแอปที่แม้จะไม่ได้เลือกเป็นแอป SMS เริ่มต้น แต่จำเป็นต้องอ่านข้อความขาเข้าพิเศษ เช่น เพื่อดำเนินการยืนยันหมายเลขโทรศัพท์
อ่านข้อมูลเพิ่มเติมได้ในบล็อกโพสต์การเตรียมแอป SMS ให้พร้อมใช้งานกับ KitKat
การเชื่อมต่อไร้สาย
การจําลองบัตรของโฮสต์
ตอนนี้แอป Android สามารถจําลองการ์ด NFC ISO14443-4 (ISO-DEP) ที่ใช้ APDU เพื่อแลกเปลี่ยนข้อมูลได้แล้ว (ตามที่ระบุไว้ใน ISO7816-4) ซึ่งจะช่วยให้อุปกรณ์ที่เปิดใช้ NFC ที่ใช้ Android 4.4 สามารถจําลองบัตร NFC หลายใบพร้อมกัน และช่วยให้เครื่องชำระเงิน NFC หรือเครื่องอ่าน NFC อื่นๆ เริ่มธุรกรรมด้วยบัตร NFC ที่เหมาะสมตามตัวระบุแอปพลิเคชัน (AID) ได้
หากต้องการจําลองการ์ด NFC ที่ใช้โปรโตคอลเหล่านี้ในแอป ให้สร้างคอมโพเนนต์บริการตามคลาส HostApduService
แต่หากแอปใช้องค์ประกอบที่ปลอดภัยสำหรับการจําลองบัตรแทน คุณจะต้องสร้างบริการตามคลาส OffHostApduService
ซึ่งจะไม่เกี่ยวข้องกับธุรกรรมโดยตรง แต่จําเป็นต้องลงทะเบียน AID ที่ควรจัดการโดยองค์ประกอบที่ปลอดภัย
อ่านข้อมูลเพิ่มเติมได้ที่คู่มือการจําลองบัตร NFC
โหมดเครื่องอ่าน NFC
โหมดเครื่องอ่าน NFC ใหม่ช่วยให้กิจกรรมจำกัดกิจกรรม NFC ทั้งหมดให้อ่านเฉพาะประเภทแท็กที่กิจกรรมสนใจขณะที่ทำงานอยู่เบื้องหน้า คุณสามารถเปิดใช้โหมดผู้อ่านสําหรับกิจกรรมด้วย enableReaderMode()
โดยระบุการใช้งาน NfcAdapter.ReaderCallback
ที่จะได้รับการเรียกกลับเมื่อตรวจพบแท็กใหม่
ความสามารถใหม่นี้เมื่อใช้ร่วมกับการจําลองบัตรโฮสต์จะช่วยให้ Android ทํางานได้ทั้งสองฝั่งของอินเทอร์เฟซการชําระเงินผ่านอุปกรณ์เคลื่อนที่ โดยอุปกรณ์หนึ่งทํางานเป็นเครื่องชำระเงิน (อุปกรณ์ที่ทํางานในโหมดเครื่องอ่าน) และอีกอุปกรณ์หนึ่งทํางานเป็นไคลเอ็นต์การชําระเงิน (อุปกรณ์ที่จําลองบัตร NFC)
เครื่องส่งสัญญาณอินฟราเรด
เมื่อใช้งานในอุปกรณ์ที่มีเครื่องส่งสัญญาณอินฟราเรด (IR) ตอนนี้คุณสามารถส่งสัญญาณ IR โดยใช้ ConsumerIrManager
API หากต้องการรับอินสแตนซ์ของ ConsumerIrManager
ให้เรียกใช้ getSystemService()
โดยมี CONSUMER_IR_SERVICE
เป็นอาร์กิวเมนต์ จากนั้นคุณสามารถค้นหาความถี่ IR ที่อุปกรณ์รองรับด้วย getCarrierFrequencies()
และส่งสัญญาณโดยส่งความถี่และรูปแบบสัญญาณที่ต้องการด้วย transmit()
คุณควรตรวจสอบก่อนเสมอว่าอุปกรณ์มีเครื่องส่ง IR หรือไม่โดยเรียกใช้ hasIrEmitter()
แต่หากแอปของคุณเข้ากันได้เฉพาะกับอุปกรณ์ที่มีเครื่องส่ง IR คุณควรใส่องค์ประกอบ <uses-feature>
ในไฟล์ Manifest สำหรับ "android.hardware.consumerir"
(FEATURE_CONSUMER_IR
)
มัลติมีเดีย
การเล่นแบบปรับอัตโนมัติ
ตอนนี้ MediaCodec
API พร้อมรองรับการเล่นวิดีโอแบบปรับเปลี่ยนได้ ซึ่งช่วยให้เปลี่ยนความละเอียดได้อย่างราบรื่นระหว่างการเล่นบน Surface
โดยคุณสามารถป้อนเฟรมอินพุตของโปรแกรมถอดรหัสที่มีความละเอียดใหม่ และความละเอียดของบัฟเฟอร์เอาต์พุตจะเปลี่ยนไปโดยแทบไม่ขาดตอน
คุณเปิดใช้การเล่นแบบปรับเปลี่ยนได้โดยการเพิ่มคีย์ 2 รายการลงใน MediaFormat
ซึ่งระบุความละเอียดสูงสุดที่แอปของคุณต้องการจากตัวแปลงรหัส ได้แก่ KEY_MAX_WIDTH
และ KEY_MAX_HEIGHT
เมื่อเพิ่มรายการเหล่านี้ลงใน MediaFormat
แล้ว ให้ส่ง MediaFormat
ไปยังอินสแตนซ์ MediaCodec
ด้วย configure()
โปรแกรมเปลี่ยนรหัสจะเปลี่ยนความละเอียดระหว่างความละเอียดที่เท่ากับหรือน้อยกว่าค่าเหล่านี้อย่างราบรื่น นอกจากนี้ โปรแกรมเปลี่ยนไฟล์ยังอาจรองรับความละเอียดที่มากกว่าความละเอียดสูงสุดที่ระบุ (ตราบใดที่ความละเอียดนั้นไม่เกินขีดจำกัดของโปรไฟล์ที่รองรับ) แต่การเปลี่ยนไปใช้ความละเอียดที่สูงขึ้นอาจไม่ราบรื่น
หากต้องการเปลี่ยนความละเอียดขณะถอดรหัสวิดีโอ H.264 ให้จัดคิวเฟรมต่อไปโดยใช้ MediaCodec.queueInputBuffer() แต่ตรวจสอบว่าคุณได้ระบุค่าชุดพารามิเตอร์ลำดับ (SPS) และชุดพารามิเตอร์รูปภาพ (PPS) ใหม่พร้อมกับเฟรมการรีเฟรชตัวถอดรหัสทันที (IDR) ในบัฟเฟอร์เดียว
อย่างไรก็ตาม ก่อนที่จะพยายามกำหนดค่าตัวแปลงรหัสสำหรับการเล่นแบบปรับเปลี่ยนได้ คุณต้องยืนยันว่าอุปกรณ์รองรับการเล่นแบบปรับเปลี่ยนได้โดยการเรียกใช้ isFeatureSupported(String)
ด้วย FEATURE_AdaptivePlayback
หมายเหตุ: การรองรับการเล่นแบบปรับเปลี่ยนจะแตกต่างกันไปตามผู้ให้บริการ โปรแกรมเปลี่ยนไฟล์บางประเภทอาจต้องใช้หน่วยความจำมากขึ้นสำหรับคำแนะนำความละเอียดที่สูงขึ้น ดังนั้น คุณควรตั้งค่าความละเอียดสูงสุดตามเนื้อหาต้นทางที่คุณกำลังถอดรหัส
การประทับเวลาของเสียงแบบออนดีมานด์
คลาส AudioTimestamp
ใหม่จะแสดงรายละเอียดไทม์ไลน์เกี่ยวกับ "เฟรม" ที่เฉพาะเจาะจงในสตรีมเสียงที่ AudioTrack
จัดการ เพื่อให้ซิงค์เสียงและวิดีโอได้ง่ายขึ้น หากต้องการรับการประทับเวลาล่าสุดที่มีอยู่ ให้สร้างอินสแตนซ์ออบเจ็กต์ AudioTimestamp
แล้วส่งไปยัง getTimestamp()
หากคําขอการประทับเวลาสําเร็จ ระบบจะกรอกอินสแตนซ์ AudioTrack
ด้วยตําแหน่งในหน่วยเฟรม พร้อมกับเวลาโดยประมาณที่เฟรมนั้นแสดงหรือจะแสดง
คุณสามารถใช้ค่าของ nanoTime
ใน AudioTimestamp
(ซึ่งเป็นค่าที่เพิ่มขึ้นเรื่อยๆ) เพื่อค้นหาเฟรมวิดีโอที่เกี่ยวข้องซึ่งใกล้เคียงที่สุดเมื่อเทียบกับ framePosition
เพื่อให้คุณวาง คัดลอก หรือหาค่าเฉลี่ยระหว่างเฟรมวิดีโอเพื่อจับคู่กับเสียงได้ หรือจะกำหนดเวลาเดลต้าระหว่างค่า nanoTime
กับเวลาที่คาดไว้ของเฟรมวิดีโอในอนาคต (โดยพิจารณาจากอัตราตัวอย่าง) เพื่อคาดการณ์เฟรมเสียงที่คาดว่าจะเล่นพร้อมกันกับเฟรมวิดีโอก็ได้
เครื่องอ่านรูปภาพบนพื้นผิว
ImageReader
API ใหม่ช่วยให้คุณเข้าถึงบัฟเฟอร์รูปภาพได้โดยตรงเมื่อมีการเรนเดอร์เป็น Surface
คุณรับ ImageReader
ได้ด้วยเมธอดแบบคงที่ newInstance()
จากนั้นเรียกใช้ getSurface()
เพื่อสร้าง Surface
ใหม่และส่งข้อมูลรูปภาพด้วยโปรแกรมสร้าง เช่น MediaPlayer
หรือ MediaCodec
หากต้องการรับการแจ้งเตือนเมื่อมีรูปภาพใหม่จากแพลตฟอร์ม ให้ใช้อินเทอร์เฟซ ImageReader.OnImageAvailableListener
และลงทะเบียนกับ setOnImageAvailableListener()
เมื่อคุณวาดเนื้อหาลงใน Surface
ขณะนี้ ImageReader.OnImageAvailableListener
จะได้รับคอลไปยัง onImageAvailable()
เมื่อเฟรมรูปภาพใหม่แต่ละเฟรมพร้อมใช้งาน ซึ่งจะแสดง ImageReader
ที่เกี่ยวข้อง คุณสามารถใช้ ImageReader
เพื่อรับข้อมูลรูปภาพของเฟรมเป็นออบเจ็กต์ Image
ได้โดยเรียกใช้ acquireLatestImage()
หรือ acquireNextImage()
ออบเจ็กต์ Image
ให้สิทธิ์เข้าถึงการประทับเวลา รูปแบบ ขนาด และข้อมูลพิกเซลของรูปภาพโดยตรงใน ByteBuffer
อย่างไรก็ตาม รูปภาพต้องอยู่ในรูปแบบตามประเภทใดประเภทหนึ่งที่กำหนดโดยค่าคงที่ใน ImageFormat
หรือ PixelFormat
เพื่อให้คลาส Image
ตีความรูปภาพได้
การวัดค่าสูงสุดและ RMS
ตอนนี้คุณสามารถค้นหาค่าสูงสุดและ RMS ของสตรีมเสียงปัจจุบันจาก Visualizer
ได้โดยการสร้างอินสแตนซ์ใหม่ของ Visualizer.MeasurementPeakRms
และส่งไปยัง getMeasurementPeakRms()
เมื่อคุณเรียกใช้เมธอดนี้ ระบบจะตั้งค่าค่าสูงสุดและ RMS ของ Visualizer.MeasurementPeakRms
ที่ระบุเป็นค่าที่วัดล่าสุด
ตัวเพิ่มระดับเสียง
LoudnessEnhancer
เป็นคลาสย่อยใหม่ของ AudioEffect
ที่ช่วยให้คุณเพิ่มระดับเสียงที่ได้ยินของ MediaPlayer
หรือ AudioTrack
ได้ ซึ่งจะมีประโยชน์อย่างยิ่งเมื่อใช้ร่วมกับวิธีการ getMeasurementPeakRms()
ใหม่ที่เราได้พูดถึงข้างต้น เพื่อเพิ่มระดับเสียงของแทร็กเสียงที่พูดขณะที่สื่ออื่นๆ กำลังเล่นอยู่
ตัวควบคุมระยะไกล
Android 4.0 (API ระดับ 14) ได้เปิดตัว RemoteControlClient
API ที่ช่วยให้แอปสื่อใช้เหตุการณ์ตัวควบคุมสื่อจากไคลเอ็นต์ระยะไกลได้ เช่น การควบคุมสื่อบนหน้าจอล็อก ตอนนี้ RemoteController
API ใหม่ช่วยให้คุณสร้างรีโมตคอนโทรลของคุณเองได้ ซึ่งจะเปิดโอกาสให้สร้างแอปและอุปกรณ์ต่อพ่วงใหม่ๆ ที่ล้ำสมัยซึ่งควบคุมการเล่นของแอปสื่อที่ผสานรวมกับ RemoteControlClient
ได้
หากต้องการสร้างรีโมตคอนโทรลเลอร์ คุณสามารถใช้อินเทอร์เฟซผู้ใช้ในลักษณะใดก็ได้ที่ต้องการ แต่หากต้องการส่งเหตุการณ์ของปุ่มสื่อไปยังแอปสื่อของผู้ใช้ คุณต้องสร้างบริการที่ขยายคลาส NotificationListenerService
และใช้อินเทอร์เฟซ RemoteController.OnClientUpdateListener
การใช้ NotificationListenerService
เป็นพื้นฐานเป็นสิ่งสําคัญเนื่องจากมีข้อจํากัดด้านความเป็นส่วนตัวที่เหมาะสม ซึ่งกําหนดให้ผู้ใช้ต้องเปิดใช้แอปของคุณเป็นผู้ฟังการแจ้งเตือนในการตั้งค่าความปลอดภัยของระบบ
คลาส NotificationListenerService
มีเมธอดนามธรรม 2 รายการที่คุณต้องติดตั้งใช้งาน แต่หากคุณสนใจเฉพาะเหตุการณ์ตัวควบคุมสื่อเพื่อจัดการการเล่นสื่อ ก็ปล่อยการติดตั้งใช้งานสำหรับเหตุการณ์เหล่านั้นว่างไว้ แล้วมุ่งเน้นที่เมธอด RemoteController.OnClientUpdateListener
แทน
การให้คะแนนจากรีโมตคอนโทรล
Android 4.4 พัฒนาความสามารถที่มีอยู่สำหรับไคลเอ็นต์รีโมตคอนโทรล (แอปที่รับเหตุการณ์การควบคุมสื่อด้วย RemoteControlClient
) โดยเพิ่มความสามารถในการให้คะแนนแทร็กปัจจุบันจากรีโมตคอนโทรล
คลาส Rating
ใหม่จะรวมข้อมูลเกี่ยวกับคะแนนของผู้ใช้ การจัดประเภทจะกำหนดโดยรูปแบบการจัดประเภท (RATING_HEART
, RATING_THUMB_UP_DOWN
, RATING_3_STARS
, RATING_4_STARS
, RATING_5_STARS
หรือ RATING_PERCENTAGE
) และค่าการจัดประเภทที่เหมาะสมกับรูปแบบนั้น
วิธีอนุญาตให้ผู้ใช้ให้คะแนนแทร็กจากรีโมตคอนโทรล
- ระบุว่าคุณต้องการให้ UI การให้คะแนนแสดงต่อผู้ใช้ (หากมี) โดยเพิ่ม Flag
FLAG_KEY_MEDIA_RATING
ในsetTransportControlFlags()
- โทรหา
editMetadata()
เพื่อดึงข้อมูลRemoteControlClient.MetadataEditor
และส่งให้RATING_KEY_BY_USER
ด้วยaddEditableKey()
- จากนั้นระบุสไตล์การให้คะแนนโดยเรียกใช้
putObject()
และส่งRATING_KEY_BY_USER
เป็นคีย์และสไตล์การให้คะแนนรูปแบบใดรูปแบบหนึ่งข้างต้นเป็นค่า
หากต้องการรับการเรียกกลับเมื่อผู้ใช้เปลี่ยนการจัดประเภทจากรีโมตคอนโทรล ให้ใช้อินเทอร์เฟซ RemoteControlClient.OnMetadataUpdateListener
ใหม่และส่งอินสแตนซ์ไปยัง setMetadataUpdateListener()
เมื่อผู้ใช้เปลี่ยนการจัดประเภท RemoteControlClient.OnMetadataUpdateListener
ของคุณจะได้รับคําเรียก onMetadataUpdate()
โดยส่ง RATING_KEY_BY_USER
เป็นคีย์และออบเจ็กต์ Rating
เป็นค่า
คำบรรยาย
VideoView
รองรับแทร็กคำบรรยาย WebVTT เมื่อเล่นวิดีโอ HTTP Live Stream (HLS) แล้ว โดยจะแสดงแทร็กคำบรรยายตามค่ากำหนดคำบรรยายแทนเสียงที่ผู้ใช้กำหนดไว้ในการตั้งค่าระบบ
นอกจากนี้ คุณยังระบุแทร็กคำบรรยาย WebVTT ให้กับ VideoView
โดยใช้เมธอด addSubtitleSource()
ได้ด้วย เมธอดนี้จะยอมรับ InputStream
ที่มีข้อมูลคำบรรยายและออบเจ็กต์ MediaFormat
ที่ระบุรูปแบบสำหรับข้อมูลคำบรรยาย ซึ่งคุณระบุได้โดยใช้ createSubtitleFormat()
คำบรรยายเหล่านี้จะปรากฏเหนือวิดีโอตามค่ากำหนดของผู้ใช้ด้วย
หากคุณไม่ได้ใช้ VideoView
เพื่อแสดงเนื้อหาวิดีโอ คุณควรทำให้คำบรรยายแทนเสียงที่วางซ้อนตรงกับค่ากำหนดคำบรรยายแทนเสียงของผู้ใช้มากที่สุด CaptioningManager
API ใหม่ช่วยให้คุณค้นหาค่ากำหนดคำบรรยายแทนเสียงของผู้ใช้ รวมถึงรูปแบบที่ CaptioningManager.CaptionStyle
กำหนด เช่น แบบตัวพิมพ์และสี ในกรณีที่ผู้ใช้ปรับค่ากําหนดบางอย่างเมื่อวิดีโอเล่นไปแล้ว คุณควรรอฟังการเปลี่ยนแปลงค่ากําหนดโดยการลงทะเบียนอินสแตนซ์ของ CaptioningManager.CaptioningChangeListener
เพื่อรับการเรียกกลับเมื่อมีการเปลี่ยนแปลงค่ากําหนด จากนั้นอัปเดตคำบรรยายตามที่จำเป็น
ภาพเคลื่อนไหวและกราฟิก
ฉากและทรานซิชัน
เฟรมเวิร์ก android.transition
ใหม่มี API ที่อำนวยความสะดวกในการสร้างภาพเคลื่อนไหวระหว่างสถานะต่างๆ ของอินเทอร์เฟซผู้ใช้ ฟีเจอร์หลักคือความสามารถในการกำหนดสถานะที่แตกต่างกันของ UI หรือที่เรียกว่า "ฉาก" โดยการสร้างเลย์เอาต์แยกกันสำหรับแต่ละสถานะ เมื่อต้องการแสดงภาพเคลื่อนไหวจากฉากหนึ่งไปยังอีกฉากหนึ่ง ให้ใช้ "ทรานซิชัน" ซึ่งจะคำนวณภาพเคลื่อนไหวที่จำเป็นเพื่อเปลี่ยนเลย์เอาต์จากฉากปัจจุบันไปยังฉากถัดไป
โดยทั่วไปแล้ว หากต้องการเปลี่ยนระหว่าง 2 ฉาก คุณจะต้องดำเนินการต่อไปนี้
- ระบุ
ViewGroup
ที่มีคอมโพเนนต์ UI ที่ต้องการเปลี่ยน - ระบุเลย์เอาต์ที่แสดงผลลัพธ์สุดท้ายของการเปลี่ยนแปลง (ฉากถัดไป)
- ระบุประเภทการเปลี่ยนที่ควรแสดงภาพเคลื่อนไหวการเปลี่ยนแปลงเลย์เอาต์
- ดำเนินการเปลี่ยน
คุณใช้ออบเจ็กต์ Scene
เพื่อทําขั้นตอนที่ 1 และ 2 ได้ Scene
มีข้อมูลเมตาที่อธิบายพร็อพเพอร์ตี้ของเลย์เอาต์ที่จําเป็นสําหรับการเปลี่ยนฉาก ซึ่งรวมถึงมุมมองหลักของฉากและเลย์เอาต์ของฉาก คุณสามารถสร้าง Scene
โดยใช้ตัวสร้างคลาสหรือเมธอดแบบคงที่ getSceneForLayout()
จากนั้นให้ใช้ TransitionManager
เพื่อทําขั้นตอนที่ 3 และ 4 วิธีหนึ่งคือส่ง Scene
ไปยังเมธอดแบบคงที่ go()
ซึ่งจะค้นหามุมมองหลักของฉากในเลย์เอาต์ปัจจุบันและทำการทรานซิชันในมุมมองย่อยเพื่อไปยังเลย์เอาต์ที่ Scene
กำหนด
หรือคุณจะไม่ต้องสร้างออบเจ็กต์ Scene
เลยก็ได้ แต่เรียกใช้ beginDelayedTransition()
แทน โดยระบุ ViewGroup
ที่มีมุมมองที่ต้องการเปลี่ยน จากนั้นเพิ่ม นําออก หรือกําหนดค่ามุมมองเป้าหมายใหม่ หลังจากระบบแสดงการเปลี่ยนแปลงตามที่จำเป็นแล้ว ทรานซิชันจะเริ่มแสดงภาพเคลื่อนไหวของมุมมองทั้งหมดที่ได้รับผลกระทบ
หากต้องการการควบคุมเพิ่มเติม คุณสามารถกำหนดชุดทรานซิชันที่ควรเกิดขึ้นระหว่างฉากที่กําหนดไว้ล่วงหน้าได้โดยใช้ไฟล์ XML ในไดเรกทอรี res/transition/
ของโปรเจ็กต์ ภายในองค์ประกอบ <transitionManager>
ให้ระบุแท็ก <transition>
อย่างน้อย 1 รายการที่ระบุฉาก (การอ้างอิงไฟล์เลย์เอาต์) และทรานซิชันที่จะใช้เมื่อเข้าสู่และ/หรือออกจากฉากนั้น จากนั้นขยายชุดทรานซิชันนี้โดยใช้ inflateTransitionManager()
ใช้ TransitionManager
ที่แสดงผลเพื่อเรียกใช้การเปลี่ยนแต่ละรายการด้วย transitionTo()
โดยส่ง Scene
ที่แสดงโดยแท็ก <transition>
รายการใดรายการหนึ่ง นอกจากนี้ คุณยังกำหนดชุดทรานซิชันแบบเป็นโปรแกรมด้วย TransitionManager
API ได้ด้วย
เมื่อระบุทรานซิชัน คุณจะใช้ประเภทที่กําหนดไว้ล่วงหน้าหลายประเภทซึ่งกําหนดโดยคลาสย่อยของ Transition
ได้ เช่น Fade
และ ChangeBounds
หากคุณไม่ระบุประเภททรานซิชัน ระบบจะใช้ AutoTransition
โดยค่าเริ่มต้น ซึ่งจะค่อยๆ จาง ย้าย และปรับขนาดมุมมองโดยอัตโนมัติตามความจำเป็น นอกจากนี้ คุณยังสร้างทรานซิชันที่กำหนดเองได้โดยขยายคลาสใดก็ได้เหล่านี้เพื่อแสดงภาพเคลื่อนไหวตามที่คุณต้องการ การเปลี่ยนที่กำหนดเองสามารถติดตามการเปลี่ยนแปลงพร็อพเพอร์ตี้ที่คุณต้องการ และสร้างภาพเคลื่อนไหวตามการเปลี่ยนแปลงเหล่านั้นได้ เช่น คุณอาจระบุคลาสย่อยของ Transition
ที่คอยฟังการเปลี่ยนแปลงพร็อพเพอร์ตี้ "rotation" ของมุมมอง แล้วแสดงภาพการเปลี่ยนแปลงเป็นภาพเคลื่อนไหว
ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของ TransitionManager
การหยุดตัวสร้างภาพเคลื่อนไหวชั่วคราว
ตอนนี้ Animator
API ให้คุณหยุดภาพเคลื่อนไหวที่ดำเนินอยู่ชั่วคราวและเล่นต่อได้ด้วยเมธอด pause()
และ resume()
หากต้องการติดตามสถานะของภาพเคลื่อนไหว ให้ใช้อินเทอร์เฟซ Animator.AnimatorPauseListener
ซึ่งจะให้การเรียกกลับเมื่อภาพเคลื่อนไหวหยุดชั่วคราวและเล่นต่อ pause()
และ resume()
จากนั้นเพิ่มตัวรับฟังลงในออบเจ็กต์ Animator
ด้วย addPauseListener()
หรือจะสร้างคลาสย่อยของคลาสนามธรรม AnimatorListenerAdapter
ก็ได้ ซึ่งตอนนี้มีการใช้งานว่างสำหรับคอลแบ็กการหยุดชั่วคราวและดำเนินการต่อที่ Animator.AnimatorPauseListener
กำหนดไว้
บิตแมปแบบใช้ซ้ำได้
ตอนนี้คุณสามารถนําบิตแมปที่เปลี่ยนแปลงได้ใน BitmapFactory
มาใช้ซ้ำเพื่อถอดรหัสบิตแมปอื่นได้ แม้ว่าบิตแมปใหม่จะมีขนาดต่างกันก็ตาม ตราบใดที่จำนวนไบต์ที่ได้ของบิตแมปที่ถอดรหัสแล้ว (ดูได้จาก getByteCount()
) น้อยกว่าหรือเท่ากับจำนวนไบต์ที่จัดสรรของบิตแมปที่ใช้ซ้ำ (ดูได้จาก getAllocationByteCount()
ดูข้อมูลเพิ่มเติมได้ที่ inBitmap
API ใหม่สําหรับ Bitmap
อนุญาตให้กําหนดค่าใหม่ในลักษณะที่คล้ายกันเพื่อนําไปใช้ซ้ำนอก BitmapFactory
(สําหรับการสร้างบิตแมปด้วยตนเองหรือตรรกะการถอดรหัสที่กําหนดเอง) ตอนนี้คุณตั้งค่าขนาดของบิตแมปด้วยเมธอด setHeight()
และ setWidth()
รวมถึงระบุ Bitmap.Config
ใหม่ด้วย setConfig()
ได้แล้วโดยไม่ส่งผลต่อการจัดสรรบิตแมปพื้นฐาน นอกจากนี้ วิธี reconfigure()
ยังช่วยให้คุณรวมการเปลี่ยนแปลงเหล่านี้ไว้ในการเรียกใช้เพียงครั้งเดียวได้อีกด้วย
อย่างไรก็ตาม คุณไม่ควรกำหนดค่าบิตแมปที่ระบบมุมมองใช้อยู่ในปัจจุบันใหม่ เนื่องจากระบบจะไม่แมปบัฟเฟอร์พิกเซลที่อยู่เบื้องหลังใหม่ในลักษณะที่คาดการณ์ได้
เนื้อหาของผู้ใช้
เฟรมเวิร์กการเข้าถึงพื้นที่เก็บข้อมูล
ใน Android เวอร์ชันก่อนหน้า หากต้องการให้แอปดึงข้อมูลไฟล์บางประเภทจากแอปอื่น แอปจะต้องเรียกใช้ Intent ที่มีการดำเนินการ ACTION_GET_CONTENT
การดำเนินการนี้ยังคงเป็นวิธีที่เหมาะในการขอไฟล์ที่ต้องการนำเข้าไปยังแอป อย่างไรก็ตาม Android 4.4 ได้เปิดตัวการดำเนินการ ACTION_OPEN_DOCUMENT
ซึ่งช่วยให้ผู้ใช้เลือกไฟล์ประเภทที่ต้องการและอนุญาตให้แอปของคุณมีสิทธิ์อ่านไฟล์นั้นในระยะยาว (อาจมีสิทธิ์เขียนด้วย) โดยไม่ต้องนำเข้าไฟล์ไปยังแอป
หากกำลังพัฒนาแอปที่ให้บริการพื้นที่เก็บข้อมูลสำหรับไฟล์ (เช่น บริการบันทึกในระบบคลาวด์) คุณสามารถเข้าร่วม UI แบบรวมนี้เพื่อเลือกไฟล์ได้โดยการใช้ผู้ให้บริการเนื้อหาเป็นคลาสย่อยของคลาส DocumentsProvider
ใหม่ คลาสย่อยของ DocumentsProvider
ต้องมีตัวกรอง Intent ที่ยอมรับการดำเนินการ PROVIDER_INTERFACE
("android.content.action.DOCUMENTS_PROVIDER"
) จากนั้นคุณต้องใช้เมธอดนามธรรม 4 รายการใน DocumentsProvider
ดังนี้
queryRoots()
- การดำเนินการนี้ต้องแสดงผล
Cursor
ที่อธิบายไดเรกทอรีรูททั้งหมดของพื้นที่เก็บข้อมูลเอกสารโดยใช้คอลัมน์ที่กําหนดไว้ในDocumentsContract.Root
queryChildDocuments()
- การดำเนินการนี้ต้องแสดงผล
Cursor
ที่อธิบายไฟล์ทั้งหมดในไดเรกทอรีที่ระบุ โดยใช้คอลัมน์ที่กําหนดไว้ในDocumentsContract.Document
queryDocument()
- การดำเนินการนี้ต้องแสดงผล
Cursor
ที่อธิบายไฟล์ที่ระบุโดยใช้คอลัมน์ที่กําหนดไว้ในDocumentsContract.Document
openDocument()
- การดำเนินการนี้ต้องแสดงผล
ParcelFileDescriptor
ที่แสดงไฟล์ที่ระบุ ระบบจะเรียกใช้เมธอดนี้เมื่อผู้ใช้เลือกไฟล์และแอปไคลเอ็นต์ขอสิทธิ์เข้าถึงโดยเรียกใช้openFileDescriptor()
ดูข้อมูลเพิ่มเติมได้ที่คู่มือเฟรมเวิร์กการเข้าถึงพื้นที่เก็บข้อมูล
การเข้าถึงพื้นที่เก็บข้อมูลภายนอก
ตอนนี้คุณสามารถอ่านและเขียนไฟล์เฉพาะแอปในสื่อจัดเก็บข้อมูลภายนอกรองได้แล้ว เช่น เมื่ออุปกรณ์มีทั้งพื้นที่เก็บข้อมูลจำลองและการ์ด SD เมธอดใหม่ getExternalFilesDirs()
ทำงานเหมือนกับเมธอด getExternalFilesDir()
ที่มีอยู่ ยกเว้นว่าจะแสดงผลอาร์เรย์ของออบเจ็กต์ File
ก่อนที่จะอ่านหรือเขียนไปยังเส้นทางใดๆ ที่เมธอดนี้แสดงผล ให้ส่งออบเจ็กต์ File
ไปยังเมธอด getStorageState()
ใหม่เพื่อยืนยันว่ามีพื้นที่เก็บข้อมูลในขณะนี้
ตอนนี้วิธีการอื่นๆ ในการเข้าถึงไดเรกทอรีแคชเฉพาะแอปและไดเรกทอรี OBB ก็มีเวอร์ชันที่สอดคล้องกันซึ่งให้สิทธิ์เข้าถึงอุปกรณ์เก็บข้อมูลรองด้วย ได้แก่ getExternalCacheDirs()
และ getObbDirs()
ตามลำดับ
รายการแรกในอาร์เรย์ File
ที่แสดงผลจะถือว่าเป็นพื้นที่เก็บข้อมูลภายนอกหลักของอุปกรณ์ ซึ่งเหมือนกับ File
ที่แสดงผลโดยเมธอดที่มีอยู่ เช่น getExternalFilesDir()
หมายเหตุ: ตั้งแต่ Android 4.4 เป็นต้นไป แพลตฟอร์มจะไม่กำหนดให้แอปของคุณต้องขอ WRITE_EXTERNAL_STORAGE
หรือ READ_EXTERNAL_STORAGE
อีกต่อไปเมื่อคุณต้องการเข้าถึงเฉพาะภูมิภาคของที่จัดเก็บข้อมูลภายนอกสำหรับแอปของคุณโดยใช้วิธีการข้างต้น อย่างไรก็ตาม คุณต้องมีสิทธิ์ดังกล่าวหากต้องการเข้าถึงภูมิภาคที่แชร์ได้ของพื้นที่เก็บข้อมูลภายนอกซึ่ง getExternalStoragePublicDirectory()
เป็นผู้จัดหา
อะแดปเตอร์การซิงค์
เมธอด requestSync()
ใหม่ใน ContentResolver
ช่วยลดขั้นตอนบางอย่างในการกําหนดคําขอซิงค์สําหรับ ContentProvider
โดยการรวมคําขอไว้ในออบเจ็กต์ SyncRequest
ใหม่ ซึ่งคุณสร้างได้ด้วย SyncRequest.Builder
พร็อพเพอร์ตี้ใน SyncRequest
มีฟังก์ชันการทำงานเหมือนกับการเรียกใช้การซิงค์ ContentProvider
ที่มีอยู่ แต่เพิ่มความสามารถในการระบุว่าควรยกเลิกการซิงค์หากเครือข่ายมีการวัดปริมาณโดยเปิดใช้ setDisallowMetered()
ข้อมูลจากผู้ใช้
เซ็นเซอร์ประเภทใหม่
เซ็นเซอร์ TYPE_GEOMAGNETIC_ROTATION_VECTOR
ใหม่จะให้ข้อมูลเวกเตอร์การหมุนตามเครื่องวัดค่าความเข้มข้นของสนามแม่เหล็ก ซึ่งเป็นทางเลือกที่มีประโยชน์สำหรับเซ็นเซอร์ TYPE_ROTATION_VECTOR
เมื่อไม่มีเครื่องวัดการหมุน หรือเมื่อใช้กับเหตุการณ์เซ็นเซอร์แบบเป็นกลุ่มเพื่อบันทึกการวางแนวของอุปกรณ์ขณะที่โทรศัพท์อยู่ในโหมดสลีป เซ็นเซอร์นี้ใช้พลังงานน้อยกว่า TYPE_ROTATION_VECTOR
แต่อาจเสี่ยงที่จะเกิดข้อมูลเหตุการณ์ที่มีสัญญาณรบกวน และมีประสิทธิภาพสูงสุดเมื่อผู้ใช้อยู่กลางแจ้ง
ตอนนี้ Android ยังรองรับเซ็นเซอร์การนับก้าวในตัวในฮาร์ดแวร์ด้วย
TYPE_STEP_DETECTOR
- เซ็นเซอร์นี้จะทริกเกอร์เหตุการณ์ทุกครั้งที่ผู้ใช้ก้าวเดิน เมื่อผู้ใช้ดำเนินการแต่ละขั้นตอน เซ็นเซอร์นี้จะส่งเหตุการณ์ที่มีค่า 1.0 และการประทับเวลาซึ่งระบุเวลาที่เกิดขั้นตอนนั้น
TYPE_STEP_COUNTER
- เซ็นเซอร์นี้จะทริกเกอร์เหตุการณ์เมื่อตรวจพบการก้าวแต่ละครั้งด้วย แต่จะให้จํานวนก้าวทั้งหมดที่สะสมตั้งแต่แอปลงทะเบียนเซ็นเซอร์นี้เป็นครั้งแรกแทน
โปรดทราบว่าเซ็นเซอร์แบบ 2 ขั้นตอนเหล่านี้อาจให้ผลลัพธ์ไม่เหมือนกันเสมอไป เหตุการณ์ TYPE_STEP_COUNTER
เกิดขึ้นโดยมีความล่าช้าสูงกว่าเหตุการณ์จาก TYPE_STEP_DETECTOR
แต่นั่นเป็นเพราะอัลกอริทึม TYPE_STEP_COUNTER
ประมวลผลมากกว่าเพื่อกำจัดผลบวกลวง ดังนั้น TYPE_STEP_COUNTER
จึงอาจส่งเหตุการณ์ช้ากว่า แต่ผลลัพธ์ก็น่าจะแม่นยำมากขึ้น
เซ็นเซอร์การเดินทั้ง 2 ประเภทขึ้นอยู่กับฮาร์ดแวร์ (Nexus 5 เป็นอุปกรณ์แรกที่รองรับ) คุณจึงควรตรวจสอบความพร้อมใช้งานด้วย hasSystemFeature()
โดยใช้ค่าคงที่ FEATURE_SENSOR_STEP_DETECTOR
และ FEATURE_SENSOR_STEP_COUNTER
เหตุการณ์เซ็นเซอร์แบบเป็นกลุ่ม
ตอนนี้ SensorManager
API ให้คุณระบุความถี่ที่คุณต้องการให้ระบบส่งเหตุการณ์เซ็นเซอร์เป็นกลุ่มไปยังแอปได้แล้ว เพื่อจัดการพลังงานของอุปกรณ์ได้ดียิ่งขึ้น ซึ่งจะไม่ลดจํานวนเหตุการณ์เซ็นเซอร์จริงที่พร้อมใช้งานสําหรับแอปของคุณในระยะเวลาที่กําหนด แต่จะเป็นการเพิ่มความถี่ที่ระบบเรียก SensorEventListener
ของคุณด้วยข้อมูลอัปเดตเซ็นเซอร์แทน กล่าวคือ ระบบจะบันทึกเหตุการณ์ทั้งหมดที่เกิดขึ้นในช่วงระยะเวลาหนึ่ง จากนั้นส่งเหตุการณ์เหล่านั้นไปยังแอปของคุณพร้อมกันแทนที่จะส่งเหตุการณ์แต่ละรายการทันทีที่เหตุการณ์เกิดขึ้น
คลาส SensorManager
จะเพิ่มเมธอด registerListener()
เวอร์ชันใหม่ 2 เวอร์ชันเพื่อให้คุณระบุ "เวลาในการตอบสนองสูงสุดของรายงาน" ได้ พารามิเตอร์ใหม่นี้จะระบุความล่าช้าสูงสุดที่ SensorEventListener
จะยอมรับสำหรับการนำส่งเหตุการณ์เซ็นเซอร์ใหม่ ตัวอย่างเช่น หากคุณระบุเวลาในการตอบสนองของกลุ่มเป็น 1 นาที ระบบจะส่งชุดเหตุการณ์ล่าสุดที่จัดกลุ่มเป็นกลุ่มๆ โดยเว้นระยะไม่เกิน 1 นาทีด้วยการเรียกใช้เมธอด onSensorChanged()
ติดต่อกัน 1 ครั้งสําหรับแต่ละเหตุการณ์ที่จัดกลุ่ม เหตุการณ์เซ็นเซอร์จะไม่ล่าช้านานกว่าค่าเวลาในการตอบสนองสูงสุดของรายงาน แต่อาจมาถึงเร็วกว่านั้นหากแอปอื่นๆ ขอเวลาในการตอบสนองที่สั้นลงสำหรับเซ็นเซอร์เดียวกัน
อย่างไรก็ตาม โปรดทราบว่าเซ็นเซอร์จะส่งเหตุการณ์แบบเป็นกลุ่มไปยังแอปตามเวลาในการตอบสนองของรายงานเฉพาะในขณะที่ CPU ทำงานอยู่ แม้ว่าเซ็นเซอร์ฮาร์ดแวร์ที่รองรับการจัดกลุ่มจะรวบรวมเหตุการณ์ของเซ็นเซอร์ต่อไปขณะที่ CPU อยู่ในโหมดสลีป แต่จะไม่ปลุก CPU เพื่อส่งเหตุการณ์ที่จัดกลุ่มไปยังแอป เมื่อเซ็นเซอร์หมดหน่วยความจำสำหรับเหตุการณ์แล้ว ก็จะเริ่มทิ้งเหตุการณ์ที่เก่าที่สุดเพื่อบันทึกเหตุการณ์ล่าสุด คุณสามารถหลีกเลี่ยงการสูญเสียเหตุการณ์ได้โดยการปลุกอุปกรณ์ก่อนที่เซ็นเซอร์จะเต็มหน่วยความจำ จากนั้นเรียกใช้ flush()
เพื่อบันทึกเหตุการณ์กลุ่มล่าสุด หากต้องการประมาณว่าหน่วยความจำจะเต็มเมื่อใดและควรล้าง ให้เรียก getFifoMaxEventCount()
เพื่อรับจำนวนเหตุการณ์เซ็นเซอร์สูงสุดที่หน่วยความจำจะบันทึกได้ แล้วหารด้วยอัตราที่แอปต้องการแต่ละเหตุการณ์ ใช้การคํานวณดังกล่าวเพื่อตั้งการปลุกด้วย AlarmManager
ที่เรียกใช้ Service
(ซึ่งใช้ SensorEventListener
) เพื่อล้างเซ็นเซอร์
หมายเหตุ: อุปกรณ์บางรุ่นไม่รองรับการจัดกลุ่มเหตุการณ์เซ็นเซอร์ เนื่องจากเซ็นเซอร์ฮาร์ดแวร์ต้องรองรับ อย่างไรก็ตาม ตั้งแต่ Android 4.4 เป็นต้นไป คุณควรใช้เมธอด registerListener()
ใหม่เสมอ เนื่องจากหากอุปกรณ์ไม่รองรับการรวมกลุ่ม ระบบจะไม่สนใจอาร์กิวเมนต์เวลาในการตอบสนองของกลุ่มและส่งเหตุการณ์เซ็นเซอร์แบบเรียลไทม์
ข้อมูลประจำตัวของผู้ควบคุมข้อมูล
ตอนนี้ Android จะระบุตัวควบคุมที่เชื่อมต่อแต่ละตัวด้วยจำนวนเต็มที่ไม่ซ้ำกันซึ่งคุณค้นหาได้ด้วย getControllerNumber()
ซึ่งจะช่วยให้คุณเชื่อมโยงตัวควบคุมแต่ละตัวกับผู้เล่นคนละคนในเกมได้ง่ายขึ้น หมายเลขสำหรับตัวควบคุมแต่ละตัวอาจเปลี่ยนแปลงเนื่องจากผู้ใช้ยกเลิกการเชื่อมต่อ เชื่อมต่อ หรือกำหนดค่าตัวควบคุมใหม่ คุณจึงควรติดตามว่าหมายเลขตัวควบคุมใดสอดคล้องกับอุปกรณ์อินพุตแต่ละเครื่องโดยลงทะเบียนอินสแตนซ์ของ InputManager.InputDeviceListener
จากนั้นเรียกใช้ getControllerNumber()
สำหรับ InputDevice
แต่ละรายการเมื่อมีการเปลี่ยนแปลง
ตอนนี้อุปกรณ์ที่เชื่อมต่อยังระบุรหัสผลิตภัณฑ์และรหัสผู้ให้บริการที่พร้อมใช้งานจาก getProductId()
และ getVendorId()
ด้วย หากต้องการแก้ไขการแมปแป้นตามชุดแป้นที่ใช้ได้บนอุปกรณ์ คุณสามารถค้นหาอุปกรณ์เพื่อดูว่าแป้นบางแป้นพร้อมใช้งานหรือไม่ด้วย hasKeys(int...)
อินเทอร์เฟซผู้ใช้
โหมดเต็มหน้าจอสมจริง
หากต้องการให้แอปมีเลย์เอาต์ที่เต็มหน้าจอ Flag SYSTEM_UI_FLAG_IMMERSIVE
ใหม่สําหรับ setSystemUiVisibility()
(เมื่อใช้ร่วมกับ SYSTEM_UI_FLAG_HIDE_NAVIGATION
) จะเปิดใช้โหมดเต็มหน้าจอแบบสมจริงใหม่ ขณะที่เปิดใช้โหมดเต็มหน้าจอที่สมจริง กิจกรรมจะยังคงรับเหตุการณ์การสัมผัสทั้งหมด ผู้ใช้สามารถแสดงแถบระบบด้วยการปัดเข้าด้านในบริเวณที่แถบระบบปรากฏตามปกติ ซึ่งจะล้าง Flag SYSTEM_UI_FLAG_HIDE_NAVIGATION
(และ Flag SYSTEM_UI_FLAG_FULLSCREEN
หากมี) เพื่อให้แถบระบบยังคงปรากฏอยู่ อย่างไรก็ตาม หากต้องการให้แถบระบบซ่อนอีกครั้งหลังจากผ่านไป 2-3 วินาที คุณสามารถใช้ Flag SYSTEM_UI_FLAG_IMMERSIVE_STICKY
แทนได้
แถบระบบแบบโปร่งแสง
ตอนนี้คุณสามารถทำให้แถบระบบโปร่งแสงได้บางส่วนด้วยธีมใหม่ Theme.Holo.NoActionBar.TranslucentDecor
และ Theme.Holo.Light.NoActionBar.TranslucentDecor
การเปิดใช้แถบระบบแบบโปร่งแสงจะทำให้เลย์เอาต์ของคุณแสดงเต็มพื้นที่ด้านหลังแถบระบบ คุณจึงต้องเปิดใช้ fitsSystemWindows
สำหรับส่วนของเลย์เอาต์ที่ไม่ควรถูกแถบระบบบดบังด้วย
หากกำลังสร้างธีมที่กำหนดเอง ให้ตั้งค่าธีมใดธีมหนึ่งเป็นธีมหลัก หรือใส่พร็อพเพอร์ตี้สไตล์ windowTranslucentNavigation
และ windowTranslucentStatus
ไว้ในธีม
Listener การแจ้งเตือนที่ปรับปรุงแล้ว
Android 4.3 เพิ่ม NotificationListenerService
API ซึ่งช่วยให้แอปได้รับข้อมูลเกี่ยวกับการแจ้งเตือนใหม่เมื่อระบบโพสต์การแจ้งเตือน ใน Android 4.4 โปรแกรมรับฟังการแจ้งเตือนจะดึงข้อมูลเมตาเพิ่มเติมสำหรับการแจ้งเตือนและรายละเอียดการดำเนินการของการแจ้งเตือนได้ดังนี้
ช่อง Notification.extras
ใหม่จะมี Bundle
เพื่อส่งข้อมูลเมตาเพิ่มเติมไปยังเครื่องมือสร้างการแจ้งเตือน เช่น EXTRA_TITLE
และ EXTRA_PICTURE
คลาส Notification.Action
ใหม่จะกำหนดลักษณะของการดําเนินการซึ่งแนบมากับการแจ้งเตือน ซึ่งคุณจะดึงข้อมูลได้จากช่อง actions
ใหม่
การมิเรอร์ Drawable สำหรับเลย์เอาต์ RTL
ใน Android เวอร์ชันเก่า หากแอปมีรูปภาพที่ควรกลับการวางแนวแนวนอนสำหรับเลย์เอาต์จากขวาไปซ้าย คุณต้องใส่รูปภาพที่กลับด้านในไดเรกทอรีทรัพยากร drawables-ldrtl/
ตอนนี้ระบบจะมิเรอร์รูปภาพให้คุณโดยอัตโนมัติด้วยการเปิดใช้แอตทริบิวต์ autoMirrored
ในทรัพยากรที่วาดได้ หรือเรียกใช้ setAutoMirrored()
เมื่อเปิดใช้ Drawable
จะแสดงกลับด้านโดยอัตโนมัติเมื่อเลย์เอาต์เป็นจากขวาไปซ้าย
การช่วยเหลือพิเศษ
ตอนนี้คลาส View
ให้คุณประกาศ "พื้นที่โฆษณาแบบเรียลไทม์" สำหรับส่วนของ UI ที่อัปเดตแบบไดนามิกด้วยเนื้อหาข้อความใหม่ได้แล้ว โดยการเพิ่มแอตทริบิวต์ accessibilityLiveRegion
ใหม่ลงในเลย์เอาต์ XML หรือเรียกใช้ setAccessibilityLiveRegion()
เช่น หน้าจอการเข้าสู่ระบบที่มีช่องข้อความที่แสดงการแจ้งเตือน "รหัสผ่านไม่ถูกต้อง" ควรทำเครื่องหมายเป็นพื้นที่ที่ใช้งานอยู่เพื่อให้โปรแกรมอ่านหน้าจออ่านออกเสียงข้อความเมื่อข้อความมีการเปลี่ยนแปลง
ตอนนี้แอปที่ให้บริการการช่วยเหลือพิเศษยังเพิ่มประสิทธิภาพด้วย API ใหม่ที่ให้ข้อมูลเกี่ยวกับคอลเล็กชันมุมมอง เช่น มุมมองรายการหรือตารางกริด โดยใช้ AccessibilityNodeInfo.CollectionInfo
และ AccessibilityNodeInfo.CollectionItemInfo
สิทธิ์ของแอป
ต่อไปนี้คือสิทธิ์ใหม่ที่แอปของคุณต้องขอด้วยแท็ก <uses-permission>
เพื่อใช้ API ใหม่บางรายการ
INSTALL_SHORTCUT
- อนุญาตให้แอปพลิเคชันติดตั้งทางลัดใน Launcher
UNINSTALL_SHORTCUT
- อนุญาตให้แอปพลิเคชันถอนการติดตั้งทางลัดใน Launcher
TRANSMIT_IR
- อนุญาตให้แอปพลิเคชันใช้ตัวส่งสัญญาณอินฟราเรดของอุปกรณ์ (หากมี)
หมายเหตุ: ตั้งแต่ Android 4.4 เป็นต้นไป แพลตฟอร์มจะไม่กำหนดให้แอปของคุณต้องขอ WRITE_EXTERNAL_STORAGE
หรือ READ_EXTERNAL_STORAGE
อีกต่อไปเมื่อคุณต้องการเข้าถึงพื้นที่เก็บข้อมูลภายนอกเฉพาะแอปโดยใช้วิธีการต่างๆ เช่น getExternalFilesDir()
อย่างไรก็ตาม คุณยังคงต้องใช้สิทธิ์หากต้องการเข้าถึงภูมิภาคที่แชร์ได้ของพื้นที่เก็บข้อมูลภายนอกที่ getExternalStoragePublicDirectory()
เป็นผู้จัดหา
ฟีเจอร์ของอุปกรณ์
ต่อไปนี้คือฟีเจอร์ใหม่ของอุปกรณ์ที่คุณประกาศได้ด้วยแท็ก <uses-feature>
เพื่อประกาศข้อกำหนดของแอปและเปิดใช้การกรองใน Google Play หรือตรวจสอบขณะรันไทม์
FEATURE_CONSUMER_IR
- อุปกรณ์สื่อสารกับอุปกรณ์ IR ของผู้บริโภคได้
FEATURE_DEVICE_ADMIN
- อุปกรณ์รองรับการบังคับใช้นโยบายด้านอุปกรณ์ผ่านผู้ดูแลระบบอุปกรณ์
FEATURE_NFC_HOST_CARD_EMULATION
- อุปกรณ์รองรับการจำลองบัตร NFC แบบโฮสต์
FEATURE_SENSOR_STEP_COUNTER
- อุปกรณ์มีตัวนับก้าวแบบฮาร์ดแวร์
FEATURE_SENSOR_STEP_DETECTOR
- อุปกรณ์มีตัวตรวจจับการก้าวของฮาร์ดแวร์
ดูรายละเอียดการเปลี่ยนแปลง API ทั้งหมดใน Android 4.4 ได้ที่รายงานความแตกต่างของ API