dynamic_icon_changer 0.0.1
dynamic_icon_changer: ^0.0.1 copied to clipboard
A Flutter plugin for dynamically changing app icons on Android and iOS based on schedules or events. Includes automatic festival handling and Android relaunch support.
dynamic_icon_changer #
A Flutter plugin to dynamically change the app icon based on upcoming festivals, sales, or any specific timeline. Supports both Android and iOS.
Features #
- Programmatic Icon Switching: Change the app icon at runtime via Dart.
- Automatic Festival/Sale Icons: Automatically switch icons based on a predefined schedule of date ranges.
- Robust Android Relaunch: Optionally relaunch the app after an icon change on Android to ensure the launcher reflects the update immediately.
- iOS Retry Mechanism: Automatically retries icon changes on iOS if the system is busy (Error 35).
- Global Throttling: Built-in 10-second throttling to prevent OS errors from frequent switching.
- Case-Insensitive Matching: (Android) Matches icon names to manifest aliases regardless of casing.
Getting Started #
1. Define Your Icons #
First, you need to prepare your icon assets for both platforms.
Android Setup
Android uses Activity Aliases. You must define an alias for each alternate icon in your android/app/src/main/AndroidManifest.xml.
- Keep your
MainActivityclean of theLAUNCHERintent filter. - Add an
activity-aliasfor each icon (including the default one).
<manifest ...>
<application ...>
<activity
android:name=".MainActivity"
...>
<!-- Remove LAUNCHER intent filter from here -->
</activity>
<!-- Default Icon Alias -->
<activity-alias
android:name=".MainActivityDefault"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:targetActivity=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- Christmas Icon Alias -->
<activity-alias
android:name=".MainActivityChristmas"
android:enabled="false"
android:icon="@mipmap/ic_launcher_christmas"
android:targetActivity=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
</manifest>
iOS Setup
iOS uses the setAlternateIconName API. You must configure CFBundleIcons in your ios/Runner/Info.plist.
- Add your icon files to the Xcode project (not just the Assets catalog, but as files in the Bundle).
- Update
Info.plist:
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>christmas</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>christmas</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
Usage #
Simple Manual Switch #
import 'package:dynamic_icon_changer/dynamic_icon_changer.dart';
final iconChanger = DynamicIconChanger();
// Android requires the list of all aliases defined in manifest
final androidAliases = [
'.MainActivityDefault',
'.MainActivityChristmas',
'.MainActivitySales'
];
// Switch to Christmas icon
// 'relaunch: true' will automatically reopen the app on Android
await iconChanger.setIcon(
'christmas',
androidActiveAliases: androidAliases,
relaunch: true,
);
// Reset to Default
await iconChanger.setIcon(
null,
androidActiveAliases: androidAliases,
relaunch: true,
);
Automatic Festival Logic #
The plugin provides a helper to handle date-based icon rotation automatically.
await iconChanger.handleAutomaticIconChange(
festivals: {
'christmas': [
DateTimeRange(
start: DateTime(now.year, 12, 1),
end: DateTime(now.year, 12, 31),
),
],
'sales': [
DateTimeRange(
start: DateTime(now.year, 1, 1),
end: DateTime(now.year, 1, 10),
),
],
},
defaultIcon: 'Default',
androidActiveAliases: androidAliases,
relaunch: true,
);
Important Considerations #
- Throttling: The
setIconmethod is internally throttled to once every 10 seconds to avoid OS-level errors and ensure stability. - iOS Behavior: The system displays a mandatory alert: "You have changed the icon for [App Name]." This cannot be disabled.
- Android Behavior: Changing the icon involves enabling/disabling manifest components. This usually triggers a launcher refresh. Using
relaunch: trueuses anAlarmManagerto automatically bring the app back to the foreground after the switch. - Case Sensitivity: On Android, matching between the
iconNameand the alias suffix is case-insensitive.