Play ویژه هوش مصنوعی درون‌دستگاهی (نسخه بتا)

مقدمه

‫Play for On-device AI مزایای Android App Bundles و توزیع Google Play را به توزیع مدل یادگیری ماشین سفارشی می‌آورد تا بتوانید عملکرد مدل را با پیچیدگی کمتر بوم‌سازگان دستگاه و بدون هزینه اضافی بهبود دهید. این ویژگی به شما امکان می‌دهد یک آرتیفکت واحد حاوی کد، دارایی‌ها، و مدل‌های یادگیری ماشین خود را در Play منتشر کنید و از بین چندین حالت توزیع و گزینه هدف‌یابی انتخاب کنید.

مزايا

  • یک آرتیفکت انتشار را در Google Play بارگذاری کنید و میزبانی، ارائه، به‌روزرسانی، و هدف‌یابی را بدون هزینه اضافی به Play واگذار کنید.
  • مدل‌های یادگیری ماشین خود را در زمان نصب، تحویل سریع، یا به‌درخواست ارائه دهید.
    • ارائه در زمان نصب می‌تواند تضمین کند که مدل بسیار بزرگی هنگام باز شدن برنامه شما وجود دارد. مدلتان به‌عنوان APK نصب خواهد شد.
    • تحویل سریع به‌طور خودکار در پس‌زمینه پس‌از نصب برنامه‌تان انجام می‌شود. ممکن است کاربران قبل‌از اینکه مدل شما به‌طور کامل بارگیری شود، برنامه‌تان را باز کنند. مدل شما در فضای ذخیره‌سازی داخلی برنامه‌تان بارگیری خواهد شد.
    • تحویل به‌درخواست به شما امکان می‌دهد مدل را در زمان اجرا درخواست کنید، که اگر مدل فقط برای جریان‌های کاربری خاصی موردنیاز باشد مفید است. مدل شما در فضای ذخیره‌سازی داخلی برنامه‌تان بارگیری خواهد شد.
  • متغیرهای مدل‌های یادگیری ماشین خود را که برای دستگاه‌های خاصی هدف‌یابی شده‌اند براساس مدل دستگاه، ویژگی‌های سیستم، یا RAM ارائه دهید.
  • با وصله کردن خودکار Play، به‌روزرسانی‌های برنامه را کوچک و بهینه‌سازی‌شده نگه دارید. این یعنی فقط تفاوت‌های فایل‌ها باید بارگیری شود.

ملاحظات

  • بااستفاده از Play for On-device AI، با شرایط مندرج در قرارداد توزیع توسعه‌دهندگان در Google Play و شرایط خدمات کیت توسعه نرم‌افزار Play Core موافقت می‌کنید.
  • مدل‌های بارگیری‌شده توسط Play برای «هوش مصنوعی درون‌دستگاهی» باید فقط توسط برنامه‌های شما استفاده شوند. مدل‌ها نباید به برنامه‌های دیگر ارائه شوند.
  • بسته‌های هوش مصنوعی تکی می‌توانند براساس اندازه بارگیری فشرده‌شان تا ۱٫۵ گیگابایت باشند. حداکثر اندازه تجمعی برنامه برای هر نسخه‌ای از برنامه‌تان که از دسته برنامه شما تولید شده باشد ۴ گیگابایت است.
  • برنامه‌هایی که اندازه آن‌ها بیش‌از ۱ گیگابایت است باید حداقل سطح کیت توسعه نرم‌افزار را روی ۲۱ یا بالاتر تنظیم کنند.

نحوه استفاده از Play ویژه هوش مصنوعی درون‌دستگاهی

Play ویژه هوش مصنوعی درون‌دستگاهی از بسته‌های هوش مصنوعی استفاده می‌کند. مدل‌های سفارشی را که آماده توزیع هستند در بسته‌های هوش مصنوعی در بسته برنامه‌تان بسته‌بندی می‌کنید. می‌توانید انتخاب کنید که بسته هوش مصنوعی در زمان نصب، تحویل سریع، یا به‌درخواست ارائه شود.

با بسته‌بندی کردن بسته‌های هوش مصنوعی با دسته برنامه‌تان، می‌توانید از همه ابزارهای آزمایش و انتشار موجود در Play، مانند دسته‌های هدف آزمایشی و عرضه گام‌به‌گام، برای مدیریت توزیع برنامه‌تان با مدل‌های سفارشی استفاده کنید.

بسته‌های هوش مصنوعی همراه با باینری برنامه به‌روز می‌شوند. اگر نسخه جدید برنامه‌تان تغییری در بسته هوش مصنوعی ایجاد نکند، فرایند وصله خودکار Play تضمین می‌کند که کاربر نیازی به بارگیری مجدد آن نداشته باشد. Play هنگام به‌روزرسانی برنامه، فقط تغییرات را بارگیری می‌کند.

