إنشاء مربّعات مخصّصة للإعدادات السريعة لتطبيقك

"الإعدادات السريعة" هي مربّعات تظهر في لوحة "الإعدادات السريعة". تمثل الإجراءات، التي يمكن للمستخدمين النقر عليها لإكمال المهام المتكررة بسرعة. يمكن أن يوفّر تطبيقك مربّعًا مخصّصًا للمستخدمين من خلال TileService. الفئة واستخدام الكائن Tile لتتبُّع حالة المربّع. على سبيل المثال: يمكنك إنشاء مربّع يتيح للمستخدمين تفعيل شبكة VPN التي يوفّرها تطبيقك.

لوحة "الإعدادات السريعة" مع تفعيل مربّع شبكة VPN
  تفعيل وإيقاف
الشكل 1. لوحة "الإعدادات السريعة" مع تفعيل مربّع شبكة VPN بين التفعيل والإيقاف

تحديد وقت إنشاء مربّع

ننصح بإنشاء مربّعات للوظائف المعيّنة التي تتوقّعها من المستخدمين إما بالوصول بشكل متكرر أو بحاجة إلى وصول سريع (أو كليهما). الأكثر فعالية المربعات هي تلك التي تتطابق مع هاتين الصفتين، مما يوفر وصولاً سريعًا إلى الإجراءات المتكررة.

على سبيل المثال، يمكنك إنشاء مربّع لتطبيق اللياقة البدنية الذي يتيح للمستخدمين لبدء جلسة تمرين بسرعة. مع ذلك، لا ننصح بإنشاء مربّع للتطبيق ذاته والذي يتيح للمستخدمين مراجعة سجل تمارينهم بالكامل.

حالات استخدام مربعات تطبيق اللياقة البدنية
الشكل 2. أمثلة على الفئات المقترَحة مقارنةً بغيرها لتطبيق اللياقة البدنية.

للمساعدة في تحسين قابلية اكتشاف المربّع الخاص بك وسهولة استخدامه، ننصحك مع تجنب بعض الممارسات:

  • تجنَّب استخدام المربّعات لتشغيل تطبيق. استخدم اختصار تطبيق أو معيارًا مشغّل التطبيقات بدلاً من ذلك.

  • تجنَّب استخدام المربّعات لإجراءات المستخدم التي لمرّة واحدة. استخدم اختصار تطبيق أو إشعار بدلاً من ذلك.

  • تجنَّب إنشاء عدد كبير جدًا من المربّعات. ننصحك باستخدام تطبيقَين كحد أقصى لكل تطبيق. يمكنك استخدام اختصار التطبيق بدلاً من ذلك.

  • تجنّب استخدام المربّعات التي تعرض معلومات، ولكنها غير تفاعلية مع المستخدمين. يمكنك استخدام إشعار أو أداة بدلاً من ذلك.

إنشاء مربّعك

لإنشاء مربع، تحتاج أولاً إلى إنشاء رمز مربع مناسب، ثم إنشاء TileService وتوضيحها في ملف البيان لتطبيقك

يقدّم نموذج الإعدادات السريعة مثالاً على كيفية إنشاء المربع وإدارته.

إنشاء الرمز المخصّص

سيكون عليك إضافة رمز مخصّص يظهر على المربّع في القائمة المنسدلة لوحة الإعدادات. (ستضيف هذا الرمز عند الإعلان عن السمة TileService، الموضحة في القسم التالي). يجب أن يكون الرمز بلون أبيض خالص مع خلفية شفافة، وبقياس 24 × 24 بكسل مستقل الكثافة، ويجب أن تكون على شكل VectorDrawable

مثال على متّجه قابل للرسم
الشكل 3. مثال على متّجه قابل للرسم

أنشِئ رمزًا يشير بشكل مرئي إلى الغرض من المربّع. يساعد هذا المستخدمين التعرف بسهولة على ما إذا كان البلاط يناسب احتياجاتهم. على سبيل المثال، يمكنك إنشاء رمز لساعة إيقاف لمربّع لتطبيق اللياقة البدنية الذي يسمح للمستخدمين ببدء جلسة التمارين الرياضية.

