{"id":484911,"date":"2026-06-25T02:30:09","date_gmt":"2026-06-25T02:30:09","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=484911"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=484911","title":{"rendered":"\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Flutter: \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u043e \u0432\u043e\u0437\u0434\u0443\u0445\u0443"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>Hola, Amigos! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u041f\u0430\u0432\u0435\u043b \u0413\u0435\u0440\u0448\u0435\u0432\u0438\u0447, Mobile Team Lead \u0430\u0433\u0435\u043d\u0442\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Amiga \u0438 \u0441\u043e\u0430\u0432\u0442\u043e\u0440 \u043a\u043d\u0438\u0433\u0438 &#171;\u041e\u0441\u043d\u043e\u0432\u044b Flutter&#187;. \u041c\u044b \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0441 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 <a href=\"https:\/\/medium.com\/@CodeX_Lancers\/dynamic-app-icons-in-flutter-the-ultimate-guide-to-manual-selection-over-the-air-cloud-updates-f24547a0837b\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0438<\/a> \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438. \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f!<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ae0\/ecd\/f8d\/ae0ecdf8d63ba22d060bf6b1b72dcc1b.png\" width=\"1536\" height=\"1024\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ae0\/ecd\/f8d\/ae0ecdf8d63ba22d060bf6b1b72dcc1b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ae0\/ecd\/f8d\/ae0ecdf8d63ba22d060bf6b1b72dcc1b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0447\u0435\u043d\u044c \u0446\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430. \u041a\u043e\u0433\u0434\u0430 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0430\u043c\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u044d\u0442\u043e \u0434\u0430\u0440\u0438\u0442 \u0438\u043c \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435 \u0447\u0443\u0432\u0441\u0442\u0432\u043e \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 \u044d\u0442\u0438\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043c\u0435\u043d\u044f\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f <em>\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e<\/em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0430\u0437\u0434\u043d\u0438\u043a\u0438, \u0440\u0435\u0431\u0440\u0435\u043d\u0434\u0438\u043d\u0433 \u0432 \u0442\u0435\u043c\u043d\u0443\u044e \u0442\u0435\u043c\u0443 \u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0441 \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u043e\u0432\u043e\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0435\u0439. \u0418 \u0432\u0441\u0435 \u044d\u0442\u043e \u0431\u0435\u0437 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438 \u0432 App Store \u0438\u043b\u0438 Google Play Store.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0438\u043a\u043e\u043d\u043e\u043a \u0432 Flutter, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0434\u0432\u0443\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445, \u043d\u0435 \u043f\u043e\u043b\u0430\u0433\u0430\u044f\u0441\u044c \u043d\u0430 \u0431\u0430\u0433\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438\u043b\u0438 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 <strong>MethodChannels<\/strong> \u043d\u0430 Kotlin \u0438 Swift \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0434\u0432\u0443\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<ol>\n<li>\n<p><strong>\u0420\u0443\u0447\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440<\/strong>: \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0430\u043c\u0438\u043c \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u043e \u0438\u0445 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u044f\u043c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 UI.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u043e\u0437\u0434\u0443\u0445\u0443<\/strong>: \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043a\u043e\u043d\u043a\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 <strong>Firebase Remote Config<\/strong>.<\/p>\n<\/li>\n<\/ol>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u0434\u0430, \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c. \u0422\u0430\u043a \u043a\u0430\u043a Flutter \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0435\u0434\u0438\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 API \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<h3>Android: Component Aliases<\/h3>\n<p>Android \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>AndroidManifest.xml<\/code>. \u0427\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u044d\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f, \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0433\u043e\u0432 <code>&lt;activity-alias&gt;<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 <code>MainActivity<\/code>. \u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 alias \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e <code>PackageManager<\/code>, \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u044d\u043a\u0440\u0430\u043d \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043a\u043e\u043d\u043a\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 alias.<\/p>\n<h4>\u26a0\ufe0f \u041f\u043e\u0431\u043e\u0447\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442 \u043d\u0430 Android:<\/h4>\n<p>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 activity alias \u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0442\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<h3>iOS: API \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0438\u043a\u043e\u043d\u043e\u043a<\/h3>\n<p>Apple \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 <code>UIApplication.shared.setAlternateIconName()<\/code>. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0430\u0441\u0441\u0435\u0442\u043e\u0432 (<code>Assets.xcassets<\/code>). \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (<code>Info.plist<\/code>).<\/p>\n<h2>\u0428\u0430\u0433 1: \u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443<\/h2>\n<h3>1. \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 MethodChannel \u0432 Flutter<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 \u0432\u0430\u0448\u0435\u043c Dart \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u043a\u0430\u043d\u0430\u043b\u0443 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439.<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/services.dart';class DynamicIconService { static const MethodChannel _channel = MethodChannel('com.dynamicicon.app\/dynamic_icon'); \/\/\/ \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u043c\u0435\u043d\u044b \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. static Future&lt;void&gt; changeIcon(String iconName) async {   try {     await _channel.invokeMethod('setIcon', {'iconName': iconName});   } on PlatformException catch (e) {     print(\"Failed to change application launcher profile: '${e.message}'.\");   } }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>2. \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f Android (AndroidManifest.xml \u0438 Kotlin)<\/h3>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u0441\u0441\u0435\u0442\u044b \u0432 \u0432\u0430\u0448\u0438 \u043f\u0430\u043f\u043a\u0438 \u0441 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>android\/app\/src\/main\/res\/mipmap-hdpi\/ic_launcher_dark.png<\/code><\/p>\n<\/li>\n<li>\n<p><code>android\/app\/src\/main\/res\/mipmap-hdpi\/ic_launcher_festive.png<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 <code>android\/app\/src\/main\/AndroidManifest.xml<\/code> &#8212; \u043f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0443 <code>android:enabled<\/code> \u0443 <code>.MainActivity<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>. \u0422\u0430\u043a \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u0435 \u0445\u0443\u043a\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043d\u0430\u0448\u0438\u043c alias.<\/p>\n<pre><code class=\"xml\">&lt;manifest xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"&gt;   &lt;application       android:label=\"Dynamic App\"       android:name=\"${applicationName}\"&gt;             &lt;!-- Base Target Activity Framework (Deactivated) --&gt;       &lt;activity           android:name=\".MainActivity\"           android:exported=\"true\"           android:enabled=\"false\"           android:launchMode=\"singleTop\"           android:theme=\"@style\/LaunchTheme\"&gt;           &lt;meta-data               android:name=\"io.flutter.embedding.android.NormalTheme\"               android:resource=\"@style\/NormalTheme\" \/&gt;       &lt;\/activity&gt;       &lt;!-- Default Application Icon Alias --&gt;       &lt;activity-alias           android:name=\".DefaultIcon\"           android:enabled=\"true\"           android:exported=\"true\"           android:icon=\"@mipmap\/ic_launcher\"           android:targetActivity=\".MainActivity\"&gt;           &lt;intent-filter&gt;               &lt;action android:name=\"android.intent.action.MAIN\"\/&gt;               &lt;category android:name=\"android.intent.category.LAUNCHER\"\/&gt;           &lt;\/intent-filter&gt;       &lt;\/activity-alias&gt;       &lt;!-- Dark Variant Icon Alias --&gt;       &lt;activity-alias           android:name=\".DarkIcon\"           android:enabled=\"false\"           android:exported=\"true\"           android:icon=\"@mipmap\/ic_launcher_dark\"           android:targetActivity=\".MainActivity\"&gt;           &lt;intent-filter&gt;               &lt;action android:name=\"android.intent.action.MAIN\"\/&gt;               &lt;category android:name=\"android.intent.category.LAUNCHER\"\/&gt;           &lt;\/intent-filter&gt;       &lt;\/activity-alias&gt;       &lt;!-- Festive Variant Icon Alias --&gt;       &lt;activity-alias           android:name=\".FestiveIcon\"           android:enabled=\"false\"           android:exported=\"true\"           android:icon=\"@mipmap\/ic_launcher_festive\"           android:targetActivity=\".MainActivity\"&gt;           &lt;intent-filter&gt;               &lt;action android:name=\"android.intent.action.MAIN\"\/&gt;               &lt;category android:name=\"android.intent.category.LAUNCHER\"\/&gt;           &lt;\/intent-filter&gt;       &lt;\/activity-alias&gt;   &lt;\/application&gt;&lt;\/manifest&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>MainActivity.kt<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u0437 <code>MethodChannel<\/code> \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0446\u0438\u043a\u043b\u0430 \u0441\u043c\u0435\u043d\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<pre><code class=\"kotlin\">package com.dynamicicon.appimport android.content.ComponentNameimport android.content.pm.PackageManagerimport io.flutter.embedding.android.FlutterActivityimport io.flutter.embedding.engine.FlutterEngineimport io.flutter.plugin.common.MethodChannelclass MainActivity: FlutterActivity() {   private val CHANNEL = \"com.dynamicicon.app\/dynamic_icon\"   private val packageNamespace = \"com.dynamicicon.app\"   private val aliasRegistry = listOf(\"DefaultIcon\", \"DarkIcon\", \"FestiveIcon\")   override fun configureFlutterEngine(flutterEngine: FlutterEngine) {       super.configureFlutterEngine(flutterEngine)             MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -&gt;           if (call.method == \"setIcon\") {               val targetIcon = call.argument&lt;String&gt;(\"iconName\")               if (targetIcon != null &amp;&amp; aliasRegistry.contains(targetIcon)) {                   toggleLauncherComponent(targetIcon)                   result.success(null)               } else {                   result.error(\"ALIAS_NOT_FOUND\", \"The target alias mapping configuration is missing.\", null)               }           } else {               result.notImplemented()           }       }   }   private fun toggleLauncherComponent(targetAlias: String) {       val pm = applicationContext.packageManager             for (alias in aliasRegistry) {           val componentState = if (alias == targetAlias) {               PackageManager.COMPONENT_ENABLED_STATE_ENABLED           } else {               PackageManager.COMPONENT_ENABLED_STATE_DISABLED           }                     pm.setComponentEnabledSetting(               ComponentName(applicationContext, \"$packageNamespace.$alias\"),               componentState,               PackageManager.DONT_KILL_APP           )       }   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>3. \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f iOS (Info.plist \u0438 Swift)<\/h3>\n<p>\u041f\u043e\u043b\u043e\u0436\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u044b \u0432\u0430\u0448\u0438\u0445 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0438\u043a\u043e\u043d\u043e\u043a \u043f\u0440\u044f\u043c\u043e \u0432 \u043f\u0430\u043f\u043a\u0443 <code>ios\/Runner\/<\/code> \u0432 \u0432\u0438\u0434\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>ic_launcher_dart@2x.png<\/code>, <code>ic_launcher_festive@3x.png<\/code>).<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u044d\u0442\u0438 \u043a\u043b\u044e\u0447\u0438 \u0432 <code>ios\/Runner\/Info.plist<\/code>:<\/p>\n<pre><code class=\"xml\">&lt;key&gt;CFBundleIcons&lt;\/key&gt;&lt;dict&gt;   &lt;key&gt;CFBundlePrimaryIcon&lt;\/key&gt;   &lt;dict&gt;       &lt;key&gt;CFBundleIconFiles&lt;\/key&gt;       &lt;array&gt;           &lt;string&gt;AppIcon&lt;\/string&gt;       &lt;\/array&gt;   &lt;\/dict&gt;   &lt;key&gt;CFBundleAlternateIcons&lt;\/key&gt;   &lt;dict&gt;       &lt;key&gt;DarkIcon&lt;\/key&gt;       &lt;dict&gt;           &lt;key&gt;CFBundleIconFiles&lt;\/key&gt;           &lt;array&gt;               &lt;string&gt;ic_launcher_dark&lt;\/string&gt;           &lt;\/array&gt;           &lt;key&gt;UIPrerenderedIcon&lt;\/key&gt;           &lt;false\/&gt;       &lt;\/dict&gt;       &lt;key&gt;FestiveIcon&lt;\/key&gt;       &lt;dict&gt;           &lt;key&gt;CFBundleIconFiles&lt;\/key&gt;           &lt;array&gt;               &lt;string&gt;ic_launcher_festive&lt;\/string&gt;           &lt;\/array&gt;           &lt;key&gt;UIPrerenderedIcon&lt;\/key&gt;           &lt;false\/&gt;       &lt;\/dict&gt;   &lt;\/dict&gt;&lt;\/dict&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 <code>ios\/Runner\/AppDelegate.swift<\/code> \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 <code>MethodChannel<\/code>:<\/p>\n<pre><code class=\"swift\">import UIKitimport Flutter@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { override func application(   _ application: UIApplication,   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -&gt; Bool {     let controller : FlutterViewController = window?.rootViewController as! FlutterViewController   let iconChannel = FlutterMethodChannel(name: \"com.dynamicicon.app\/dynamic_icon\",                                          binaryMessenger: controller.binaryMessenger)     iconChannel.setMethodCallHandler({     (call: FlutterMethodCall, result: @escaping FlutterResult) -&gt; Void in     guard call.method == \"setIcon\" else {         result(FlutterMethodNotImplemented)         return     }         if let arguments = call.arguments as? [String: Any],        let iconName = arguments[\"iconName\"] as? String {         self.updateAlternateIcon(named: iconName, response: result)     } else {         result(FlutterError(code: \"BAD_ARGS\", message: \"Arguments malformed\", details: nil))     }   })   GeneratedPluginRegistrant.register(with: self)   return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func updateAlternateIcon(named targetName: String, response: @escaping FlutterResult) {     if #available(iOS 10.3, *) {         let systemKey = (targetName == \"DefaultIcon\") ? nil : targetName                 UIApplication.shared.setAlternateIconName(systemKey) { error in             if let error = error {                 response(FlutterError(code: \"IOS_ERROR\", message: error.localizedDescription, details: nil))             } else {                 response(null)             }         }     } else {         response(FlutterError(code: \"UNSUPPORTED_OS\", message: \"Minimum OS layout required\", details: nil))     } }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0428\u0430\u0433 2: \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043a\u043e\u043d\u043a\u0430\u043c\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0448 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u0434 \u0433\u043e\u0442\u043e\u0432, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c <strong>\u0440\u0443\u0447\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440<\/strong> \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <strong>\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 remote config<\/strong>.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0431\u044b\u0441\u0442\u0440\u043e, \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u043e: <strong>Firebase Remote Config \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435<\/strong>. \u0415\u0441\u043b\u0438 \u043a\u043b\u044e\u0447 \u0438\u0437 remote config \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u043b\u0430\u0447\u043d\u0443\u044e \u0430\u0434\u043c\u0438\u043d\u043a\u0443, \u0442\u043e \u043e\u043d \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u0415\u0441\u043b\u0438 \u043e\u0431\u043b\u0430\u0447\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u0430 \u0438\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>DefaultIcon<\/code>, \u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0443\u0447\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0432\u0430\u0448 <code>pubspec.yaml<\/code>:<\/p>\n<pre><code class=\"yaml\">dependencies: flutter:   sdk: flutter firebase_core: ^3.0.0 firebase_remote_config: ^5.0.0 shared_preferences: ^2.2.0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0434\u0432\u043e\u0439\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app_icon_manager.dart<\/code>, \u0447\u0442\u043e\u0431\u044b \u0447\u0435\u0442\u043a\u043e \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"dart\">import 'package:firebase_remote_config\/firebase_remote_config.dart';import 'package:shared_preferences\/shared_preferences.dart';import 'dynamic_icon_service.dart';class AppIconManager { static const String _remoteOverrideKey = 'cloud_icon_override'; static const String _userPrefKey = 'user_selected_icon'; static const String _activeCachedKey = 'currently_applied_icon'; \/\/\/ \u0420\u0435\u0436\u0438\u043c 1: \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0438\u043a\u043e\u043d\u043a\u0443 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f static Future&lt;void&gt; updateUserIconPreference(String targetIconName) async {   final SharedPreferences prefs = await SharedPreferences.getInstance();   await prefs.setString(_userPrefKey, targetIconName);     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u043b\u0430\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c   final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance;   final String cloudOverride = remoteConfig.getString(_remoteOverrideKey);   if (cloudOverride == 'DefaultIcon' || cloudOverride.isEmpty) {     await _applyIconSafetyGuard(targetIconName);   } else {     print(\"User setting cached, but blocked by active Cloud Override: $cloudOverride\");   } } \/\/\/ \u0420\u0435\u0436\u0438\u043c 2: \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e \u0432\u043e\u0437\u0434\u0443\u0445\u0443 static Future&lt;void&gt; syncCloudConfiguration() async {   final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance;   try {     await remoteConfig.setDefaults(&lt;String, dynamic&gt;{_remoteOverrideKey: 'DefaultIcon'});     await remoteConfig.setConfigSettings(RemoteConfigSettings(       fetchTimeout: const Duration(seconds: 10),       minimumFetchInterval: const Duration(hours: 2),     ));     bool updated = await remoteConfig.fetchAndActivate();     if (!updated) return;     final String cloudOverrideValue = remoteConfig.getString(_remoteOverrideKey);     final SharedPreferences prefs = await SharedPreferences.getInstance();     if (cloudOverrideValue != 'DefaultIcon' &amp;&amp; cloudOverrideValue.isNotEmpty) {       \/\/ \u041e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f       await _applyIconSafetyGuard(cloudOverrideValue);     } else {       \/\/ Fallback \u043d\u0430 \u0432\u044b\u0431\u043e\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f       final String userPreference = prefs.getString(_userPrefKey) ?? 'DefaultIcon';       await _applyIconSafetyGuard(userPreference);     }   } catch (e) {     print('Failed to synchronize Firebase Remote Config layer: $e');   } } \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a MethodChannel \u0435\u0441\u043b\u0438 \u0438\u043a\u043e\u043d\u043a\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0430 static Future&lt;void&gt; _applyIconSafetyGuard(String targetValue) async {   final SharedPreferences prefs = await SharedPreferences.getInstance();   final String currentlyActive = prefs.getString(_activeCachedKey) ?? 'DefaultIcon';   \/\/ \u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439   if (currentlyActive == targetValue) return;   print('Modifying launcher layout state from $currentlyActive to $targetValue');   await DynamicIconService.changeIcon(targetValue);   await prefs.setString(_activeCachedKey, targetValue); }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0428\u0430\u0433 3: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 UI \u0441\u043b\u043e\u0439 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0439\u0442\u0435 \u043d\u0430\u0448 \u0441\u043b\u043e\u0439 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>main()<\/code> \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430.<\/p>\n<pre><code class=\"dart\">import 'package:firebase_core\/firebase_core.dart';import 'package:flutter\/material.dart';import 'app_icon_manager.dart';void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); \/\/ \u0417\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f await AppIconManager.syncCloudConfiguration(); runApp(const MyApp());}class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) {   return const MaterialApp(     home: SettingsIconScreen(),   ); }}class SettingsIconScreen extends StatelessWidget { const SettingsIconScreen({super.key}); @override Widget build(BuildContext context) {   return Scaffold(     appBar: AppBar(title: const Text('Customize App Icon')),     body: Padding(       padding: const EdgeInsets.all(16.0),       child: Column(         crossAxisAlignment: CrossAxisAlignment.start,         children: [           const Text(             'Select Your Preference:',             style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),           ),           const SizedBox(height: 12),           ListTile(             leading: const Icon(Icons.phone_android),             title: const Text('Default Classic Blue'),             onTap: () =&gt; AppIconManager.updateUserIconPreference('DefaultIcon'),           ),           ListTile(             leading: const Icon(Icons.dark_mode),             title: const Text('Premium Minimalist Dark'),             onTap: () =&gt; AppIconManager.updateUserIconPreference('DarkIcon'),           ),           ListTile(             leading: const Icon(Icons.celebration),             title: const Text('Festive Celebration Theme'),             onTap: () =&gt; AppIconManager.updateUserIconPreference('FestiveIcon'),           ),         ],       ),     ),   ); }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u043e\u0431\u043b\u0430\u043a\u0430<\/h2>\n<p>\u041d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u0434\u0432\u043e\u0439\u043d\u043e\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e! \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u043e\u0437\u0434\u0443\u0445\u0443:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 <strong>\u041a\u043e\u043d\u0441\u043e\u043b\u044c Firebase<\/strong> \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043a <strong>Remote Config<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>cloud_icon_override<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0435\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>FestiveIcon<\/code> (\u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 <code>DefaultIcon<\/code>, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u043e\u0440 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c).<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 <strong>\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/strong><\/p>\n<\/li>\n<\/ol>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1051626\/\">https:\/\/habr.com\/ru\/articles\/1051626\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hola, Amigos! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u041f\u0430\u0432\u0435\u043b \u0413\u0435\u0440\u0448\u0435\u0432\u0438\u0447, Mobile Team Lead \u0430\u0433\u0435\u043d\u0442\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Amiga \u0438 \u0441\u043e\u0430\u0432\u0442\u043e\u0440 \u043a\u043d\u0438\u0433\u0438 &#171;\u041e\u0441\u043d\u043e\u0432\u044b Flutter&#187;. \u041c\u044b \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0441 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438. \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f!\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0447\u0435\u043d\u044c \u0446\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430. \u041a\u043e\u0433\u0434\u0430 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0430\u043c\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u044d\u0442\u043e \u0434\u0430\u0440\u0438\u0442 \u0438\u043c \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435 \u0447\u0443\u0432\u0441\u0442\u0432\u043e \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 \u044d\u0442\u0438\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043c\u0435\u043d\u044f\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0430\u0437\u0434\u043d\u0438\u043a\u0438, \u0440\u0435\u0431\u0440\u0435\u043d\u0434\u0438\u043d\u0433 \u0432 \u0442\u0435\u043c\u043d\u0443\u044e \u0442\u0435\u043c\u0443 \u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0441 \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u043e\u0432\u043e\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0435\u0439. \u0418 \u0432\u0441\u0435 \u044d\u0442\u043e \u0431\u0435\u0437 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438 \u0432 App Store \u0438\u043b\u0438 Google Play Store.\u0412 \u044d\u0442\u043e\u0439 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0438\u043a\u043e\u043d\u043e\u043a \u0432 Flutter, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0434\u0432\u0443\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445, \u043d\u0435 \u043f\u043e\u043b\u0430\u0433\u0430\u044f\u0441\u044c \u043d\u0430 \u0431\u0430\u0433\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438\u043b\u0438 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 MethodChannels \u043d\u0430 Kotlin \u0438 Swift \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0434\u0432\u0443\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:\u0420\u0443\u0447\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440: \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0430\u043c\u0438\u043c \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u043e \u0438\u0445 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u044f\u043c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 UI.\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u043e\u0437\u0434\u0443\u0445\u0443: \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043a\u043e\u043d\u043a\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 Firebase Remote Config.\u041a\u0430\u043a \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u0434\u0430, \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c. \u0422\u0430\u043a \u043a\u0430\u043a Flutter \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0435\u0434\u0438\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 API \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.Android: Component AliasesAndroid \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 AndroidManifest.xml. \u0427\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u044d\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f, \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0433\u043e\u0432 &lt;activity-alias&gt;, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 MainActivity. \u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 alias \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e PackageManager, \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u044d\u043a\u0440\u0430\u043d \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043a\u043e\u043d\u043a\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 alias.\u26a0\ufe0f \u041f\u043e\u0431\u043e\u0447\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442 \u043d\u0430 Android:\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 activity alias \u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0442\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430.iOS: API \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0438\u043a\u043e\u043d\u043e\u043aApple \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 UIApplication.shared.setAlternateIconName(). \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0430\u0441\u0441\u0435\u0442\u043e\u0432 (Assets.xcassets). \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (Info.plist).\u0428\u0430\u0433 1: \u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u04431. \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 MethodChannel \u0432 Flutter\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 \u0432\u0430\u0448\u0435\u043c Dart \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u043a\u0430\u043d\u0430\u043b\u0443 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439.import &#8216;package:flutter\/services.dart&#8217;;class DynamicIconService { static const MethodChannel _channel = MethodChannel(&#8216;com.dynamicicon.app\/dynamic_icon&#8217;); \/\/\/ \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u043c\u0435\u043d\u044b \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. static Future&lt;void&gt; changeIcon(String iconName) async {   try {     await _channel.invokeMethod(&#8216;setIcon&#8217;, {&#8216;iconName&#8217;: iconName});   } on PlatformException catch (e) {     print(&#171;Failed to change application launcher profile: &#8216;${e.message}&#8217;.&#187;);   } }}2. \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f Android (AndroidManifest.xml \u0438 Kotlin)\u0421\u043d\u0430\u0447\u0430\u043b\u0430, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u0441\u0441\u0435\u0442\u044b \u0432 \u0432\u0430\u0448\u0438 \u043f\u0430\u043f\u043a\u0438 \u0441 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438:android\/app\/src\/main\/res\/mipmap-hdpi\/ic_launcher_dark.pngandroid\/app\/src\/main\/res\/mipmap-hdpi\/ic_launcher_festive.png\u0414\u0430\u043b\u0435\u0435, \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 android\/app\/src\/main\/AndroidManifest.xml &#8212; \u043f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0443 android:enabled \u0443 .MainActivity \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 false. \u0422\u0430\u043a \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u0435 \u0445\u0443\u043a\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043d\u0430\u0448\u0438\u043c alias.&lt;manifest xmlns:android=&#187;http:\/\/schemas.android.com\/apk\/res\/android&#187;&gt;   &lt;application       android:label=&#187;Dynamic App&#187;       android:name=&#187;${applicationName}&#187;&gt;             &lt;!&#8212; Base Target Activity Framework (Deactivated) &#8212;&gt;       &lt;activity           android:name=&#187;.MainActivity&#187;           android:exported=&#187;true&#187;           android:enabled=&#187;false&#187;           android:launchMode=&#187;singleTop&#187;           android:theme=&#187;@style\/LaunchTheme&#187;&gt;           &lt;meta-data               android:name=&#187;io.flutter.embedding.android.NormalTheme&#187;               android:resource=&#187;@style\/NormalTheme&#187; \/&gt;       &lt;\/activity&gt;       &lt;!&#8212; Default Application Icon Alias &#8212;&gt;       &lt;activity-alias           android:name=&#187;.DefaultIcon&#187;           android:enabled=&#187;true&#187;           android:exported=&#187;true&#187;           android:icon=&#187;@mipmap\/ic_launcher&#187;           android:targetActivity=&#187;.MainActivity&#187;&gt;           &lt;intent-filter&gt;               &lt;action android:name=&#187;android.intent.action.MAIN&#187;\/&gt;               &lt;category android:name=&#187;android.intent.category.LAUNCHER&#187;\/&gt;           &lt;\/intent-filter&gt;       &lt;\/activity-alias&gt;       &lt;!&#8212; Dark Variant Icon Alias &#8212;&gt;       &lt;activity-alias           android:name=&#187;.DarkIcon&#187;           android:enabled=&#187;false&#187;           android:exported=&#187;true&#187;           android:icon=&#187;@mipmap\/ic_launcher_dark&#187;           android:targetActivity=&#187;.MainActivity&#187;&gt;           &lt;intent-filter&gt;               &lt;action android:name=&#187;android.intent.action.MAIN&#187;\/&gt;               &lt;category android:name=&#187;android.intent.category.LAUNCHER&#187;\/&gt;           &lt;\/intent-filter&gt;       &lt;\/activity-alias&gt;       &lt;!&#8212; Festive Variant Icon Alias &#8212;&gt;       &lt;activity-alias           android:name=&#187;.FestiveIcon&#187;           android:enabled=&#187;false&#187;           android:exported=&#187;true&#187;           android:icon=&#187;@mipmap\/ic_launcher_festive&#187;           android:targetActivity=&#187;.MainActivity&#187;&gt;           &lt;intent-filter&gt;               &lt;action android:name=&#187;android.intent.action.MAIN&#187;\/&gt;               &lt;category android:name=&#187;android.intent.category.LAUNCHER&#187;\/&gt;           &lt;\/intent-filter&gt;       &lt;\/activity-alias&gt;   &lt;\/application&gt;&lt;\/manifest&gt;\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b MainActivity.kt \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u0437 MethodChannel \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0446\u0438\u043a\u043b\u0430 \u0441\u043c\u0435\u043d\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:package com.dynamicicon.appimport android.content.ComponentNameimport android.content.pm.PackageManagerimport io.flutter.embedding.android.FlutterActivityimport io.flutter.embedding.engine.FlutterEngineimport io.flutter.plugin.common.MethodChannelclass MainActivity: FlutterActivity() {   private val CHANNEL = &#171;com.dynamicicon.app\/dynamic_icon&#187;   private val packageNamespace = &#171;com.dynamicicon.app&#187;   private val aliasRegistry = listOf(&#171;DefaultIcon&#187;, &#171;DarkIcon&#187;, &#171;FestiveIcon&#187;)   override fun configureFlutterEngine(flutterEngine: FlutterEngine) {       super.configureFlutterEngine(flutterEngine)             MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -&gt;           if (call.method == &#171;setIcon&#187;) {               val targetIcon = call.argument&lt;String&gt;(&#171;iconName&#187;)               if (targetIcon != null &amp;&amp; aliasRegistry.contains(targetIcon)) {                   toggleLauncherComponent(targetIcon)                   result.success(null)               } else {                   result.error(&#171;ALIAS_NOT_FOUND&#187;, &#171;The target alias mapping configuration is missing.&#187;, null)               }           } else {               result.notImplemented()           }       }   }   private fun toggleLauncherComponent(targetAlias: String) {       val pm = applicationContext.packageManager             for (alias in aliasRegistry) {           val componentState = if (alias == targetAlias) {               PackageManager.COMPONENT_ENABLED_STATE_ENABLED           } else {               PackageManager.COMPONENT_ENABLED_STATE_DISABLED           }                     pm.setComponentEnabledSetting(               ComponentName(applicationContext, &#171;$packageNamespace.$alias&#187;),               componentState,               PackageManager.DONT_KILL_APP           )       }   }}3. \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f iOS (Info.plist \u0438 Swift)\u041f\u043e\u043b\u043e\u0436\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u044b \u0432\u0430\u0448\u0438\u0445 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0438\u043a\u043e\u043d\u043e\u043a \u043f\u0440\u044f\u043c\u043e \u0432 \u043f\u0430\u043f\u043a\u0443 ios\/Runner\/ \u0432 \u0432\u0438\u0434\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, ic_launcher_dart@2x.png, ic_launcher_festive@3x.png).\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u044d\u0442\u0438 \u043a\u043b\u044e\u0447\u0438 \u0432 ios\/Runner\/Info.plist:&lt;key&gt;CFBundleIcons&lt;\/key&gt;&lt;dict&gt;   &lt;key&gt;CFBundlePrimaryIcon&lt;\/key&gt;   &lt;dict&gt;       &lt;key&gt;CFBundleIconFiles&lt;\/key&gt;       &lt;array&gt;           &lt;string&gt;AppIcon&lt;\/string&gt;       &lt;\/array&gt;   &lt;\/dict&gt;   &lt;key&gt;CFBundleAlternateIcons&lt;\/key&gt;   &lt;dict&gt;       &lt;key&gt;DarkIcon&lt;\/key&gt;       &lt;dict&gt;           &lt;key&gt;CFBundleIconFiles&lt;\/key&gt;           &lt;array&gt;               &lt;string&gt;ic_launcher_dark&lt;\/string&gt;           &lt;\/array&gt;           &lt;key&gt;UIPrerenderedIcon&lt;\/key&gt;           &lt;false\/&gt;       &lt;\/dict&gt;       &lt;key&gt;FestiveIcon&lt;\/key&gt;       &lt;dict&gt;           &lt;key&gt;CFBundleIconFiles&lt;\/key&gt;           &lt;array&gt;               &lt;string&gt;ic_launcher_festive&lt;\/string&gt;           &lt;\/array&gt;           &lt;key&gt;UIPrerenderedIcon&lt;\/key&gt;           &lt;false\/&gt;       &lt;\/dict&gt;   &lt;\/dict&gt;&lt;\/dict&gt;\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 ios\/Runner\/AppDelegate.swift \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 MethodChannel:import UIKitimport Flutter@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { override func application(   _ application: UIApplication,   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -&gt; Bool {     let controller : FlutterViewController = window?.rootViewController as! FlutterViewController   let iconChannel = FlutterMethodChannel(name: &#171;com.dynamicicon.app\/dynamic_icon&#187;,                                          binaryMessenger: controller.binaryMessenger)     iconChannel.setMethodCallHandler({     (call: FlutterMethodCall, result: @escaping FlutterResult) -&gt; Void in     guard call.method == &#171;setIcon&#187; else {         result(FlutterMethodNotImplemented)         return     }         if let arguments = call.arguments as? [String: Any],        let iconName = arguments[&#171;iconName&#187;] as? String {&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-484911","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/484911","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=484911"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/484911\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=484911"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=484911"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=484911"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}