بسته‌های هوش مصنوعی فقط حاوی مدل هستند. Java/Kotlin و کتابخانه‌های بومی مجاز نیستند. اگر لازم است کتابخانه‌ها یا کد را برای اجرای مدل یادگیری ماشین خود ارسال کنید، آن را به واحد پایه یا واحد ویژگی منتقل کنید. می‌توانید پیمانه ویژگی‌تان را به‌گونه‌ای پیکربندی کنید که تنظیمات بارگیری و هدف‌یابی آن با بسته هوش مصنوعی یکسان باشد.

استفاده از LiteRT و MediaPipe با بسته‌های هوش مصنوعی

می‌توانید از LiteRT و MediaPipe با بسته‌های هوش مصنوعی استفاده کنید. مدلتان را در یک بسته هوش مصنوعی بسته‌بندی کنید و سپس بااستفاده از دستورالعمل‌های بسته‌های زمان نصب یا بسته‌های تحویل سریع و درخواستی به آن دسترسی پیدا کنید.

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

شروع به کار با بسته‌های هوش مصنوعی

در سطح بالا، در اینجا نحوه شروع استفاده از Play ویژه هوش مصنوعی درون‌دستگاهی آورده شده است:

  1. مدل‌هایتان را در بسته‌های هوش مصنوعی در «دسته برنامه Android» خود بسته‌بندی کنید و مشخص کنید بسته‌های هوش مصنوعی چگونه باید ارائه شوند.
  2. [اختیاری] اگر می‌خواهید مدل‌های مختلفی را به دستگاه‌های مختلف ارائه دهید، می‌توانید هدف‌یابی دستگاه را برای بسته‌های هوش مصنوعی خود پیکربندی کنید. برای مثال، می‌توانید بسته هوش مصنوعی «الف» را به مدل دستگاه خاصی، بسته هوش مصنوعی «ب» را به دستگاه‌هایی با حداقل ۶ گیگابایت حافظه دسترسی تصادفی، و هیچ مدلی را به سایر دستگاه‌ها ارائه نکنید.
  3. [اختیاری] اگر از تحویل درخواستی یا تحویل سریع استفاده می‌کنید، «کتابخانه Play AI Delivery» را در برنامه‌تان ادغام کنید تا بسته‌های هوش مصنوعی را درصورت نیاز بارگیری کنید.
  4. دسته برنامه‌تان را آزمایش و در Google Play منتشر کنید.

بررسی نسخه افزایه Android Gradle

برای استفاده از بسته‌های هوش مصنوعی، مطمئن شوید که نسخه «افزایه Android Gradle» (AGP) شما حداقل ۸.۸ باشد. این نسخه با Android Studio Ladybug 2 بسته‌بندی شده است.

مدلتان را در بسته هوش مصنوعی استخراج کنید

برای مراحل زیر، Android Studio لازم نیست.

  1. در دایرکتوری سطح بالای پروژه‌تان، دایرکتوری‌ای برای بسته هوش مصنوعی ایجاد کنید. این نام دایرکتوری به‌عنوان نام بسته هوش مصنوعی استفاده می‌شود. نام بسته هوش مصنوعی باید با حرف شروع شود و فقط می‌تواند حاوی حروف، اعداد، و زیرخط باشد.
  2. در فهرست راهنمای بسته هوش مصنوعی، فایل build.gradle ایجاد کنید و کد زیر را اضافه کنید. حتماً نام بسته هوش مصنوعی و فقط یک نوع تحویل را مشخص کنید:

    // In the AI pack's build.gradle file:
    plugins {
      id 'com.android.ai-pack'
    }
    
    aiPack {
        packName = "ai-pack-name" // Directory name for the AI pack
        dynamicDelivery {
            deliveryType = "[ install-time | fast-follow | on-demand ]"
        }
    }
    
  3. در فایل برنامه build.gradle پروژه، نام هر بسته هوش مصنوعی را در پروژه خود اضافه کنید، همان‌طور که در زیر نشان داده شده است:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":ai-pack-name", ":ai-pack2-name"]
    }
    
  4. در فایل settings.gradle پروژه، همه بسته‌های هوش مصنوعی را در پروژه‌تان به‌صورت زیر اضافه کنید:

    // In the settings.gradle file:
    include ':app'
    include ':ai-pack-name'
    include ':ai-pack2-name'
    
  5. در بسته هوش مصنوعی، دایرکتوری src/main/assets/ را ایجاد کنید.

  6. مدل‌هایتان را در فهرست راهنمای src/main/assets قرار دهید. در اینجا می‌توانید زیرفهرست راهنما هم ایجاد کنید. ساختار فهرست راهنمای برنامه‌تان باید اکنون شبیه به موارد زیر باشد:

    • build.gradle
    • settings.gradle
    • app/
    • ai-pack-name/build.gradle
    • ai-pack-name/src/main/assets/your-model-directories
  7. برای بار کردن و اجرای مدل‌هایتان، کد اضافه کنید. نحوه انجام این کار به حالت تحویل بسته‌های هوش مصنوعی شما بستگی دارد. دستورالعمل‌های مربوط به زمان نصب و تحویل سریع/درخواست‌محور را در زیر ببینید.

  8. [اختیاری] هدف‌یابی دستگاه را پیکربندی کنید تا مدل‌های مختلف را به دستگاه‌های مختلف ارسال کنید.

  9. ساختن «دسته برنامه Android» با Gradle. در دسته برنامه تولیدشده، دایرکتوری سطح ریشه اکنون شامل موارد زیر است:

    • ‫ai-pack-name/manifest/AndroidManifest.xml: شناسه و حالت ارسال بسته هوش مصنوعی را پیکربندی می‌کند
    • ai-pack-name/assets/your-model-directories: دایرکتوری‌ای که حاوی همه دارایی‌های ارائه‌شده به‌عنوان بخشی از بسته هوش مصنوعی است

    Gradle مانیفست را برای هر بسته هوش مصنوعی تولید می‌کند و دایرکتوری assets/ را برای شما خروجی می‌دهد.

