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

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

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

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

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

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

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

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

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

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

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

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

สร้างการ์ด

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

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

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

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

ตัวอย่าง Vector Drawable
ภาพที่ 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 จะได้รับการเชื่อมโยงเมื่อแอปของคุณขอหรือเมื่อระบบต้องสื่อสารกับ 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 ข้อความแจ้ง API ตำแหน่งโฆษณาของการตั้งค่าด่วน
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

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

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

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