شروع کردن

این صفحه به شما نشان می دهد که چگونه محیط خود را راه اندازی کنید و Slices را در برنامه خود بسازید.

توجه : Android Studio نسخه 3.2 یا بالاتر حاوی ابزارها و عملکردهای اضافی است که می تواند در توسعه Slice به شما کمک کند:

  • ابزار بازسازی AndroidX: اگر در پروژه‌ای کار می‌کنید که از کتابخانه‌های AndroidX استفاده می‌کند، لازم است.
  • بررسی‌های پرز را برش می‌دهد: در هنگام ساختن Slices، اقدامات ضد رایج را می‌گیرد
  • الگوی SliceProvider : هنگام ساخت یک SliceProvider ، دیگ بخار را کنترل می کند

Slice Viewer را دانلود و نصب کنید

آخرین نمونه نسخه APK Slice Viewer را دانلود کنید که می توانید از آن برای آزمایش Slice خود بدون اجرای SliceView API استفاده کنید.

اگر ADB در محیط شما به درستی تنظیم نشده است، برای اطلاعات بیشتر به راهنمای ADB مراجعه کنید.

با اجرای دستور زیر در همان فهرستی که slice-viewer.apk دانلود شده است، Slice Viewer را روی دستگاه خود نصب کنید:

adb install -r -t slice-viewer.apk

Slice Viewer را اجرا کنید

می توانید Slice Viewer را از پروژه Android Studio خود یا از خط فرمان راه اندازی کنید:

Slice Viewer را از پروژه Android Studio خود راه اندازی کنید

  1. در پروژه خود، Run > Edit Configurations را انتخاب کنید...
  2. در گوشه بالا سمت چپ، روی علامت سبز سبز کلیک کنید
  3. برنامه اندروید را انتخاب کنید

  4. برش را در قسمت نام وارد کنید

  5. ماژول برنامه خود را در منوی کشویی Module انتخاب کنید

  6. در قسمت گزینه های راه اندازی ، URL را از منوی کرکره راه اندازی انتخاب کنید

  7. slice-<your slice URI> را در قسمت URL وارد کنید

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

  8. روی OK کلیک کنید

ابزار Slice Viewer را از طریق ADB (خط فرمان) راه اندازی کنید

برنامه خود را از Android Studio اجرا کنید:

adb install -t -r <yourapp>.apk

Slice خود را با اجرای دستور زیر مشاهده کنید:

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

نمایشگر Slice که یک برش WiFi را نشان می دهد

همه برش های خود را در یک مکان مشاهده کنید

علاوه بر راه‌اندازی یک Slice، می‌توانید فهرستی دائمی از Slice خود را مشاهده کنید.

  • از نوار جستجو برای جستجوی دستی Slices خود از طریق URI استفاده کنید (برای مثال content://com.example.android.app/hello ). هر بار که جستجو می کنید، Slice به لیست اضافه می شود.
  • هر زمان که ابزار Slice Viewer را با یک Slice URI راه اندازی می کنید، Slice به لیست اضافه می شود.
  • می توانید یک Slice را بکشید تا آن را از لیست حذف کنید.
  • روی URI Slice ضربه بزنید تا صفحه ای را ببینید که فقط شامل آن Slice است. این همان تأثیر راه‌اندازی Slice Viewer با Slice URI را دارد.

Slice Viewer لیستی از Slices را نشان می دهد

Slice را در حالت های مختلف مشاهده کنید

برنامه‌ای که Slice ارائه می‌کند می‌تواند SliceView#mode در زمان اجرا تغییر دهد، بنابراین باید مطمئن شوید که Slice شما در هر حالت همانطور که انتظار می‌رود به نظر برسد. برای تغییر حالت، نماد منو را در قسمت سمت راست بالای صفحه انتخاب کنید.

نمایشگر تک تکه با حالت تنظیم شده روی "کوچک"

اولین Slice خود را بسازید

برای ساختن یک Slice، پروژه Android Studio خود را باز کنید، روی بسته src خود کلیک راست کرده و New... > Other > Slice Provider را انتخاب کنید. این یک کلاس ایجاد می کند که SliceProvider را گسترش می دهد، ورودی ارائه دهنده مورد نیاز را به AndroidManifest.xml شما اضافه می کند، و build.gradle شما را تغییر می دهد تا وابستگی های Slice مورد نیاز را اضافه کند.

اصلاح 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 شما اضافه می شوند:

کاتلین

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

جاوا

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

هر Slice یک URI مرتبط دارد. هنگامی که سطحی می خواهد یک Slice را نمایش دهد، با این URI یک درخواست الزام آور برای برنامه شما ارسال می کند. سپس برنامه شما این درخواست را انجام می دهد و به صورت پویا Slice را از طریق روش onBindSlice می سازد. سپس سطح می تواند در صورت لزوم Slice را نمایش دهد.

در زیر نمونه‌ای از روش onBindSlice است که مسیر /hello URI را بررسی می‌کند و یک Hello World Slice را برمی‌گرداند:

کاتلین

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."
            }
        }
    }
}

جاوا

@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();
}

از پیکربندی اجرای slice که در بخش Slice Viewer در بالا ایجاد کردید، استفاده کنید و URI Slice خود (به عنوان مثال slice-content://com.android.example.slicesample/hello ) Hello World Slice را ارسال کنید تا آن را در قسمت مشاهده کنید. نمایشگر برش.

برش های تعاملی

مشابه اعلان‌ها، می‌توانید با پیوست کردن اشیاء PendingIntent که در تعامل کاربر ایجاد می‌شوند، کلیک‌های درون Slice خود را مدیریت کنید. مثال زیر یک Activity را شروع می کند که می تواند آن مقاصد را دریافت و مدیریت کند:

کاتلین

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"
    )
}

جاوا

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"
    );
}

برش‌ها همچنین از انواع ورودی‌های دیگر مانند ضامن‌ها پشتیبانی می‌کنند که شامل حالت در قصد ارسال شده به برنامه می‌شود.

کاتلین

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)
}

جاوا

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);
}

سپس گیرنده می تواند وضعیت دریافتی خود را بررسی کند:

کاتلین

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"
    }
}

جاوا

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();
        }
    }
}

برش های پویا

برش ها همچنین می توانند حاوی محتوای پویا باشند. در مثال زیر، Slice اکنون شامل تعداد پخش‌های دریافتی در محتوای خود می‌شود:

کاتلین

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."
                }
            }
        }
    }
}

جاوا

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 به سیستم اطلاع دهد که تغییری رخ داده است.

کاتلین

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"
    }
}

جاوا

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);
        }
    }
}

قالب ها

Slices از قالب های مختلفی پشتیبانی می کند. برای جزئیات بیشتر در مورد گزینه ها و رفتارهای الگو، به الگوها مراجعه کنید.