สร้างการ์ดการตั้งค่าด่วนที่กำหนดเองสำหรับแอป

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

แผงการตั้งค่าด่วนที่มีการเปิดและปิดการ์ด VPN
รูปที่ 1 แผงการตั้งค่าด่วนที่เปิดและปิดการ์ด VPN

เลือกเวลาสร้างการ์ด

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

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

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

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

  • หลีกเลี่ยงการใช้การ์ดเพื่อเปิดแอป ให้ใช้ทางลัดของแอปหรือ Launcher มาตรฐานแทน

  • หลีกเลี่ยงการใช้การ์ดสําหรับการดําเนินการของผู้ใช้แบบครั้งเดียว ให้ใช้ทางลัดของแอปหรือการแจ้งเตือนแทน

  • หลีกเลี่ยงการสร้างการ์ดมากเกินไป เราแนะนำให้มี URL ไม่เกิน 2 รายการต่อแอป โปรดใช้แป้นพิมพ์ลัดสำหรับแอปแทน

  • หลีกเลี่ยงการใช้การ์ดที่แสดงข้อมูลแต่ผู้ใช้ไม่สามารถโต้ตอบได้ ให้ใช้การแจ้งเตือนหรือวิดเจ็ตแทน

สร้างหน้าต่าง

หากต้องการสร้างการ์ด คุณต้องสร้างไอคอนการ์ดที่เหมาะสมก่อน จากนั้นสร้างและประกาศ TileService ในไฟล์ Manifest ของแอป

ตัวอย่างการตั้งค่าด่วนแสดงตัวอย่างวิธีสร้างและจัดการการ์ด

สร้างไอคอนที่กำหนดเอง

คุณจะต้องระบุไอคอนที่กำหนดเอง ซึ่งจะแสดงบนการ์ดในแผงการตั้งค่าด่วน (คุณจะเพิ่มไอคอนนี้เมื่อประกาศ TileService ซึ่งอธิบายไว้ในส่วนถัดไป) ไอคอนต้องเป็นสีขาวทึบพร้อมพื้นหลังโปร่งใส วัดขนาด 24 x 24dp และอยู่ในรูปแบบของ VectorDrawable

ตัวอย่างเวกเตอร์ที่ถอนออกได้
รูปที่ 3 ตัวอย่าง Vector Drawable

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

สร้างและประกาศ TileService

สร้างบริการสำหรับการ์ดที่ขยายคลาส TileService

Kotlin

class MyQSTileService: TileService() {

  // Called when the user adds your tile.
  override fun onTileAdded() {
    super.onTileAdded()
  }
  // Called when your app can update your tile.
  override fun onStartListening() {
    super.onStartListening()
  }

  // Called when your app can no longer update your tile.
  override fun onStopListening() {
    super.onStopListening()
  }

  // Called when the user taps on your tile in an active or inactive state.
  override fun onClick() {
    super.onClick()
  }
  // Called when the user removes your tile.
  override fun onTileRemoved() {
    super.onTileRemoved()
  }
}

Java

public class MyQSTileService extends TileService {

  // Called when the user adds your tile.
  @Override
  public void onTileAdded() {
    super.onTileAdded();
  }

  // Called when your app can update your tile.
  @Override
  public void onStartListening() {
    super.onStartListening();
  }

  // Called when your app can no longer update your tile.
  @Override
  public void onStopListening() {
    super.onStopListening();
  }

  // Called when the user taps on your tile in an active or inactive state.
  @Override
  public void onClick() {
    super.onClick();
  }

  // Called when the user removes your tile.
  @Override
  public void onTileRemoved() {
    super.onTileRemoved();
  }
}

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

 <service
     android:name=".MyQSTileService"
     android:exported="true"
     android:label="@string/my_default_tile_label"  // 18-character limit.
     android:icon="@drawable/my_default_icon_label"
     android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
     <intent-filter>
         <action android:name="android.service.quicksettings.action.QS_TILE" />
     </intent-filter>
 </service>

จัดการ TileService ของคุณ

เมื่อสร้างและประกาศ TileService ในไฟล์ Manifest ของแอปแล้ว คุณจะต้องจัดการสถานะของ TileService

