الخطوات الأولى

توضّح لك هذه الصفحة كيفية إعداد بيئتك وإنشاء الشرائح في تطبيقك:

ملاحظة: يحتوي الإصدار 3.2 من "استوديو Android" أو الإصدارات الأحدث على إضافات أدوات ووظائف يمكن أن تساعدك في تطوير "الشرائح":

  • أداة إعادة الهيكلة لنظام AndroidX: مطلوبة إذا كنت تعمل في مشروع يستخدم مكتبات AndroidX.
  • تقسيم عمليات فحص الوبر: لرصد الممارسات المضادة الشائعة عند إنشاء شرائح
  • نموذج SliceProvider: يعالج النص النموذجي عند إنشاء SliceProvider

تنزيل وتثبيت "عارض الشرائح"

تنزيل أحدث عيّنة إصدار APK لعارض الشرائح التي يمكنك استخدامها لاختبار الشرائح بدون تنفيذ SliceView API.

إذا لم يتم إعداد ADB بشكل صحيح في بيئتك، راجع لمزيد من المعلومات، يمكنك الانتقال إلى دليل Ads Data Hub.

ثبِّت عارض الشرائح على جهازك من خلال تنفيذ الأمر التالي في الدليل نفسه مثل slice-viewer.apk الذي تم تنزيله:

adb install -r -t slice-viewer.apk

تشغيل عارض الشرائح

يمكنك تشغيل Slice Viewer إما من مشروعك على "استوديو Android" أو من سطر الأوامر:

تشغيل Slice Viewer من مشروعك على "استوديو Android"

  1. في مشروعك، اختَر تشغيل > تعديل الإعدادات...
  2. في أعلى يمين الصفحة، انقر على علامة الجمع الخضراء.
  3. اختَر تطبيق Android.

  4. أدخِل شريحة في حقل الاسم.

  5. اختَر وحدة التطبيق في القائمة المنسدلة الوحدة.

  6. ضمن خيارات الإطلاق، اختَر عنوان URL من القائمة المنسدلة الإطلاق.

  7. يُرجى إدخال slice-<your slice URI> في حقل عنوان URL.

    مثال: slice-content://com.example.your.sliceuri

  8. انقر على حسنًا.

تشغيل أداة Slice Viewer عبر ADB (سطر الأوامر)

لتشغيل تطبيقك من "استوديو Android":

adb install -t -r <yourapp>.apk

يمكنك عرض شريحتك بتشغيل الأمر التالي:

adb shell am start -a android.intent.action.VIEW -d slice-<your slice URI>

عارِض شرائح يعرض شريحة WiFi واحدة

عرض كل الشرائح في مكان واحد

بالإضافة إلى إطلاق شريحة واحدة، يمكنك عرض قائمة دائمة شرائح.

  • استخدِم شريط البحث للبحث يدويًا عن الشرائح عبر عنوان URI (على سبيل المثال، content://com.example.android.app/hello). في كل مرة تبحث فيها، يتم عرض تمت إضافته إلى القائمة.
  • عندما تقوم بتشغيل أداة Slice Viewer باستخدام معرف موارد منتظم (URI) الخاص بالشريحة، تتم إضافة الشريحة. إلى القائمة.
  • ويمكنك تمرير شريحة لإزالتها من القائمة.
  • انقر على معرّف الموارد المنتظم (URI) الخاص بالقطعة لعرض صفحة تحتوي على تلك الشريحة فقط. تحتوي هذه النتيجة على يكون له نفس تأثير تشغيل Slice Viewer باستخدام معرف موارد منتظم (URI) لشرائح.

عارِض الشرائح يعرض قائمة بالشرائح

عرض الشريحة في أوضاع مختلفة

يمكن لأي تطبيق يقدّم شريحة تعديل SliceView#mode في وقت التشغيل، لذا يجب التأكد من ظهور الشريحة كما هو متوقع في كل وضع. حدد رمز القائمة في الجانب العلوي الأيسر من الصفحة لتغيير الوضع.

عارض تقطيع واحد مع ضبط الوضع على "صغير"

إنشاء أول شريحة لك

لإنشاء شريحة، افتح مشروعك على "استوديو Android" وانقر بزر الماوس الأيمن على src. الحزمة، وحدد جديد... &gt; غير ذلك > ماكينة التقطيع: يؤدي هذا إلى إنشاء فئة يمتد إلى SliceProvider، ويضيف إدخال مقدم الخدمة المطلوب في AndroidManifest.xml وتعديل build.gradle لإضافة تبعيات الشرائح المطلوبة.

يظهر أدناه التعديل الذي تم إجراؤه على AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.app">
    ...
    <application>
        ...
        <provider android:name="MySliceProvider"
            android:authorities="com.example.android.app"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.app.slice.category.SLICE" />
            </intent-filter>
        </provider>
        ...
    </application>

</manifest>

تمت إضافة الموارد التابعة التالية إلى build.gradle:

Kotlin

dependencies {
// ...
    implementation "androidx.slice:slice-builders-ktx:(latest version)"
// ...
}

Java

dependencies {
// ...
    implementation "androidx.slice:slice-builders:(latest version)"
// ...
}

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

في ما يلي مثال على طريقة onBindSlice التي تتحقّق من معرّف الموارد المنتظم (URI) "/hello". وعرض شريحة Hello World:

Kotlin

override fun onBindSlice(sliceUri: Uri): Slice? {
    val activityAction = createActivityAction()
    return if (sliceUri.path == "/hello") {
        list(context, sliceUri, ListBuilder.INFINITY) {
            row {
                primaryAction = activityAction
                title = "Hello World."
            }
        }
    } else {
        list(context, sliceUri, ListBuilder.INFINITY) {
            row {
                primaryAction = activityAction
                title = "URI not recognized."
            }
        }
    }
}

Java

@Override
public Slice onBindSlice(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    SliceAction activityAction = createActivityAction();
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY);
    // Create parent ListBuilder.
    if ("/hello".equals(sliceUri.getPath())) {
        listBuilder.addRow(new ListBuilder.RowBuilder()
                .setTitle("Hello World")
                .setPrimaryAction(activityAction)
        );
    } else {
        listBuilder.addRow(new ListBuilder.RowBuilder()
                .setTitle("URI not recognized")
                .setPrimaryAction(activityAction)
        );
    }
    return listBuilder.build();
}