پیکربندی تحویل در زمان نصب

بسته‌های هوش مصنوعی که به‌عنوان زمان نصب پیکربندی شده‌اند، بلافاصله پس‌از راه‌اندازی برنامه دردسترس قرار می‌گیرند. از Java AssetManager API برای دسترسی به بسته‌های هوش مصنوعی ارائه‌شده در این حالت استفاده کنید:

import android.content.res.AssetManager;
...
Context context = createPackageContext("com.example.app", 0);
AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open("model-name");

پیکربندی تحویل سریع و تحویل به‌درخواست

برای بارگیری بسته‌های هوش مصنوعی با تحویل سریع یا تحویل درخواستی، از Play AI Delivery Library استفاده کنید.

اعلام وابستگی به «کتابخانه ارائه هوش مصنوعی Play»

در فایل build.gradle برنامه‌تان، وابستگی به Play AI Delivery Library را اعلام کنید:

dependencies {
  ...
  implementation "com.google.android.play:ai-delivery:0.1.1-alpha01"
}

بررسی وضعیت

هر بسته هوش مصنوعی در پوشه‌ای جداگانه در حافظه داخلی برنامه ذخیره می‌شود. از روش getPackLocation() برای تعیین پوشه ریشه بسته هوش مصنوعی استفاده کنید. این روش مقادیر زیر را برمی‌گرداند:

برگرداندن مقدار وضعیت
شیء AiPackLocation معتبر پوشه ریشه بسته هوش مصنوعی برای دسترسی فوری در assetsPath() آماده است
null بسته هوش مصنوعی ناشناخته است یا بسته‌های هوش مصنوعی دردسترس نیستند

دریافت اطلاعات بارگیری درباره بسته‌های هوش مصنوعی

از روش
getPackStates() برای تعیین اندازه بارگیری و اینکه آیا بسته درحال بارگیری است یا نه استفاده کنید.

Task<AiPackStates> getPackStates(List<String> packNames)

‫getPackStates() روشی غیرهم‌زمان است که Task<AiPackStates> را برمی‌گرداند. روش packStates() شیء AiPackStates، Map<String, AiPackState> را برمی‌گرداند. این نقشه حاوی وضعیت هر بسته هوش مصنوعی درخواست‌شده است که با نام آن کلیدگذاری شده است:

Map<String, AiPackState> AiPackStates#packStates()

درخواست نهایی به‌صورت زیر نشان داده می‌شود:

final String aiPackName = "myAiPackName";

