สร้างโฮสต์วิดเจ็ต

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

หน้านี้จะเน้นความรับผิดชอบที่เกี่ยวข้องกับการติดตั้งใช้งานAppWidgetHostที่กําหนดเอง ดูตัวอย่างที่เฉพาะเจาะจงเกี่ยวกับวิธีใช้ AppWidgetHost ได้ที่ซอร์สโค้ดของหน้าจอหลัก Android LauncherAppWidgetHost

ภาพรวมของคลาสและแนวคิดหลักที่เกี่ยวข้องกับการติดตั้งใช้งาน AppWidgetHost ที่กําหนดเองมีดังนี้

  • โฮสต์วิดเจ็ตแอป: AppWidgetHost ให้การโต้ตอบกับบริการ AppWidget สําหรับแอปที่ฝังวิดเจ็ตใน UI AppWidgetHost ต้องมีรหัสที่ไม่ซ้ำกันภายในแพ็กเกจของโฮสต์เอง รหัสนี้จะคงอยู่ตลอดการใช้งานโฮสต์ โดยปกติแล้วรหัสจะเป็นค่าฮาร์ดโค้ดที่คุณกำหนดในแอป

  • รหัสวิดเจ็ตแอป: อินสแตนซ์วิดเจ็ตแต่ละรายการจะได้รับรหัสที่ไม่ซ้ำกันเมื่อมีการเชื่อมโยง ดู bindAppWidgetIdIfAllowed() และดูรายละเอียดเพิ่มเติมได้ในส่วนการเชื่อมโยงวิดเจ็ตต่อจากนี้ โฮสต์จะได้รับรหัสที่ไม่ซ้ำกันโดยใช้ allocateAppWidgetId() รหัสนี้จะคงอยู่ตลอดอายุการใช้งานของวิดเจ็ตจนกว่าจะถูกลบออกจากโฮสต์ สถานะเฉพาะของโฮสต์ เช่น ขนาดและตําแหน่งของวิดเจ็ต จะต้องได้รับการเก็บรักษาโดยแพ็กเกจโฮสติ้งและเชื่อมโยงกับรหัสวิดเจ็ตแอป

  • มุมมองโฮสต์วิดเจ็ตแอป: ให้คิดว่า AppWidgetHostView เป็นกรอบที่บรรจุวิดเจ็ตไว้ทุกครั้งที่ต้องแสดง วิดเจ็ตจะเชื่อมโยงกับ AppWidgetHostView ทุกครั้งที่โฮสต์สร้างวิดเจ็ต

    • โดยค่าเริ่มต้น ระบบจะสร้าง AppWidgetHostView แต่โฮสต์สามารถสร้างคลาสย่อยของ AppWidgetHostView ของตัวเองได้โดยขยายคลาสนั้น
    • ตั้งแต่ Android 12 (API ระดับ 31) AppWidgetHostView ได้เปิดตัววิธีสำหรับจัดการสีที่รับน้ำหนักแบบไดนามิก ดังนี้ setColorResources() และ resetColorResources() โฮสต์มีหน้าที่รับผิดชอบในการระบุสีให้กับเมธอดเหล่านี้
  • กลุ่มตัวเลือก: AppWidgetHost ใช้กลุ่มตัวเลือกเพื่อสื่อสารข้อมูลเกี่ยวกับวิธีแสดงวิดเจ็ตให้กับ AppWidgetProvider เช่น รายการช่วงขนาด และวิดเจ็ตจะแสดงในหน้าจอล็อกหรือหน้าจอหลัก ข้อมูลนี้ช่วยให้ AppWidgetProvider ปรับแต่งเนื้อหาและลักษณะที่ปรากฏของวิดเจ็ตตามวิธีและตำแหน่งที่แสดง คุณใช้ updateAppWidgetOptions() และ updateAppWidgetSize() เพื่อแก้ไขแพ็กเกจของวิดเจ็ตได้ ทั้ง 2 วิธีนี้จะทริกเกอร์การเรียกกลับonAppWidgetOptionsChanged()ไปที่ AppWidgetProvider

การเชื่อมโยงวิดเจ็ต

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