استخدِم إعداد تشغيل الشريحة الذي أنشأته في قسم "عارض الشرائح". أعلاه، إدخال عنوان URI في Slice (على سبيل المثال، slice-content://com.android.example.slicesample/hello) من Hello World التقطيع لعرضه في عارض الشرائح.

شرائح تفاعلية

كما هي الحال مع الإشعارات، يمكنك التعامل مع النقرات داخل الشريحة من خلال إرفاق PendingIntent من الكائنات تحدث عند تفاعل المستخدم. يبدأ المثال أدناه Activity الذي يمكنه تلقّي هذه الطلبات ومعالجتها الأهداف:

Kotlin

fun createSlice(sliceUri: Uri): Slice {
    val activityAction = createActivityAction()
    return list(context, sliceUri, INFINITY) {
        row {
            title = "Perform action in app"
            primaryAction = activityAction
        }
    }
}

fun createActivityAction(): SliceAction {
    val intent = Intent(context, MainActivity::class.java)
    return SliceAction.create(
        PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), 0),
        IconCompat.createWithResource(context, R.drawable.ic_home),
        ListBuilder.ICON_IMAGE,
        "Enter app"
    )
}

Java

public Slice createSlice(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    SliceAction activityAction = createActivityAction();
    return new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            .addRow(new ListBuilder.RowBuilder()
                    .setTitle("Perform action in app.")
                    .setPrimaryAction(activityAction)
            ).build();
}

public SliceAction createActivityAction() {
    if (getContext() == null) {
        return null;
    }
    return SliceAction.create(
            PendingIntent.getActivity(
                    getContext(),
                    0,
                    new Intent(getContext(), MainActivity.class),
                    0
            ),
            IconCompat.createWithResource(getContext(), R.drawable.ic_home),
            ListBuilder.ICON_IMAGE,
            "Enter app"
    );
}

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

Kotlin

fun createBrightnessSlice(sliceUri: Uri): Slice {
    val toggleAction =
        SliceAction.createToggle(
            createToggleIntent(),
            "Toggle adaptive brightness",
            true
        )
    return list(context, sliceUri, ListBuilder.INFINITY) {
        row {
            title = "Adaptive brightness"
            subtitle = "Optimizes brightness for available light"
            primaryAction = toggleAction
        }
        inputRange {
            inputAction = (brightnessPendingIntent)
            max = 100
            value = 45
        }
    }
}

fun createToggleIntent(): PendingIntent {
    val intent = Intent(context, MyBroadcastReceiver::class.java)
    return PendingIntent.getBroadcast(context, 0, intent, 0)
}

Java

public Slice createBrightnessSlice(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    SliceAction toggleAction = SliceAction.createToggle(
            createToggleIntent(),
            "Toggle adaptive brightness",
            true
    );
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            .addRow(new ListBuilder.RowBuilder()
                    .setTitle("Adaptive brightness")
                    .setSubtitle("Optimizes brightness for available light.")
                    .setPrimaryAction(toggleAction)
            ).addInputRange(new ListBuilder.InputRangeBuilder()
                    .setInputAction(brightnessPendingIntent)
                    .setMax(100)
                    .setValue(45)
            );
    return listBuilder.build();
}

public PendingIntent createToggleIntent() {
    Intent intent = new Intent(getContext(), MyBroadcastReceiver.class);
    return PendingIntent.getBroadcast(getContext(), 0, intent, 0);
}

