وارد کردن و صادر کردن داده‌های صفحه اصلی

داده‌های صفحه اصلی اندروید توسط کلاس LauncherProvider ارائه می‌شوند که ContentProvider ارث‌بری می‌کند و امکان ایمپورت و اکسپورت داده‌های فضای کاری Launcher را با استفاده از XML فراهم می‌کند.

تعامل با ارائه دهنده محتوا

برای تعامل با کلاس LaunchProvider که از ContentProvider ارث‌بری می‌کند، از متد call استفاده کنید:

class LauncherProvider : ContentProvider {
    public Bundle call(String method, String arg, Bundle extras);
}

کلاس LaunchProvider را فراخوانی کنید

برای فراخوانی کلاس LauncherProvider از برنامه خود، از کد زیر استفاده کنید:

class YourClass {

    /**
     * This method imports Launcher workspace data as a XML string. Calling this method clears the old
     * data model within Launcher and replaces it with the imported data. It should be noted
     * that it doesn't need to clear all the Launcher's data, just what is similar to what is being imported.
     */
    fun importLauncherData(xmlRepresentation: String, ctx: Context): Boolean {
        val uri = try {
            getLauncherProviderUri(ctx)
        } catch (e: IllegalStateException) {
            Log.e(TAG, "Failed to get launcher provider URI", e)
            return false
        }
        val bundle = ctx.contentResolver.call(
            uri,
            LauncherProviderConstants.METHOD_IMPORT_LAYOUT_XML,
            xmlRepresentation,
            null,
        )
        return LauncherProviderConstants.SUCCESS
            .equals(bundle.getBoolean(LauncherProviderConstants.KEY_RESULT))
    }

    /**
     * Use this function to retrieve an XML string representation of the Launcher's Workspace.
     * This method doesn't return what the user sees on their home screen,
     * but rather what is in their data model at the moment it's called.
     */
    fun exportLauncherData(xmlRepresentation: String, ctx: Context): String {
        val uri = try {
            getLauncherProviderUri(ctx)
        } catch (e: IllegalStateException) {
            Log.e(TAG, "Failed to get launcher provider URI", e)
            return ""
        }
        val bundle = ctx.contentResolver.call(
            uri,
            LauncherProviderConstants.METHOD_EXPORT_LAYOUT_XML,
            null,
            null,
        )
        if (LauncherProviderConstants.FAILURE
            .equals(bundle.getBoolean(LauncherProviderConstants.KEY_RESULT))) {
            Log.e(TAG, "failed to export launcher data; review previous logs for the cause.")
        }
        return bundle.getString(LauncherProviderConstants.KEY_LAYOUT, "")
    }

    /**
     * Returns a Uri for interacting with Launcher's ContentProvider.
     *
     * Not all Launchers implement this api. This method throws an IllegalStateException
     * if the Launcher doesn't support it.
     */
    private fun getLauncherProviderUri(ctx: Context): Uri {
        val homeIntent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
        val launcherPackage: String =
            ctx.packageManager
                .resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY)
                ?.activityInfo
                ?.packageName ?: throw IllegalStateException("No launcher package found")
        val authority = "${launcherPackage}.settings"
        ctx.packageManager.resolveContentProvider(authority, 0)
            ?: throw IllegalStateException(
                "Launcher package '$launcherPackage' does not support LauncherProvider",
            )
        return "content://$authority".toUri()
    }
}

پارامترها

این ثابت‌ها در متد فراخوانی استفاده می‌شوند:

object LauncherProviderConstants {

    // Valid arg parameters for export and import operations
    private static final String METHOD_EXPORT_LAYOUT_XML = "EXPORT_LAYOUT_XML";
    private static final String METHOD_IMPORT_LAYOUT_XML = "IMPORT_LAYOUT_XML";

    // Bundle key and value set for determining if operation completed successfully or not
    private static final String KEY_RESULT = "KEY_RESULT";
    private static final String SUCCESS = "success";
    private static final String FAILURE = "failure";