นอกจากนี้ การเชื่อมโยง API ยังช่วยให้โฮสต์ระบุ UI ที่กําหนดเองสําหรับการเชื่อมโยงได้อีกด้วย หากต้องการใช้กระบวนการนี้ แอปของคุณต้องประกาศสิทธิ์ BIND_APPWIDGET ในไฟล์ Manifest ของโฮสต์

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

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

ข้อมูลโค้ดนี้แสดงตัวอย่างวิธีแสดงกล่องโต้ตอบ

Kotlin

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)
    // This is the options bundle described in the preceding section.
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)
}
startActivityForResult(intent, REQUEST_BIND_APPWIDGET)

Java

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle described in the preceding section.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);

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

ความรับผิดชอบของโฮสต์

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

ไม่ว่าคุณจะกำหนดเป้าหมาย Android เวอร์ชันใด โฮสต์ทุกรายมีหน้าที่รับผิดชอบดังต่อไปนี้

  • เมื่อเพิ่มวิดเจ็ต ให้กําหนดรหัสวิดเจ็ตตามที่อธิบายไว้ก่อนหน้านี้ เมื่อนำวิดเจ็ตออกจากโฮสต์แล้ว ให้เรียกใช้ deleteAppWidgetId() เพื่อยกเลิกการจัดสรรหน่วยความจำของรหัสวิดเจ็ต

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

  • วิดเจ็ตจะระบุความกว้างและความสูงเริ่มต้นในAppWidgetProviderInfoข้อมูลเมตา ค่าเหล่านี้จะกำหนดไว้ในเซลล์ โดยเริ่มตั้งแต่ Android 12 หากระบุ targetCellWidth และ targetCellHeight หรือ dps หากระบุเฉพาะ minWidth และ minHeight ดูแอตทริบิวต์การปรับขนาดวิดเจ็ต

    ตรวจสอบว่าวิดเจ็ตมีการแสดงผลด้วย DPI อย่างน้อยเท่านี้ ตัวอย่างเช่น โฮสต์จำนวนมากจัดแนวไอคอนและวิดเจ็ตในตารางกริด ในสถานการณ์นี้ โฮสต์จะเพิ่มวิดเจ็ตโดยใช้จำนวนเซลล์ขั้นต่ำที่เป็นไปตามข้อจำกัด minWidth และ minHeight โดยค่าเริ่มต้น

นอกเหนือจากข้อกำหนดที่ระบุไว้ในส่วนก่อนหน้าแล้ว แพลตฟอร์มบางเวอร์ชันยังมีฟีเจอร์ที่เพิ่มภาระหน้าที่ใหม่ๆ ให้แก่โฮสต์ด้วย

กำหนดแนวทางตามเวอร์ชัน Android ที่กำหนดเป้าหมาย

Android 12

Android 12 (API ระดับ 31) จะรวม List<SizeF> เพิ่มเติมที่มีรายการขนาดที่เป็นไปได้ใน dps ที่อินสแตนซ์วิดเจ็ตใช้ได้ไว้ในกลุ่มตัวเลือก จำนวนขนาดที่ระบุจะขึ้นอยู่กับการติดตั้งใช้งานของโฮสต์ โดยปกติแล้ว โฮสต์จะมี 2 ขนาดสำหรับโทรศัพท์ ได้แก่ แนวตั้งและแนวนอน และ 4 ขนาดสำหรับอุปกรณ์แบบพับได้

AppWidgetProvider หนึ่งรายการสามารถระบุRemoteViewsได้สูงสุด MAX_INIT_VIEW_COUNT (16) รายการให้กับRemoteViews เนื่องจากออบเจ็กต์ AppWidgetProvider จะจับคู่ออบเจ็กต์ RemoteViews กับแต่ละขนาดใน List<SizeF> อย่าระบุขนาดมากกว่า MAX_INIT_VIEW_COUNT

นอกจากนี้ Android 12 ยังเปิดตัวแอตทริบิวต์ maxResizeWidth และ maxResizeHeight ใน dps ด้วย เราขอแนะนำให้วิดเจ็ตที่ใช้แอตทริบิวต์เหล่านี้อย่างน้อย 1 รายการมีขนาดไม่เกินขนาดที่แอตทริบิวต์ระบุ

แหล่งข้อมูลเพิ่มเติม

  • ดูเอกสารอ้างอิง Glance