إنشاء 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 في ملف البيان لتطبيقك. إضافة الاسم والتصنيف 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 وتعريفها في بيان التطبيق، عليك إجراء ما يلي: إدارة حالتها.

TileService هي خدمة مرتبطة. سيتم ربط TileService عندما يطلبها تطبيقك أو إذا كان النظام بحاجة إلى الاتصال به. نموذج تتضمن دورة حياة الخدمة المرتبطة الطرق الأربع التالية لمعاودة الاتصال: onCreate() وonBind() وonUnbind() و onDestroy(). ويستدعي النظام هذه الطرق في كل مرة الخدمة تدخل مرحلة حياة جديدة.

نظرة عامة على مراحل نشاط TileService

بالإضافة إلى عمليات معاودة الاتصال التي تتحكم في دورة حياة الخدمة المحددة، يجب عليك تنفيذ طرق أخرى خاصة بمراحل نشاط TileService هذه الطرق قد يتم الاتصال خارج onCreate() وonDestroy() بسبب Service يتم استدعاء طرق مراحل النشاط وTileService طرق مراحل النشاط في نوعين سلاسل المحادثات غير المتزامنة المنفصلة.

تتضمن دورة حياة TileService الطرق التالية التي تم استدعاؤها من قِبل النظام في كل مرة يدخل فيها TileService في مرحلة نشاط جديدة:

  • onTileAdded(): لا استدعاء هذه الطريقة إلا عندما يضيف مستخدم المربّع لأول مرة، وإذا أزال المستخدم مربّعك وأضافه مرة أخرى. هذا هو أفضل وقت لإجراء أي عملية إعداد لمرة واحدة. ومع ذلك، قد لا يلبي جميع الإعداد اللازم.

  • onStartListening() وonStopListening(): هذه الطريقتان يتم طلبها عندما يحدِّث التطبيق المربّع، ويتم استدعاؤها كثيرًا. تشير رسالة الأشكال البيانية يظل TileService مسدودًا بين onStartListening() و onStopListening()، يتم السماح لتطبيقك بتعديل المربّع وإرسال التحديثات.

  • onTileRemoved(): لا تُعرف هذه الطريقة إلا إذا أزال المستخدم حسابك مربع.

اختيار وضع الاستماع

يرصد جهاز "TileService" الصوت في وضع النشط أو في الوضع غير نشط. ننصحك بما يلي: باستخدام وضع النشاط، وعليك الإفصاح عنه في بيان التطبيق. وإلا، وضع TileService هو الوضع العادي ولا يلزم الإفصاح عنه.

ولا تفترض أنّ جهاز TileService الخاص بك سيكون خارج نطاق onStartListening(). زوج من الطرق onStopListening().

استخدِم "وضع النشاط" مع جهاز "TileService" الذي يستمع ويراقب حالته في عمليتك الخاصة. هناك TileService في وضع النشاط مرتبطة بـ onTileAdded()، onTileRemoved()، انقر على الأحداث، وعندما تطلب عملية التطبيق.

ننصح باستخدام "وضع النشاط" إذا تم إشعار "TileService" عند حالة المربّع. يجب تحديثه من خلال عمليته الخاصة. تحدّ المربّعات النشطة من الضغط الواقع على النظام لأنها لا تُضطر إلى ربطها في كل مرة تظهر فيها لوحة "الإعدادات السريعة" مرئية للمستخدم.

يمكن استدعاء طريقة TileService.requestListeningState() الثابتة تطلب بدء حالة الاستماع وتتلقى معاودة الاتصال onStartListening()

يمكنك الإعلان عن "وضع النشاط" من خلال إضافة META_DATA_ACTIVE_TILE إلى ملف البيان للتطبيق.

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

وضع غير نشط