TileService เป็นบริการที่มีผลผูกพัน TileService จะมีผลเมื่อแอปขอหรือหากระบบจำเป็นต้องสื่อสารกับแอป วงจรชีวิตของบริการที่เชื่อมโยงโดยทั่วไปมีเมธอดการเรียกกลับ 4 รายการ ได้แก่ onCreate(), onBind(), onUnbind() และ onDestroy() ระบบจะเรียกใช้เมธอดเหล่านี้ทุกครั้งที่บริการเข้าสู่ช่วงวงจรใหม่

ภาพรวมวงจรการใช้งาน TileService

นอกเหนือจากการเรียกกลับที่ควบคุมวงจรบริการที่เชื่อมโยงแล้ว คุณต้องติดตั้งใช้งานเมธอดอื่นๆ สำหรับวงจร TileService โดยเฉพาะ วิธีการเหล่านี้อาจเรียกใช้นอก onCreate() และ onDestroy() เนื่องจากมีการเรียกใช้เมธอดวงจรชีวิตของ Service และเมธอดวงจรชีวิตของ TileService ใน 2 เทรดที่ไม่สอดคล้องกัน

วงจรชีวิตของ TileService มีเมธอดต่อไปนี้ ซึ่งระบบจะเรียกใช้ทุกครั้งที่ TileService เข้าสู่ระยะวงจรใหม่

  • onTileAdded(): ระบบจะเรียกใช้เมธอดนี้เฉพาะเมื่อผู้ใช้เพิ่มการ์ดเป็นครั้งแรก และในกรณีที่ผู้ใช้นำการ์ดออกแล้วเพิ่มการ์ดอีกครั้ง นี่เป็นเวลาที่เหมาะที่สุดในการเริ่มต้นใช้งานแบบครั้งเดียว อย่างไรก็ตาม การดำเนินการนี้อาจไม่เป็นไปตามการเริ่มต้นที่จำเป็นทั้งหมด

  • onStartListening() และ onStopListening(): ระบบจะเรียกใช้เมธอดเหล่านี้ทุกครั้งที่แอปอัปเดตการ์ด และเรียกใช้บ่อยครั้ง TileService จะยังคงเชื่อมโยงระหว่าง onStartListening() กับ onStopListening() ซึ่งช่วยให้แอปของคุณแก้ไขการ์ดและพุชการอัปเดตได้

  • onTileRemoved(): ระบบจะเรียกใช้เมธอดนี้เฉพาะในกรณีที่ผู้ใช้นำการ์ดของคุณออกเท่านั้น

เลือกโหมดการฟัง

TileService จะฟังในโหมดแอ็กทีฟหรือโหมดไม่ได้ใช้งาน เราขอแนะนำให้ใช้โหมดทำงาน ซึ่งคุณจะต้องประกาศในไฟล์ Manifest ของแอป มิเช่นนั้น TileService จะเป็นโหมดมาตรฐานและไม่จำเป็นต้องประกาศ

อย่าคิดว่า TileService จะอยู่นอกคู่เมธอด onStartListening() และ onStopListening()

ใช้โหมดทำงานสําหรับ TileService ที่คอยฟังและตรวจสอบสถานะในกระบวนการของตนเอง TileService ในโหมดทำงานจะเชื่อมโยงกับ onTileAdded(), onTileRemoved(), เหตุการณ์การแตะ และเมื่อกระบวนการของแอปร้องขอ

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

คุณสามารถเรียกเมธอด TileService.requestListeningState() แบบคงที่เพื่อส่งคําขอเริ่มสถานะการฟังและรับการติดต่อกลับไปยัง onStartListening()

คุณสามารถประกาศโหมดทำงานได้โดยเพิ่ม META_DATA_ACTIVE_TILE ลงในไฟล์ Manifest ของแอป

<service ...>
    <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
         android:value="true" />
    ...
</service>

โหมดไม่ใช้งาน

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

แอปของคุณจะได้รับการติดต่อกลับไปยัง onStartListening() หลังจากที่ผู้ใช้เปิดแผงการตั้งค่าด่วน คุณสามารถอัปเดตออบเจ็กต์ Tile กี่ครั้งก็ได้ระหว่างวันที่ onStartListening() ถึง onStopListening()

คุณไม่จำเป็นต้องประกาศโหมดที่ไม่ทำงาน เพียงแค่ไม่ต้องเพิ่ม META_DATA_ACTIVE_TILE ลงในไฟล์ Manifest ของแอป

ภาพรวมสถานะการ์ด