aiPackManager
    .getPackStates(Collections.singletonList(aiPackName))
    .addOnCompleteListener(new OnCompleteListener<AiPackStates>() {
        @Override
        public void onComplete(Task<AiPackStates> task) {
            AiPackStates aiPackStates;
            try {
                aiPackStates = task.getResult();
                AiPackState aiPackState =
                    aiPackStates.packStates().get(aiPackName);
            } catch (RuntimeExecutionException e) {
                Log.d("MainActivity", e.getMessage());
                return;
            });

روش‌های زیر AiPackState اندازه بسته هوش مصنوعی، مقدار بارگیری‌شده تاکنون (درصورت درخواست)، و مقدار منتقل‌شده به برنامه را ارائه می‌دهند:

برای دریافت وضعیت بسته هوش مصنوعی، از روش status() استفاده کنید که وضعیت را به‌صورت عدد صحیحی برمی‌گرداند که با فیلد ثابتی در کلاس AiPackStatus مطابقت دارد. بسته هوش مصنوعی که هنوز نصب نشده است وضعیت AiPackStatus.NOT_INSTALLED دارد.

اگر درخواستی ناموفق بود، از روش errorCode() استفاده کنید که مقدار برگشتی آن با فیلد ثابتی در کلاس AiPackErrorCode مطابقت دارد.

نصب

از روش fetch() برای بارگیری بسته هوش مصنوعی برای اولین‌بار یا درخواست تکمیل به‌روزرسانی بسته هوش مصنوعی استفاده کنید:

Task<AiPackStates> fetch(List<String> packNames)

این روش یک شیء AiPackStates برمی‌گرداند که حاوی فهرستی از بسته‌ها و وضعیت‌ها و اندازه‌های بارگیری اولیه آن‌ها است. اگر بسته هوش مصنوعی درخواست‌شده ازطریق fetch() درحال بارگیری باشد، وضعیت بارگیری برگردانده می‌شود و بارگیری دیگری شروع نمی‌شود.

نظارت بر وضعیت بارگیری

باید AiPackStateUpdateListener را پیاده‌سازی کنید تا پیشرفت نصب بسته‌های هوش مصنوعی را پیگیری کنید. به‌روزرسانی‌های وضعیت برای هر بسته به‌طور جداگانه ارائه می‌شود تا بتوانید وضعیت هر بسته هوش مصنوعی را به‌طور مستقل پیگیری کنید. می‌توانید قبل‌از تکمیل شدن همه بارگیری‌های دیگر برای درخواستتان، استفاده از بسته‌های هوش مصنوعی دردسترس را شروع کنید.

void registerListener(AiPackStateUpdateListener listener)
void unregisterListener(AiPackStateUpdateListener listener)
بارگیری‌های بزرگ

اگر حجم بارگیری بیشتر از ۲۰۰ مگابایت باشد و کاربر به Wi-Fi متصل نباشد، بارگیری شروع نمی‌شود تا زمانی که کاربر صریحاً رضایت خود را برای ادامه بارگیری بااستفاده از اتصال داده تلفن همراه اعلام کند. به‌طور مشابه، اگر حجم بارگیری زیاد باشد و کاربر اتصال Wi-Fi را ازدست بدهد، بارگیری موقتاً متوقف می‌شود و برای ادامه دادن بااستفاده از اتصال داده تلفن همراه، رضایت صریح لازم است. بسته موقتاً متوقف‌شده دارای وضعیت WAITING_FOR_WIFI است. برای راه‌اندازی جریان میانای کاربر برای درخواست رضایت از کاربر، از روش showConfirmationDialog() استفاده کنید.

توجه داشته باشید که اگر برنامه این روش را فراخوانی نکند، بارگیری موقتاً متوقف می‌شود و فقط زمانی‌که کاربر دوباره به اتصال Wi-Fi برگردد به‌طور خودکار ازسر گرفته می‌شود.

تأیید کاربر لازم است

اگر بسته‌ای وضعیت REQUIRES_USER_CONFIRMATION داشته باشد، بارگیری ادامه نخواهد یافت تا زمانی که کاربر کادر گفتگویی را که با showConfirmationDialog() نشان داده می‌شود بپذیرد. این وضعیت زمانی رخ می‌دهد که برنامه توسط Play شناسایی نشود—برای مثال، اگر برنامه جانبی بار شده باشد. توجه داشته باشید که فراخوانی showConfirmationDialog() در این مورد باعث به‌روزرسانی برنامه می‌شود. پس‌از به‌روزرسانی، باید دوباره بسته‌های هوش مصنوعی را درخواست کنید.

در زیر نمونه‌ای از پیاده‌سازی شنونده آورده شده است:

AiPackStateUpdateListener aiPackStateUpdateListener = new AiPackStateUpdateListener() {
    private final ActivityResultLauncher<IntentSenderRequest> activityResultLauncher =
      registerForActivityResult(
          new ActivityResultContracts.StartIntentSenderForResult(),
          new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
              if (result.getResultCode() == RESULT_OK) {
                Log.d(TAG, "Confirmation dialog has been accepted.");
              } else if (result.getResultCode() == RESULT_CANCELED) {
                Log.d(TAG, "Confirmation dialog has been denied by the user.");
              }
            }
          });

    @Override
    public void onStateUpdate(AiPackState aiPackState) {
      switch (aiPackState.status()) {
        case AiPackStatus.PENDING:
          Log.i(TAG, "Pending");
          break;

        case AiPackStatus.DOWNLOADING:
          long downloaded = aiPackState.bytesDownloaded();
          long totalSize = aiPackState.totalBytesToDownload();
          double percent = 100.0 * downloaded / totalSize;

          Log.i(TAG, "PercentDone=" + String.format("%.2f", percent));
          break;

        case AiPackStatus.TRANSFERRING:
          // 100% downloaded and assets are being transferred.
          // Notify user to wait until transfer is complete.
          break;

        case AiPackStatus.COMPLETED:
          // AI pack is ready to use. Run the model.
          break;

        case AiPackStatus.FAILED:
          // Request failed. Notify user.
          Log.e(TAG, aiPackState.errorCode());
          break;

        case AiPackStatus.CANCELED:
          // Request canceled. Notify user.
          break;

        case AiPackStatus.WAITING_FOR_WIFI:
        case AiPackStatus.REQUIRES_USER_CONFIRMATION:
          if (!confirmationDialogShown) {
            aiPackManager.showConfirmationDialog(activityResultLauncher);
            confirmationDialogShown = true;
          }
          break;

        case AiPackStatus.NOT_INSTALLED:
          // AI pack is not downloaded yet.
          break;
        case AiPackStatus.UNKNOWN:
          Log.wtf(TAG, "AI pack status unknown")
          break;
      }
    }
}

