این راهنما نحوه پشتیبانی از بهروزرسانیهای درون برنامهای در برنامه خود را با استفاده از Kotlin یا Java توضیح میدهد. برای مواردی که پیاده سازی شما از کد بومی (C/C++) و مواردی که پیاده سازی شما از Unity استفاده می کند، راهنماهای جداگانه ای وجود دارد.
محیط توسعه خود را تنظیم کنید
کتابخانه بهروزرسانی درون برنامهای Play بخشی از کتابخانههای هسته Google Play است. لطفاً وابستگی Gradle زیر را برای ادغام کتابخانه بهروزرسانی درون برنامه Play اضافه کنید.
شیار
// In your app’s build.gradle file: ... dependencies { // This dependency is downloaded from the Google’s Maven repository. // So, make sure you also include that repository in your project's build.gradle file. implementation 'com.google.android.play:app-update:2.1.0' // For Kotlin users also add the Kotlin extensions library for Play In-App Update: implementation 'com.google.android.play:app-update-ktx:2.1.0' ... }
کاتلین
// In your app’s build.gradle.kts file: ... dependencies { // This dependency is downloaded from the Google’s Maven repository. // So, make sure you also include that repository in your project's build.gradle file. implementation("com.google.android.play:app-update:2.1.0") // For Kotlin users also import the Kotlin extensions library for Play In-App Update: implementation("com.google.android.play:app-update-ktx:2.1.0") ... }
در دسترس بودن بهروزرسانی را بررسی کنید
قبل از درخواست بهروزرسانی، بررسی کنید که آیا بهروزرسانی برای برنامه شما موجود است یا خیر. از AppUpdateManager
برای بررسی بهروزرسانی استفاده کنید:
کاتلین
val appUpdateManager = AppUpdateManagerFactory.create(context) // Returns an intent object that you use to check for an update. val appUpdateInfoTask = appUpdateManager.appUpdateInfo // Checks that the platform will allow the specified type of update. appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE // This example applies an immediate update. To apply a flexible update // instead, pass in AppUpdateType.FLEXIBLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) ) { // Request the update. } }
جاوا
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context); // Returns an intent object that you use to check for an update. Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo(); // Checks that the platform will allow the specified type of update. appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> { if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE // This example applies an immediate update. To apply a flexible update // instead, pass in AppUpdateType.FLEXIBLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) { // Request the update. } });
نمونه AppUpdateInfo
برگشتی حاوی وضعیت در دسترس بودن بهروزرسانی است. بسته به وضعیت به روز رسانی، نمونه شامل موارد زیر نیز می شود:
- اگر بهروزرسانی در دسترس باشد و بهروزرسانی مجاز باشد، نمونه شامل قصدی برای شروع بهروزرسانی است.
- اگر یک بهروزرسانی درونبرنامه از قبل در حال انجام است، نمونه وضعیت بهروزرسانی در حال انجام را نیز گزارش میکند.
بیات بودن بهروزرسانی را بررسی کنید
علاوه بر بررسی اینکه آیا یک بهروزرسانی در دسترس است، ممکن است بخواهید بررسی کنید که از آخرین باری که کاربر از یک بهروزرسانی از طریق فروشگاه Play اطلاع داده شده است، چقدر زمان گذشته است. این می تواند به شما کمک کند تصمیم بگیرید که آیا باید یک به روز رسانی انعطاف پذیر را شروع کنید یا یک به روز رسانی فوری. برای مثال، ممکن است چند روز قبل از اطلاع دادن به کاربر با یک بهروزرسانی انعطافپذیر، و چند روز پس از آن قبل از نیاز به بهروزرسانی فوری صبر کنید.
از clientVersionStalenessDays()
برای بررسی تعداد روزهایی که بهروزرسانی در فروشگاه Play در دسترس قرار گرفته است استفاده کنید:
کاتلین
val appUpdateManager = AppUpdateManagerFactory.create(context) // Returns an intent object that you use to check for an update. val appUpdateInfoTask = appUpdateManager.appUpdateInfo // Checks whether the platform allows the specified type of update, // and current version staleness. appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && (appUpdateInfo.clientVersionStalenessDays() ?: -1) >= DAYS_FOR_FLEXIBLE_UPDATE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) { // Request the update. } }
جاوا
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context); // Returns an intent object that you use to check for an update. Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo(); // Checks whether the platform allows the specified type of update, // and current version staleness. appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> { if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.clientVersionStalenessDays() != null && appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_FLEXIBLE_UPDATE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) { // Request the update. } });
اولویت بهروزرسانی را بررسی کنید
Google Play Developer API به شما امکان می دهد اولویت هر به روز رسانی را تعیین کنید. این به برنامه شما اجازه میدهد تصمیم بگیرد که چقدر بهروزرسانی بهطور جدی به کاربر توصیه کند. برای مثال، استراتژی زیر را برای تنظیم اولویت بهروزرسانی در نظر بگیرید:
- بهبودهای جزئی رابط کاربری: به روز رسانی با اولویت پایین . نه بهروزرسانی انعطافپذیر و نه بهروزرسانی فوری را درخواست کنید. فقط زمانی بهروزرسانی کنید که کاربر با برنامه شما تعامل نداشته باشد.
- بهبود عملکرد: به روز رسانی با اولویت متوسط . درخواست به روز رسانی انعطاف پذیر
- به روز رسانی امنیتی حیاتی: به روز رسانی با اولویت بالا . درخواست به روز رسانی فوری
برای تعیین اولویت، گوگل پلی از یک عدد صحیح بین 0 تا 5 استفاده می کند که 0 به عنوان پیش فرض و 5 بالاترین اولویت است. برای تنظیم اولویت برای بهروزرسانی، از فیلد inAppUpdatePriority
زیر Edits.tracks.releases
در Google Play Developer API استفاده کنید. تمامی نسخه های جدید اضافه شده در نسخه دارای اولویت یکسان با نسخه هستند. اولویت را فقط می توان در هنگام عرضه نسخه جدید تنظیم کرد و بعداً نمی توان آن را تغییر داد.
همانطور که در مستندات Play Developer API توضیح داده شده است، اولویت را با استفاده از Google Play Developer API تنظیم کنید. اولویت بهروزرسانی درونبرنامه باید در منبع Edit.tracks
که در روش Edit.tracks: update
ارسال شده است، مشخص شود. مثال زیر انتشار یک برنامه با کد نسخه 88 و inAppUpdatePriority
5 را نشان می دهد:
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
در کد برنامهتان، میتوانید با استفاده از updatePriority()
سطح اولویت را برای یک بهروزرسانی مشخص بررسی کنید. اولویت بازگشتی، بدون در نظر گرفتن مسیر انتشار inAppUpdatePriority
را برای همه کدهای نسخه برنامه بین نسخه نصب شده و آخرین نسخه موجود در نظر می گیرد. به عنوان مثال، سناریوی زیر را در نظر بگیرید:
- شما نسخه 1 را برای یک آهنگ تولیدی بدون اولویت منتشر می کنید.
- شما نسخه 2 را در یک آهنگ آزمایشی داخلی با اولویت 5 منتشر می کنید.
- شما نسخه 3 را برای یک آهنگ تولیدی بدون اولویت منتشر می کنید.
هنگامی که کاربران تولیدی از نسخه 1 به نسخه 3 به روز می شوند، با وجود اینکه نسخه 2 در مسیر دیگری منتشر شده است، اولویت 5 را خواهند داشت.
کاتلین
val appUpdateManager = AppUpdateManagerFactory.create(context) // Returns an intent object that you use to check for an update. val appUpdateInfoTask = appUpdateManager.appUpdateInfo // Checks whether the platform allows the specified type of update, // and checks the update priority. appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.updatePriority() >= 4 /* high priority */ && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) { // Request an immediate update. } }
جاوا
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context); // Returns an intent object that you use to check for an update. Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo(); // Checks whether the platform allows the specified type of update, // and checks the update priority. appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> { if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.updatePriority() >= 4 /* high priority */ && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) { // Request an immediate update. } });
یک به روز رسانی را شروع کنید
پس از تأیید وجود بهروزرسانی، میتوانید با استفاده از AppUpdateManager.startUpdateFlowForResult()
درخواست بهروزرسانی کنید:
کاتلین
appUpdateManager.startUpdateFlowForResult( // Pass the intent that is returned by 'getAppUpdateInfo()'. appUpdateInfo, // an activity result launcher registered via registerForActivityResult activityResultLauncher, // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for // flexible updates. AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build())
جاوا
appUpdateManager.startUpdateFlowForResult( // Pass the intent that is returned by 'getAppUpdateInfo()'. appUpdateInfo, // an activity result launcher registered via registerForActivityResult activityResultLauncher, // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for // flexible updates. AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build());
هر نمونه AppUpdateInfo
را می توان تنها یک بار برای شروع به روز رسانی استفاده کرد. برای امتحان مجدد بهروزرسانی در صورت عدم موفقیت، یک AppUpdateInfo
جدید درخواست کنید و دوباره بررسی کنید که بهروزرسانی موجود و مجاز است.
میتوانید با استفاده از قرارداد ActivityResultContracts.StartIntentSenderForResult
داخلی، یک راهانداز نتیجه فعالیت ثبت کنید. برای وضعیت بهروزرسانی، بخش دریافت پاسخ تماس را بررسی کنید.
مراحل بعدی بستگی به این دارد که آیا درخواست بهروزرسانی انعطافپذیر دارید یا بهروزرسانی فوری .
یک به روز رسانی را با AppUpdateOptions پیکربندی کنید
AppUpdateOptions
حاوی یک فیلد AllowAssetPackDeletion
است که مشخص می کند آیا به روز رسانی مجاز است بسته های دارایی را در صورت محدودیت فضای ذخیره سازی دستگاه پاک کند یا خیر. این فیلد بهطور پیشفرض روی false
تنظیم شده است، اما میتوانید از متد setAllowAssetPackDeletion()
برای تنظیم آن روی true
استفاده کنید:
کاتلین
appUpdateManager.startUpdateFlowForResult( // Pass the intent that is returned by 'getAppUpdateInfo()'. appUpdateInfo, // an activity result launcher registered via registerForActivityResult activityResultLauncher, // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for // flexible updates. AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE) .setAllowAssetPackDeletion(true) .build())
جاوا
appUpdateManager.startUpdateFlowForResult( // Pass the intent that is returned by 'getAppUpdateInfo()'. appUpdateInfo, // an activity result launcher registered via registerForActivityResult activityResultLauncher, // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for // flexible updates. AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE) .setAllowAssetPackDeletion(true) .build());
برای وضعیت بهروزرسانی یک تماس پاسخ دریافت کنید
پس از شروع بهروزرسانی، پاسخ تماس راهانداز نتیجه فعالیت ثبتشده نتیجه گفتگوی تأیید را دریافت میکند:
کاتلین
registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult -> // handle callback if (result.resultCode != RESULT_OK) { log("Update flow failed! Result code: " + result.resultCode); // If the update is canceled or fails, // you can request to start the update again. } }
جاوا
registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { // handle callback if (result.getResultCode() != RESULT_OK) { log("Update flow failed! Result code: " + result.getResultCode()); // If the update is canceled or fails, // you can request to start the update again. } } });
چندین مقدار وجود دارد که ممکن است از callback onActivityResult()
دریافت کنید:
-
RESULT_OK
: کاربر به روز رسانی را پذیرفته است. برای بهروزرسانیهای فوری، ممکن است این تماس را دریافت نکنید زیرا با بازگرداندن کنترل زمان به برنامه شما، بهروزرسانی باید تمام شده باشد. -
RESULT_CANCELED
: کاربر بهروزرسانی را رد یا لغو کرده است. -
ActivityResult.RESULT_IN_APP_UPDATE_FAILED
: برخی از خطاهای دیگر یا کاربر را از ارائه رضایت یا ادامه بهروزرسانی جلوگیری میکرد.
به روز رسانی انعطاف پذیر را مدیریت کنید
وقتی یک بهروزرسانی انعطافپذیر را شروع میکنید، ابتدا یک گفتگو برای درخواست رضایت برای کاربر ظاهر میشود. اگر کاربر رضایت دهد، دانلود در پسزمینه شروع میشود و کاربر میتواند به تعامل با برنامه شما ادامه دهد. این بخش نحوه نظارت و تکمیل بهروزرسانی درونبرنامه انعطافپذیر را شرح میدهد.
وضعیت بهروزرسانی انعطافپذیر را نظارت کنید
پس از شروع بارگیری برای بهروزرسانی انعطافپذیر، برنامه شما باید وضعیت بهروزرسانی را کنترل کند تا بداند چه زمانی میتوان بهروزرسانی را نصب کرد و پیشرفت را در رابط کاربری برنامهتان نشان داد.
میتوانید با ثبت یک شنونده برای بهروزرسانیهای وضعیت نصب، وضعیت بهروزرسانی در حال انجام را نظارت کنید. همچنین میتوانید یک نوار پیشرفت در رابط کاربری برنامه ارائه دهید تا کاربران را از پیشرفت دانلود مطلع کنید.
کاتلین
// Create a listener to track request state updates. val listener = InstallStateUpdatedListener { state -> // (Optional) Provide a download progress bar. if (state.installStatus() == InstallStatus.DOWNLOADING) { val bytesDownloaded = state.bytesDownloaded() val totalBytesToDownload = state.totalBytesToDownload() // Show update progress bar. } // Log state or install the update. } // Before starting an update, register a listener for updates. appUpdateManager.registerListener(listener) // Start an update. // When status updates are no longer needed, unregister the listener. appUpdateManager.unregisterListener(listener)
جاوا
// Create a listener to track request state updates. InstallStateUpdatedListener listener = state -> { // (Optional) Provide a download progress bar. if (state.installStatus() == InstallStatus.DOWNLOADING) { long bytesDownloaded = state.bytesDownloaded(); long totalBytesToDownload = state.totalBytesToDownload(); // Implement progress bar. } // Log state or install the update. }; // Before starting an update, register a listener for updates. appUpdateManager.registerListener(listener); // Start an update. // When status updates are no longer needed, unregister the listener. appUpdateManager.unregisterListener(listener);
یک به روز رسانی انعطاف پذیر نصب کنید
وقتی وضعیت InstallStatus.DOWNLOADED
را تشخیص دادید، برای نصب بهروزرسانی باید برنامه را مجدداً راهاندازی کنید.
برخلاف بهروزرسانیهای فوری، Google Play بهطور خودکار راهاندازی مجدد برنامه را برای بهروزرسانی انعطافپذیر راهاندازی نمیکند. این به این دلیل است که در طول یک بهروزرسانی انعطافپذیر، کاربر انتظار دارد به تعامل با برنامه ادامه دهد تا زمانی که تصمیم بگیرد که میخواهد بهروزرسانی را نصب کند.
توصیه میشود قبل از راهاندازی مجدد برنامه، یک اعلان (یا نشانههای رابط کاربری دیگر) ارائه دهید تا به کاربر اطلاع دهید که بهروزرسانی آماده نصب است و درخواست تأیید کنید.
مثال زیر اجرای یک نوار اسنک متریال دیزاین را نشان میدهد که از کاربر برای راهاندازی مجدد برنامه درخواست تأیید میکند:
کاتلین
val listener = { state -> if (state.installStatus() == InstallStatus.DOWNLOADED) { // After the update is downloaded, show a notification // and request user confirmation to restart the app. popupSnackbarForCompleteUpdate() } ... } // Displays the snackbar notification and call to action. fun popupSnackbarForCompleteUpdate() { Snackbar.make( findViewById(R.id.activity_main_layout), "An update has just been downloaded.", Snackbar.LENGTH_INDEFINITE ).apply { setAction("RESTART") { appUpdateManager.completeUpdate() } setActionTextColor(resources.getColor(R.color.snackbar_action_text_color)) show() } }
جاوا
InstallStateUpdatedListener listener = state -> { if (state.installStatus() == InstallStatus.DOWNLOADED) { // After the update is downloaded, show a notification // and request user confirmation to restart the app. popupSnackbarForCompleteUpdate(); } ... }; // Displays the snackbar notification and call to action. private void popupSnackbarForCompleteUpdate() { Snackbar snackbar = Snackbar.make( findViewById(R.id.activity_main_layout), "An update has just been downloaded.", Snackbar.LENGTH_INDEFINITE); snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate()); snackbar.setActionTextColor( getResources().getColor(R.color.snackbar_action_text_color)); snackbar.show(); }
وقتی appUpdateManager.completeUpdate()
را در پیش زمینه فراخوانی می کنید، پلتفرم یک رابط کاربری تمام صفحه نمایش می دهد که برنامه را در پس زمینه راه اندازی مجدد می کند. پس از اینکه پلتفرم آپدیت را نصب کرد، برنامه شما به فعالیت اصلی خود راه اندازی مجدد می شود.
اگر زمانی که برنامه شما در پسزمینه قرار دارد، بهجای آن completeUpdate()
را فراخوانی کنید، بهروزرسانی بیصدا و بدون مخفی کردن رابط کاربری دستگاه نصب میشود.
هر زمان که کاربر برنامه شما را در پیش زمینه می آورد، بررسی کنید که آیا برنامه شما به روز رسانی در انتظار نصب است یا خیر. اگر برنامه شما بهروزرسانی در حالت DOWNLOADED
دارد، از کاربر بخواهید که بهروزرسانی را نصب کند. در غیر این صورت، داده های به روز رسانی همچنان فضای ذخیره سازی دستگاه کاربر را اشغال می کند.
کاتلین
// Checks that the update is not stalled during 'onResume()'. // However, you should execute this check at all app entry points. override fun onResume() { super.onResume() appUpdateManager .appUpdateInfo .addOnSuccessListener { appUpdateInfo -> ... // If the update is downloaded but not installed, // notify the user to complete the update. if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) { popupSnackbarForCompleteUpdate() } } }
جاوا
// Checks that the update is not stalled during 'onResume()'. // However, you should execute this check at all app entry points. @Override protected void onResume() { super.onResume(); appUpdateManager .getAppUpdateInfo() .addOnSuccessListener(appUpdateInfo -> { ... // If the update is downloaded but not installed, // notify the user to complete the update. if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) { popupSnackbarForCompleteUpdate(); } }); }
به روز رسانی فوری را مدیریت کنید
هنگامی که بهروزرسانی فوری را شروع میکنید و کاربر با شروع بهروزرسانی موافقت میکند، Google Play پیشرفت بهروزرسانی را در بالای رابط کاربری برنامه شما در تمام مدت بهروزرسانی نشان میدهد. اگر کاربر برنامه شما را در طول بهروزرسانی ببندد یا خاتمه دهد، بهروزرسانی باید به دانلود و نصب در پسزمینه بدون تأیید کاربر اضافی ادامه دهد.
با این حال، وقتی برنامه شما به پیشزمینه برمیگردد، باید تأیید کنید که بهروزرسانی در وضعیت UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
متوقف نشده است. اگر بهروزرسانی در این حالت متوقف شد، بهروزرسانی را از سر بگیرید:
کاتلین
// Checks that the update is not stalled during 'onResume()'. // However, you should execute this check at all entry points into the app. override fun onResume() { super.onResume() appUpdateManager .appUpdateInfo .addOnSuccessListener { appUpdateInfo -> ... if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS ) { // If an in-app update is already running, resume the update. appUpdateManager.startUpdateFlowForResult( appUpdateInfo, activityResultLauncher, AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()) } } }
جاوا
// Checks that the update is not stalled during 'onResume()'. // However, you should execute this check at all entry points into the app. @Override protected void onResume() { super.onResume(); appUpdateManager .getAppUpdateInfo() .addOnSuccessListener( appUpdateInfo -> { ... if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) { // If an in-app update is already running, resume the update. appUpdateManager.startUpdateFlowForResult( appUpdateInfo, activityResultLauncher, AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()); } }); }
جریان به روز رسانی نتیجه ای را برمی گرداند همانطور که در مستندات مرجع برای startUpdateFlowForResult() توضیح داده شده است. به ویژه، برنامه شما باید بتواند مواردی را که کاربر بهروزرسانی را رد کرده یا دانلود را لغو میکند، مدیریت کند. هنگامی که کاربر هر یک از این اقدامات را انجام می دهد، رابط کاربری Google Play بسته می شود. برنامه شما باید بهترین راه را برای ادامه تعیین کند.
در صورت امکان، به کاربر اجازه دهید بدون بهروزرسانی ادامه دهد و بعداً دوباره از او درخواست کنید. اگر برنامه شما بدون بهروزرسانی نمیتواند کار کند، قبل از راهاندازی مجدد جریان بهروزرسانی یا درخواست از کاربر برای بستن برنامه، یک پیام آموزنده نمایش دهید. به این ترتیب، کاربر متوجه میشود که وقتی آماده نصب بهروزرسانی مورد نیاز باشد، میتواند برنامه شما را دوباره راهاندازی کند.
مراحل بعدی
بهروزرسانیهای درونبرنامهای را آزمایش کنید تا مطمئن شوید که ادغام شما به درستی کار میکند.