الوضع غير النشط هو الوضع العادي. تكون TileService في وضع غير نشط إذا يتم ربطها عندما يظهر للمستخدم مربّعك. وهذا يعني أن قد يتم إنشاء TileService وربطه مجددًا في أوقات خارجة عن سيطرته. أُنشأها جون هنتر، الذي كان متخصصًا كما قد يتم إلغاء ربطها وإتلافها عندما لا يعرض المستخدم المربع.

يتلقّى تطبيقك معاودة الاتصال بالرقم onStartListening() بعد أن يفتح المستخدم لوحة "الإعدادات السريعة" يمكنك تعديل عنصر Tile عدة مرات. تريد بين onStartListening() وonStopListening().

ليس عليك الإعلان عن "وضع عدم النشاط"، ما عليك سوى عدم إضافة META_DATA_ACTIVE_TILE إلى ملف البيان لتطبيقك

نظرة عامة على حالات المربّعات

بعد أن يضيف المستخدم مربّعك، سيكون متوفّرًا دائمًا في إحدى الحالات التالية.

  • 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(). استنادًا إلى وضع المربّع، يمكن تعديل المربّع مرة واحدة على الأقل حتى جارٍ تلقّي معاودة الاتصال بالرقم onStopListening().

في وضع النشاط، يمكنك تحديث مربّعك مرة واحدة بالضبط قبل تلقّي رد الاتصال إلى onStopListening(). في وضع عدم النشاط، يمكنك تعديل المربّع عدة مرات على النحو الذي تريده بين onStartListening() وonStopListening().

يمكنك استرداد كائن Tile من خلال استدعاء getQsTile(). للتحديث حقول معيّنة في كائن Tile، يمكنك استدعاء الطرق التالية:

يجب الاتصال بـ updateTile() لتعديل المربّع بعد الانتهاء من إعداد حقول الكائن Tile إلى القيم الصحيحة. سيجعل ذلك النظام تحليل بيانات المربّعات المعدّلة وتعديل واجهة المستخدم

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

بدءًا من الإصدار 28 من واجهة برمجة تطبيقات Android، على PendingIntent تحتوي على Intent.FLAG_ACTIVITY_NEW_TASK:

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

يمكنك بدلاً من ذلك إضافة العلامة في AndroidManifest.xml ضمن القسم قسم "Activity".

وضع علامة على مربّعك كقابل للتبديل

نقترح عليك وضع علامة على مربّعك كقابل للتبديل إذا كان يعمل بشكل أساسي التبديل بين حالتين (وهو السلوك الأكثر شيوعًا للمربّعات). يساعد ذلك في تقديم معلومات حول سلوك المربع لنظام التشغيل تحسين إمكانية الوصول بشكل عام.

اضبط بيانات 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(). لتسهّل على المستخدمين إضافة مربّعك إلى الجهاز. هذه الطريقة سيطلب من المستخدمين إضافة مربّعك بسرعة إلى الإعدادات السريعة لوحة الإعدادات. تتضمن المطالبة اسم التطبيق والتصنيف المتوفر ورمز القناة.

طلب من واجهة برمجة التطبيقات الخاصة بموضع الإعدادات السريعة
الشكل 5. طلب من واجهة برمجة التطبيقات لموضع الإعلان في الإعدادات السريعة
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

تحتوي معاودة الاتصال على معلومات حول ما إذا تمت إضافة المربّع أم لا، إذا كانت موجودة بالفعل أو حدث أي خطأ.

استنِد إلى تقديرك الخاص عند تحديد وقت ووتيرة إرسال طلبات إلى المستخدمين. أر نقترح الاتصال برقم requestAddTileService() في السياق الصحيح فقط، مثل عندما يتفاعل المستخدم لأول مرة مع إحدى الميزات التي تسهِّلها المربّع.

يمكن أن يختار النظام إيقاف معالجة الطلبات ComponentName إذا تم رفضه من قِبل المستخدم عددًا كافيًا من المرات من قبل. تشير رسالة الأشكال البيانية يتم تحديد المستخدم من خلال Context المستخدَم لاسترداد هذه القيمة خدمة - يجب أن تتطابق مع المستخدم الحالي.