همچنین می‌توانید از روش getPackStates() برای دریافت وضعیت بارگیری‌های فعلی استفاده کنید. AiPackStates شامل پیشرفت بارگیری، وضعیت بارگیری، و هرگونه کد خطای خرابی است.

دسترسی به بسته‌های هوش مصنوعی

پس‌از اینکه درخواست بارگیری به وضعیت COMPLETED رسید، می‌توانید بااستفاده از فراخوانی‌های سیستم فایل به بسته هوش مصنوعی دسترسی پیدا کنید. از روش getPackLocation() برای دریافت پوشه ریشه بسته هوش مصنوعی استفاده کنید.

بسته‌های هوش مصنوعی در دایرکتوری assets در دایرکتوری ریشه بسته هوش مصنوعی ذخیره می‌شوند. بااستفاده از روش راحتی assetsPath() می‌توانید مسیر دایرکتوری assets را دریافت کنید. از روش زیر برای دریافت مسیر دارایی خاصی استفاده کنید:

private String getAbsoluteAiAssetPath(String aiPack, String relativeAiAssetPath) {
    AiPackLocation aiPackPath = aiPackManager.getPackLocation(aiPack);

    if (aiPackPath == null) {
        // AI pack is not ready
        return null;
    }

    String aiAssetsFolderPath = aiPackPath.assetsPath();
    // equivalent to: FilenameUtils.concat(aiPackPath.path(), "assets");
    String aiAssetPath = FilenameUtils.concat(aiAssetsFolderPath, relativeAiAssetPath);
    return aiAssetPath;
}

پیکربندی هدف‌یابی دستگاه

می‌توانید دستورالعمل‌های هدف‌یابی دستگاه را دنبال کنید تا دستگاه‌ها یا گروه‌های دستگاهی را که باید بسته‌های هوش مصنوعی شما را دریافت کنند مشخص کنید.

سایر روش‌های Play AI Delivery API

در زیر برخی‌از روش‌های اضافی میانای برنامه‌سازی کاربردی که ممکن است بخواهید در برنامه‌تان استفاده کنید آورده شده است.

لغو درخواست

از cancel() برای لغو درخواست بسته هوش مصنوعی فعال استفاده کنید. توجه داشته باشید که این درخواست عملیاتی با حداکثر تلاش است.

برداشتن بسته هوش مصنوعی

از removePack() برای زمان‌بندی برداشتن بسته هوش مصنوعی استفاده کنید.

دریافت مکان‌های چند بسته هوش مصنوعی

از getPackLocations() برای پُرسمان وضعیت چندین بسته هوش مصنوعی به‌صورت انبوه استفاده کنید که نقشه‌ای از بسته‌های هوش مصنوعی و مکان‌های آن‌ها را برمی‌گرداند. نقشه برگردانده‌شده توسط getPackLocations() حاوی ورودی برای هر بسته‌ای است که درحال‌حاضر بارگیری شده و به‌روز است.

هدف‌گیری دستگاه

هدف‌یابی دستگاه به شما امکان می‌دهد کنترل دقیق‌تری بر اینکه کدام بخش‌های دسته برنامه‌تان به دستگاه‌های خاصی ارائه شود داشته باشید. برای مثال، می‌توانید مطمئن شوید که مدل بزرگ فقط به دستگاه‌هایی با RAM بالا ارسال می‌شود یا می‌توانید نسخه‌های مختلف یک مدل را به دستگاه‌های مختلف ارسال کنید.

می‌توانید ویژگی‌های دستگاه را هدف‌یابی کنید، ازجمله:

نمای کلی مراحل لازم

مراحل زیر برای فعال کردن هدف‌یابی دستگاه لازم است:

  1. گروه‌های دستگاهتان را در فایل XML تعریف کنید.
  2. مشخص کنید کدام بخش‌های دسته‌تان باید به کدام گروه‌های دستگاه برود.
  3. [اختیاری] پیکربندی‌تان را به‌صورت محلی آزمایش کنید.
  4. دسته خود را (که حاوی فایل XML است) در Google Play بارگذاری کنید.

بررسی نسخه افزایه Android Gradle

برای استفاده از هدف‌یابی دستگاه، مطمئن شوید که نسخه «افزایه Android Gradle» (AGP) شما حداقل ۸.۱۰.۰ باشد. این ویژگی با «استودیو Android» (نسخه Meerkat 2 و جدیدتر) بسته‌بندی شده است. جدیدترین نسخه پایدار Android Studio را بارگیری کنید.

فعال کردن این ویژگی در «افزایه Android Gradle»

هدف‌یابی دستگاه باید به‌طور صریح در فایل gradle.properties شما فعال شود:

android.experimental.enableDeviceTargetingConfigApi=true

ایجاد فایل XML پیکربندی هدف‌یابی دستگاه

فایل پیکربندی هدف‌یابی دستگاه یک فایل XML است که در آن گروه‌های دستگاه سفارشی خود را تعریف می‌کنید. برای مثال، می‌توانید گروه دستگاهی به‌نام qti_v79 تعریف کنید که شامل همه دستگاه‌های دارای SoC‏ Qualcomm SM8750 باشد:

<config:device-targeting-config
    xmlns:config="http://schemas.android.com/apk/config">

    <config:device-group name="qti_v79">
        <config:device-selector>
            <config:system-on-chip manufacturer="QTI" model="SM8750"/>
        </config:device-selector>
    </config:device-group>

</config:device-targeting-config>

گروه دستگاه از حداکثر ۵ انتخاب‌گر دستگاه تشکیل شده است. اگر دستگاهی با هرکدام از انتخاب‌کننده‌های دستگاه در گروه دستگاه مطابقت داشته باشد، در آن گروه دستگاه قرار می‌گیرد.

انتخاب‌گر دستگاه می‌تواند یک یا چند ویژگی دستگاه داشته باشد. اگر دستگاهی با همه ویژگی‌های دستگاه انتخاب‌کننده مطابقت داشته باشد، انتخاب می‌شود.

اگر دستگاهی با چند گروه مطابقت داشته باشد، محتوای گروهی که ابتدا در فایل XML تعریف شده است برای آن ارائه می‌شود. ترتیبی که گروه‌ها را در فایل XML تعریف می‌کنید، ترتیب اولویت شما است.

اگر دستگاهی با هیچ گروهی مطابقت نداشته باشد، گروه پیش‌فرض «دیگر» را دریافت خواهد کرد. این گروه به‌طور خودکار تولید می‌شود و نباید به‌طور صریح تعریف شود.

ویژگی‌های دردسترس دستگاه

  • device_ram: الزامات حافظه دسترسی تصادفی دستگاه
    • min_bytes (شامل): حداقل RAM موردنیاز (به بایت)
    • max_bytes (انحصاری): حداکثر حافظه دسترسی تصادفی موردنیاز (به بایت)
  • included_device_ids: مدل‌های دستگاهی که باید در این انتخابگر گنجانده شوند (حداکثر ۱۰۰۰۰ شناسه دستگاه در هر گروه). اگر دستگاه با هرکدام از device_idهای موجود در فهرست مطابقت داشته باشد، این ویژگی برآورده می‌شود.
    • build_brand: سازنده دستگاه
    • build_device: کد مدل دستگاه
  • excluded_device_ids: مدل‌های دستگاهی که باید در این انتخابگر مستثنی شوند (حداکثر ۱۰۰۰۰ شناسه دستگاه در هر گروه). اگر دستگاه با هیچ‌کدام از device_idهای موجود در فهرست مطابقت نداشته باشد، این ویژگی برآورده می‌شود.
    • build_brand: سازنده دستگاه
    • build_device: کد مدل دستگاه
  • required_system_features: ویژگی‌هایی که دستگاه باید داشته باشد تا در این انتخابگر گنجانده شود (حداکثر ۱۰۰ ویژگی برای هر گروه). دستگاه باید همه ویژگی‌های سیستم را در این فهرست داشته باشد تا این ویژگی را برآورده کند.

    مرجع ویژگی سیستم

    • نام: ویژگی سیستم
  • forbidden_system_features: ویژگی‌هایی که دستگاه نباید داشته باشد تا توسط این انتخابگر اضافه شود (حداکثر ۱۰۰ ویژگی برای هر گروه). اگر دستگاهی هریک از ویژگی‌های سیستم را در این فهرست داشته باشد، این ویژگی را برآورده نمی‌کند.

    مرجع ویژگی سیستم

    • نام: ویژگی سیستم
  • system-on-chip: سیستم روی تراشه‌هایی که باید در این انتخابگر گنجانده شوند. دستگاه باید یکی از تراشه‌های این فهرست را داشته باشد تا این ویژگی را برآورده کند.

در اینجا نمونه‌ای آورده شده است که همه ویژگی‌های ممکن دستگاه را نشان می‌دهد:

<config:device-targeting-config
    xmlns:config="http://schemas.android.com/apk/config">

    <config:device-group name="myCustomGroup1">
      <config:device-selector ram-min-bytes="8000000000">
        <config:included-device-id brand="google" device="redfin"/>
        <config:included-device-id brand="google" device="sailfish"/>
        <config:included-device-id brand="good-brand"/>
        <config:excluded-device-id brand="google" device="caiman"/>
        <config:system-on-chip manufacturer="Sinclair" model="ZX80"/>
        <config:system-on-chip manufacturer="Commodore" model="C64"/>
      </config:device-selector>
      <config:device-selector ram-min-bytes="16000000000"/>
    </config:device-group>

    <config:device-group name="myCustomGroup2">
      <config:device-selector ram-min-bytes="4000000000" ram-max-bytes="8000000000">
        <config:required-system-feature name="android.hardware.bluetooth"/>
        <config:required-system-feature name="android.hardware.location"/>
        <config:forbidden-system-feature name="android.hardware.camera"/>
        <config:forbidden-system-feature name="mindcontrol.laser"/>
      </config:device-selector>
    </config:device-group>

</config:device-targeting-config>