หลังจากผู้ใช้เพิ่มการ์ดแล้ว การ์ดจะอยู่ในสถานะใดสถานะหนึ่งต่อไปนี้เสมอ

  • STATE_ACTIVE: บ่งบอกสถานะเปิดหรือเปิดใช้งาน ผู้ใช้จะโต้ตอบกับการ์ดของคุณได้ขณะอยู่ในสถานะนี้

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

  • STATE_INACTIVE: บ่งบอกสถานะปิดหรือหยุดชั่วคราว ผู้ใช้จะโต้ตอบกับการ์ดของคุณได้ขณะอยู่ในสถานะนี้

    หากใช้ตัวอย่างการ์ดแอปฟิตเนสอีกครั้ง การ์ดใน STATE_INACTIVE จะหมายความว่าผู้ใช้ยังไม่ได้เริ่มเซสชันการออกกำลังกาย แต่สามารถเริ่มได้หากต้องการ

  • STATE_UNAVAILABLE: บ่งบอกสถานะไม่พร้อมใช้งานชั่วคราว ผู้ใช้จะโต้ตอบกับการ์ดของคุณไม่ได้ขณะอยู่ในสถานะนี้

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

ระบบจะกำหนดสถานะเริ่มต้นของออบเจ็กต์ Tile เท่านั้น คุณตั้งค่าTile สถานะของออบเจ็กต์ตลอดอายุการใช้งานที่เหลือ

ระบบอาจปรับสีไอคอนและพื้นหลังของการ์ดเพื่อแสดงสถานะของวัตถุ Tile วัตถุ Tile ที่ตั้งค่าเป็น STATE_ACTIVE จะมืดที่สุด ส่วน STATE_INACTIVE และ STATE_UNAVAILABLE จะสว่างขึ้นเรื่อยๆ สีจริงจะขึ้นอยู่กับผู้ผลิตและเวอร์ชันเท่านั้น

ปรับไทล์ VPN ให้แสดงสถานะของออบเจ็กต์
รูปที่ 4 ตัวอย่างไทล์ที่มีการปรับสีให้สอดคล้องกับสถานะของไทล์ (สถานะใช้งานอยู่ ไม่ได้ใช้งาน และใช้งานไม่ได้ ตามลำดับ)

อัปเดตการ์ด

คุณจะอัปเดตการ์ดได้เมื่อได้รับการติดต่อกลับที่ onStartListening() ไทล์จะอัปเดตได้อย่างน้อย 1 ครั้งจนกว่าจะได้รับการติดต่อกลับไปยัง onStopListening() ทั้งนี้ขึ้นอยู่กับโหมดของไทล์

ในโหมดแอ็กทีฟ คุณจะอัปเดตการ์ดได้เพียงครั้งเดียวก่อนที่จะได้รับการเรียกกลับไปยัง onStopListening() ในโหมดไม่ทำงาน คุณสามารถอัปเดตการ์ดได้บ่อยเท่าที่ต้องการระหว่าง onStartListening() ถึง onStopListening()

คุณเรียกข้อมูลออบเจ็กต์ Tile ได้โดยโทรไปที่ getQsTile() หากต้องการอัปเดตช่องที่เฉพาะเจาะจงของออบเจ็กต์ Tile ให้เรียกใช้เมธอดต่อไปนี้

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

Kotlin

data class StateModel(val enabled: Boolean, val label: String, val icon: Icon)

override fun onStartListening() {
  super.onStartListening()
  val state = getStateFromService()
  qsTile.label = state.label
  qsTile.contentDescription = tile.label
  qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
  qsTile.icon = state.icon
  qsTile.updateTile()
}

Java

public class StateModel {
  final boolean enabled;
  final String label;
  final Icon icon;

  public StateModel(boolean e, String l, Icon i) {
    enabled = e;
    label = l;
    icon = i;
  }
}