يمكن للمُستلِم عندها التحقّق من الحالة التي يتلقّاها:

Kotlin

class MyBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.hasExtra(Slice.EXTRA_TOGGLE_STATE)) {
            Toast.makeText(context, "Toggled:  " + intent.getBooleanExtra(
                    Slice.EXTRA_TOGGLE_STATE, false),
                    Toast.LENGTH_LONG).show()
        }
    }

    companion object {
        const val EXTRA_MESSAGE = "message"
    }
}

Java

public class MyBroadcastReceiver extends BroadcastReceiver {

    public static String EXTRA_MESSAGE = "message";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.hasExtra(EXTRA_TOGGLE_STATE)) {
            Toast.makeText(context, "Toggled:  " + intent.getBooleanExtra(
                    EXTRA_TOGGLE_STATE, false),
                    Toast.LENGTH_LONG).show();
        }
    }
}

شرائح ديناميكية

يمكن أن تتضمّن الشرائح أيضًا محتوى ديناميكيًا. في المثال التالي، الشريحة الآن يشمل عدد عمليات البث المستلمة في محتواه:

Kotlin

fun createDynamicSlice(sliceUri: Uri): Slice {
    return when (sliceUri.path) {
        "/count" -> {
            val toastAndIncrementAction = SliceAction.create(
                createToastAndIncrementIntent("Item clicked."),
                actionIcon,
                ListBuilder.ICON_IMAGE,
                "Increment."
            )
            list(context, sliceUri, ListBuilder.INFINITY) {
                row {
                    primaryAction = toastAndIncrementAction
                    title = "Count: ${MyBroadcastReceiver.receivedCount}"
                    subtitle = "Click me"
                }
            }
        }

        else -> {
            list(context, sliceUri, ListBuilder.INFINITY) {
                row {
                    primaryAction = createActivityAction()
                    title = "URI not found."
                }
            }
        }
    }
}

Java

public Slice createDynamicSlice(Uri sliceUri) {
    if (getContext() == null || sliceUri.getPath() == null) {
        return null;
    }
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY);
    switch (sliceUri.getPath()) {
        case "/count":
            SliceAction toastAndIncrementAction = SliceAction.create(
                    createToastAndIncrementIntent("Item clicked."),
                    actionIcon,
                    ListBuilder.ICON_IMAGE,
                    "Increment."
            );
            listBuilder.addRow(
                    new ListBuilder.RowBuilder()
                            .setPrimaryAction(toastAndIncrementAction)
                            .setTitle("Count: " + MyBroadcastReceiver.sReceivedCount)
                            .setSubtitle("Click me")
            );
            break;
        default:
            listBuilder.addRow(
                    new ListBuilder.RowBuilder()
                            .setPrimaryAction(createActivityAction())
                            .setTitle("URI not found.")
            );
            break;
    }
    return listBuilder.build();
}

public PendingIntent createToastAndIncrementIntent(String s) {
    Intent intent = new Intent(getContext(), MyBroadcastReceiver.class)
            .putExtra(MyBroadcastReceiver.EXTRA_MESSAGE, s);
    return PendingIntent.getBroadcast(getContext(), 0, intent, 0);
}

في هذا المثال، بينما يظهر العدد، لا يتم تعديله من تلقاء نفسه. يمكنك تعديل جهاز استقبال البث لإعلام النظام بحدوث تغيير باستخدام ContentResolver#notifyChange

Kotlin

class MyBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.hasExtra(Slice.EXTRA_TOGGLE_STATE)) {
            Toast.makeText(
                context, "Toggled:  " + intent.getBooleanExtra(
                    Slice.EXTRA_TOGGLE_STATE, false
                ),
                Toast.LENGTH_LONG
            ).show()
            receivedCount++;
            context.contentResolver.notifyChange(sliceUri, null)
        }
    }

    companion object {
        var receivedCount = 0
        val sliceUri = Uri.parse("content://com.android.example.slicesample/count")
        const val EXTRA_MESSAGE = "message"
    }
}

Java

public class MyBroadcastReceiver extends BroadcastReceiver {

    public static int sReceivedCount = 0;
    public static String EXTRA_MESSAGE = "message";

    private static Uri sliceUri = Uri.parse("content://com.android.example.slicesample/count");

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.hasExtra(EXTRA_TOGGLE_STATE)) {
            Toast.makeText(context, "Toggled:  " + intent.getBooleanExtra(
                    EXTRA_TOGGLE_STATE, false),
                    Toast.LENGTH_LONG).show();
            sReceivedCount++;
            context.getContentResolver().notifyChange(sliceUri, null);
        }
    }
}

النماذج

تتيح الشرائح استخدام مجموعة متنوعة من النماذج. لمزيد من التفاصيل حول خيارات النماذج وسلوكيات المستخدمين، يُرجى مراجعة النماذج.