    // Bundle key used to store exported XML-string representation of Launcher's workspace layout
    // and item metadata
    private static final String KEY_LAYOUT = "KEY_LAYOUT";
}

از ثابت‌های LauncherProvider با محدودیت‌های زیر استفاده کنید:

  • از متد contentResolver.call به همراه پارامتر متد EXPORT_LAYOUT_XML برای خروجی گرفتن از فضای کاری لانچر به فرمت XML استفاده کنید.
  • در حین خروجی گرفتن، نمایش XML در بسته‌ی برگردانده شده با استفاده از کلید KEY_LAYOUT قابل دسترسی است.
  • از متد contentResolver.call به همراه پارامتر متد IMPORT_LAYOUT_XML برای وارد کردن یک نمایش XML از فضای کاری لانچر استفاده کنید.
  • در حین وارد کردن، نمایش XML به عنوان پارامتر arg متد فراخوانی ارائه می‌شود.
  • برای فراخوانی‌های API مربوط به هر دو مورد export و import، تکمیل موفقیت‌آمیز عملیات انتخاب‌شده، success برمی‌گرداند و عملیات‌های قطع‌شده یا ناموفق، failure برمی‌گردانند.
  • مقدار success یا failure با استفاده از کلید KEY_RESULT در بسته‌ی بازگشتی قابل بازیابی است.

برای مثال، به فراخوانی کلاس LaunchProvider مراجعه کنید.

نمایش XML

برای ساختار XML در هنگام ایمپورت و اکسپورت از راهنماهای زیر استفاده کنید.

  • برنامه فضای کاری:

    <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <workspace rows="4" columns="5">
      <autoinstall container="desktop" x="1" y="1" screen="0" className="com.android.launcher3.tests.Activity2" packageName="com.google.android.apps.nexuslauncher" />
    </workspace>
    
  • اپلیکیشن هات‌سیت:

    <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <workspace>
      <autoinstall container="hotseat" rank="0" className="com.android.launcher3.tests.Activity2" packageName="com.google.android.apps.nexuslauncher" />
    </workspace>
    
  • ویجت:

    <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <workspace>
      <appwidget container="desktop" spanX="2" spanY="2" x="0" y="1" screen="0" className="PlaceholderWidget" packageName="com.test.pending" />
    </workspace>
    
  • پوشه:

    <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <workspace>
      <folder container="desktop" x="1" y="1" screen="1" titleText="CustomFolder">
        <autoinstall className="com.android.launcher3.tests.Activity1" packageName="com.google.android.apps.nexuslauncher" />
        <autoinstall className="com.android.launcher3.tests.Activity2" packageName="com.google.android.apps.nexuslauncher" />
        <autoinstall className="com.android.launcher3.tests.Activity3" packageName="com.google.android.apps.nexuslauncher" />
      </folder>
    </workspace>
    
  • میانبر عمیق:

    <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <workspace>
      <shortcut shortcutId="shortcut2" packageName="com.google.android.apps.nexuslauncher.tests" />
    </workspace>
    
  • جفت برنامه:

    <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <workspace>
      <apppair container="desktop" x="1" y="1" screen="1" titleText="CustomFolder">
        <autoinstall className="com.android.launcher3.tests.Activity1" packageName="com.google.android.apps.nexuslauncher" />
        <autoinstall className="com.android.launcher3.tests.Activity2" packageName="com.google.android.apps.nexuslauncher" />
      </apppair>
    </workspace>
    

فرضیات رفتاری

موارد زیر فرضیات رفتاری برای کلاس LaunchProvider هستند.

  • روش‌ها اتمیک و مسدودکننده هستند.
  • داده‌های مشابه در لانچر هنگام وارد کردن، رونویسی می‌شوند و فقط داده‌های تازه وارد شده باقی می‌مانند.
  • داده‌های وارد شده بلافاصله قابل دسترسی هستند؛ خروجی گرفتن بلافاصله پس از وارد کردن، داده‌های جدید را برمی‌گرداند.