@Override
public void onStartListening() {
  super.onStartListening();
  StateModel state = getStateFromService();
  Tile tile = getQsTile();
  tile.setLabel(state.label);
  tile.setContentDescription(state.label);
  tile.setState(state.enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
  tile.setIcon(state.icon);
  tile.updateTile();
}

แฮนเดิลการแตะ

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

เมื่อแอปได้รับการติดต่อกลับไปยัง onClick() แอปจะเปิดกล่องโต้ตอบหรือกิจกรรม เรียกให้ทำงานในเบื้องหลัง หรือเปลี่ยนสถานะของการ์ดได้

Kotlin

var clicks = 0
override fun onClick() {
  super.onClick()
  counter++
  qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
  qsTile.label = "Clicked $counter times"
  qsTile.contentDescription = qsTile.label
  qsTile.updateTile()
}

Java

int clicks = 0;

@Override
public void onClick() {
  super.onClick();
  counter++;
  Tile tile = getQsTile();
  tile.setState((counter % 2 == 0) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
  tile.setLabel("Clicked " + counter + " times");
  tile.setContentDescription(tile.getLabel());
  tile.updateTile();
}

เปิดกล่องโต้ตอบ

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

เปิดกิจกรรม

startActivityAndCollapse() เริ่มกิจกรรมขณะยุบแผง กิจกรรมจะมีประโยชน์หากมีข้อมูลที่ละเอียดกว่าที่จะแสดงในกล่องโต้ตอบ หรือหากการดําเนินการของคุณเป็นแบบอินเทอร์แอกทีฟสูง

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

การแตะการ์ดค้างไว้จะเป็นการแสดงหน้าจอข้อมูลแอปแก่ผู้ใช้ หากต้องการลบล้างลักษณะการทำงานนี้และเปิดใช้งานกิจกรรมสำหรับการตั้งค่าค่ากําหนดแทน ให้เพิ่ม <intent-filter> ลงในกิจกรรมใดกิจกรรมหนึ่งที่มี ACTION_QS_TILE_PREFERENCES

ตั้งแต่ Android API 28 เป็นต้นไป PendingIntent ต้องมีIntent.FLAG_ACTIVITY_NEW_TASKต่อไปนี้

if (Build.VERSION.SDK_INT >= 28) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

หรือจะเพิ่ม Flag ใน AndroidManifest.xml ในส่วนที่เฉพาะเจาะจงของ Activityก็ได้

ทำเครื่องหมายการ์ดของคุณว่าเปิด/ปิดได้

เราขอแนะนำให้ทําเครื่องหมายการ์ดเป็น "เปิด/ปิดได้" หากการ์ดทํางานเป็นหลักเป็นสวิตช์แบบ 2 สถานะ (ซึ่งเป็นลักษณะการทํางานของการ์ดที่พบบ่อยที่สุด) ซึ่งช่วยในการระบุข้อมูลเกี่ยวกับลักษณะการทำงานของการ์ดแก่ระบบปฏิบัติการและปรับปรุงการช่วยเหลือพิเศษโดยรวม

ตั้งค่าข้อมูลเมตา TOGGLEABLE_TILE เป็น true เพื่อทําเครื่องหมายการ์ดว่าสลับได้

<service ...>
  <meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
    android:value="true" />
</service>

ดำเนินการที่ปลอดภัยเท่านั้นในอุปกรณ์ที่ล็อกไว้อย่างปลอดภัย

การ์ดอาจแสดงที่ด้านบนของหน้าจอล็อกในอุปกรณ์ที่ล็อกอยู่ หากการ์ดมีข้อมูลที่ละเอียดอ่อน ให้ตรวจสอบค่าของ isSecure() เพื่อดูว่าอุปกรณ์อยู่ในสถานะที่ปลอดภัยหรือไม่ และ TileService ควรเปลี่ยนลักษณะการทํางานตามความเหมาะสม

หากการดำเนินการของการ์ดปลอดภัยที่จะดำเนินการขณะล็อกอยู่ ให้ใช้ startActivity() เพื่อเปิดกิจกรรมที่ด้านบนของหน้าจอล็อก

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

แจ้งให้ผู้ใช้เพิ่มการ์ด

หากต้องการเพิ่มการ์ดด้วยตนเอง ผู้ใช้ต้องทำตามขั้นตอนต่อไปนี้

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

นอกจากนี้ ผู้ใช้ยังย้ายหรือนำการ์ดของคุณออกได้ทุกเมื่อ

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

ข้อความแจ้งของ Quick Settings Placement API
รูปที่ 5 ข้อความแจ้งของ Placement API การตั้งค่าด่วน
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

การเรียกกลับจะมีข้อมูลว่ามีการเพิ่มการ์ดหรือไม่ เพิ่มหรือไม่ มีการเพิ่มการ์ดอยู่แล้ว หรือเกิดข้อผิดพลาดใดๆ ขึ้น

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

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