کدهای رسمی سازنده دستگاه و مدل دستگاه

می‌توانید قالب‌بندی صحیح سازنده دستگاه و کد مدل را بااستفاده از «کاتالوگ دستگاه» در «کنسول Google Play» به یکی از روش‌های زیر پیدا کنید:

  • بررسی دستگاه‌های تکی بااستفاده از «کاتالوگ دستگاه» و پیدا کردن سازنده و کد مدل در مکان‌هایی که در مثال زیر نشان داده شده است (برای Google Pixel 4a، سازنده «Google» و کد مدل «sunfish» است)

    صفحه pixel 4a در فهرست دستگاه‌ها

    صفحه pixel 4a در فهرست دستگاه‌ها

  • بارگیری فایل CSV دستگاه‌های پشتیبانی‌شده و استفاده از سازنده و کد مدل به‌ترتیب برای فیلدهای build_brand و build_device.

فایل پیکربندی هدف‌یابی دستگاهتان را در دسته برنامه‌تان بگنجانید

موارد زیر را به فایل build.gradle واحد اصلی‌تان اضافه کنید:

android {
  ...
  bundle {
    deviceTargetingConfig = file('device_targeting_config.xml')
    deviceGroup {
      enableSplit = true   // split bundle by #group
      defaultGroup = "other"  // group used for standalone APKs
    }
  }
  ...
}

device_targeting_config.xml مسیر فایل پیکربندی شما نسبت به واحد اصلی است. این کار تضمین می‌کند که فایل پیکربندی شما با دسته برنامه‌تان بسته‌بندی شده است.

بند deviceGroup تضمین می‌کند که فایل‌های APK تولیدشده از دسته شما براساس گروه‌های دستگاه تقسیم می‌شوند.

استفاده از هدف‌یابی دستگاه برای بسته‌های هوش مصنوعی

می‌توانید اندازه را در دستگاه‌ها بهینه‌سازی کنید و مدل‌های بزرگتان را فقط به دستگاه‌هایی ارائه دهید که می‌توانند آن‌ها را اجرا کنند.

با گرفتن دایرکتوری‌های بسته AI موجود که در مرحله آخر ایجاد شده‌اند، بسته‌های AI خود را براساس گروه‌های دستگاه تقسیم کنید و پوشه‌های مناسب را (همان‌طور که در زیر توضیح داده شده است) با ‎#group_myCustomGroup1،‏ ‎#group_myCustomGroup2، و غیره پسوندگذاری کنید. هنگام استفاده از بسته‌های AI در برنامه‌تان، نیازی به آدرس‌دهی پوشه‌ها با پسوند نخواهید داشت (به عبارت دیگر، پسوند به‌طور خودکار درطول فرایند ساخت حذف می‌شود).

پس‌از مرحله قبلی، ممکن است این‌گونه به‌نظر برسد:

...
.../ai-pack-name/src/main/assets/image-classifier#group_myCustomGroup1/
.../ai-pack-name/src/main/assets/image-classifier#group_myCustomGroup2/
...

در این مثال، به ai-pack-name/assets/image-classifier/ بدون هیچ پسوندی ارجاع می‌دهید.

دستگاه‌های موجود در myCustomGroup1 همه دارایی‌های موجود در image-classifier#group_myCustomGroup1/ را دریافت خواهند کرد، درحالی‌که دستگاه‌های موجود در myCustomGroup2 همه دارایی‌های موجود در image-classifier#group_myCustomGroup2/ را دریافت خواهند کرد.

دستگاه‌هایی که به myCustomGroup1 یا myCustomGroup2 تعلق ندارند، بسته ai-pack-name خالی دریافت خواهند کرد.

دلیلش این است که دستگاه‌هایی که با هیچ گروه دستگاهی مطابقت ندارند، نسخه پیش‌فرض بسته هوش مصنوعی شما را دریافت خواهند کرد. این شامل هر چیزی است که داخل فهرست راهنمای دارای #group_suffix نباشد.

پس‌از بارگیری بسته هوش مصنوعی، می‌توانید بااستفاده از AssetManager برای بسته‌های زمان نصب یا AiPackManager برای بسته‌های تحویل سریع و درخواستی، بررسی کنید که آیا مدل شما وجود دارد یا نه. نمونه‌هایی برای انجام این کار برای همه حالت‌های تحویل در برنامه نمونه نشان داده شده است.

استفاده از هدف‌یابی دستگاه برای واحدهای ویژگی

همچنین می‌توانید از هدف‌یابی دستگاه برای پیمانه‌های ویژگی استفاده کنید. به‌جای تقسیم کردن واحدهای ویژگی براساس گروه دستگاه، مشخص می‌کنید که آیا کل واحد باید براساس عضویت در گروه دستگاه ارائه شود یا نه.

برای ارسال پیمانه ویژگی به دستگاه‌هایی که به myCustomGroup1 یا myCustomGroup2 تعلق دارند، AndroidManifest.xml آن را اصلاح کنید:

<manifest ...>
  ...
  <dist:module dist:title="...">
    <dist:delivery>
      <dist:install-time>
        <dist:conditions>
          <dist:device-groups>
            <dist:device-group dist:name="myCustomGroup1"/>
            <dist:device-group dist:name="myCustomGroup2"/>
          </dist:device-groups>
          ...
        </dist:conditions>
      </dist:install-time>
    </dist:delivery>
  </dist:module>
  ...
</manifest>

آزمایش محلی

قبل‌از ایجاد نسخه پخش برای بسته جدیدتان، می‌توانید به‌صورت محلی با «هم‌رسانی داخلی برنامه» یا Bundletool آزمایش کنید.

هم‌رسانی داخلی برنامه

«هم‌رسانی داخلی برنامه» به شما امکان می‌دهد از دسته برنامه برای تولید سریع نشانی وبی استفاده کنید که می‌توانید در دستگاه محلی روی آن تک‌ضرب بزنید تا دقیقاً همان چیزی را نصب کنید که اگر آن نسخه برنامه در دسته آزمایشی یا تولید فعال بود، Google Play برای آن دستگاه نصب می‌کرد.

دستورالعمل‌های هم‌رسانی داخلی برنامه را ببینید.

بسته‌ابزار

همچنین می‌توانید بااستفاده از bundletool (نسخه ۱.۱۸.۰ یا بالاتر) فایل‌های APK تولید کنید و آن‌ها را در دستگاهتان بارگذاری جانبی کنید. برای آزمایش محلی برنامه‌تان بااستفاده از bundletool، این مراحل را دنبال کنید:

  1. دسته برنامه‌تان را با «استودیو Android» یا bundletool بسازید.

  2. تولید APK با پرچم --local-testing:

    java -jar bundletool-all.jar build-apks --bundle=path/to/your/bundle.aab \
      --output=output.apks --local-testing
    
  3. دستگاهی را متصل کنید و bundletool را اجرا کنید تا APKها را جانبی بار کنید:

    # Example without Device Targeting Configuration
    java -jar bundletool.jar install-apks --apks=output.apks
    
    # Example with Device Targeting Configuration (you must specify which groups the connected device belongs to)
    java -jar bundletool.jar install-apks --apks=output.apks --device-groups=myCustomGroup1,myCustomGroup2
    

محدودیت‌های آزمایش محلی با bundletool

محدودیت‌های آزمایش محلی با bundletool در زیر آمده است:

  • fast-follow بسته مانند on-demand بسته عمل می‌کند. یعنی وقتی برنامه جانبی بار می‌شود، به‌طور خودکار واکشی نمی‌شوند. توسعه‌دهندگان باید هنگام شروع برنامه، آن‌ها را به‌صورت دستی درخواست کنند؛ این کار نیازی به تغییر کد در برنامه شما ندارد.
  • بسته‌ها به‌جای Play از فضای ذخیره‌سازی خارجی واکشی می‌شوند، بنابراین نمی‌توانید نحوه رفتار کدتان را درصورت بروز خطاهای شبکه آزمایش کنید.
  • آزمایش محلی سناریوی انتظار برای Wi-Fi را پوشش نمی‌دهد.
  • به‌روزرسانی‌ها پشتیبانی نمی‌شود. قبل‌از نصب نسخه جدید ساخت، نسخه قبلی را به‌صورت دستی حذف نصب کنید.

تأیید کنید که APKهای درست نصب شده‌اند

از روش زیر استفاده کنید تا مطمئن شوید فقط APKهای صحیح در دستگاه نصب شده است

adb shell pm path {packageName}

باید چیزی شبیه این ببینید:

package:{...}/base.apk
package:{...}/split_config.en.apk
package:{...}/split_config.xxhdpi.apk
package:{...}/split_main_ai-pack-name.apk
package:{...}/split_main_ai-pack-name.config.group_myCustomGroup1.apk

توجه داشته باشید که فقط APKهایی را در این فهرست خواهید دید که از واحد ویژگی و بسته‌های هوش مصنوعی زمان نصب ساخته شده‌اند. دسته‌های هوش مصنوعی درخواستی و تحویل سریع به‌عنوان APK نصب نمی‌شوند.

آزمایش و انتشار در Google Play

توصیه می‌کنیم برنامه‌تان را به‌طور کامل در Google Play با دسته هدف آزمایشی داخلی آزمایش کنید.

پس‌از انجام این کار، می‌توانید به‌روزرسانی برنامه‌تان را به‌صورت افزایشی با عرضه مرحله‌ای در نسخه تولید منتشر کنید.

برنامه نمونه بااستفاده از Play ویژه هوش مصنوعی درون‌دستگاهی

برنامه نمونه را بارگیری کنید.

این نمونه نحوه استفاده از هریک از حالت‌های تحویل و همچنین پیکربندی هدف‌یابی دستگاه را نشان می‌دهد. برای شروع، بخش آزمایش محلی را ببینید.

درباره دسته‌های برنامه Android بیشتر بدانید و مرجع‌های کیت توسعه نرم‌افزار توزیع هوش مصنوعی را بخوانید.