diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 0d403611..eb601acd 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -52,5 +52,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/java/fun/upup/musicfree/MainApplication.java b/android/app/src/main/java/fun/upup/musicfree/MainApplication.java
index ae3b0b80..eacac5e6 100644
--- a/android/app/src/main/java/fun/upup/musicfree/MainApplication.java
+++ b/android/app/src/main/java/fun/upup/musicfree/MainApplication.java
@@ -11,6 +11,7 @@
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.soloader.SoLoader;
+import fun.upup.musicfree.appIconUtil.AppIconUtilPackage;
import fun.upup.musicfree.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
@@ -39,6 +40,7 @@ protected List getPackages() {
packages.add(new UtilsPackage());
packages.add(new Mp3UtilPackage());
packages.add(new LyricUtilPackage());
+ packages.add(new AppIconUtilPackage(getPackageName()));
return packages;
}
diff --git a/android/app/src/main/java/fun/upup/musicfree/appIconUtil/AppIconUtilModule.java b/android/app/src/main/java/fun/upup/musicfree/appIconUtil/AppIconUtilModule.java
new file mode 100644
index 00000000..9434ecb6
--- /dev/null
+++ b/android/app/src/main/java/fun/upup/musicfree/appIconUtil/AppIconUtilModule.java
@@ -0,0 +1,173 @@
+// 参考:https://blog.stackademic.com/change-the-app-icon-at-runtime-for-react-native-by-creating-a-nativemodule-5bfb285bd69b
+package fun.upup.musicfree.appIconUtil;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.app.Activity;
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.facebook.react.bridge.Promise;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+public class AppIconUtilModule extends ReactContextBaseJavaModule implements Application.ActivityLifecycleCallbacks {
+ private static ReactApplicationContext reactContext;
+
+ private final String packageName;
+
+ public static final String MAIN_ACTVITY_BASE_NAME = ".MainActivity";
+
+ private String componentClass = "";
+
+ private final Set classesToKill = new HashSet<>();
+
+ public AppIconUtilModule(ReactApplicationContext context, String packageName) {
+ super(context);
+ reactContext = context;
+ this.packageName = packageName;
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return "AppIconUtil";
+ }
+
+ @ReactMethod
+ public void getIcon(Promise promise) {
+ final Activity activity = getCurrentActivity();
+ if (activity == null) {
+ promise.reject("ACTIVITY_NOT_FOUND", "Activity was not found");
+ return;
+ }
+
+ final String activityName = activity.getComponentName().getClassName();
+
+ if (activityName.endsWith(MAIN_ACTVITY_BASE_NAME)) {
+ promise.resolve("Default");
+ return;
+ }
+ String[] activityNameSplit = activityName.split("MainActivity");
+ if (activityNameSplit.length != 2) {
+ promise.reject("ANDROID:UNEXPECTED_COMPONENT_CLASS:", this.componentClass);
+ return;
+ }
+ promise.resolve(activityNameSplit[1]);
+ }
+
+ @ReactMethod
+ public void changeIcon(String iconName, Promise promise) {
+
+ final Activity activity = getCurrentActivity();
+
+ if (activity == null) {
+ promise.reject("ACTIVITY_NOT_FOUND", "The activity is null. Check if the app is running properly.");
+ return;
+ }
+ if (iconName.isEmpty()) {
+ promise.reject("EMPTY_ICON_STRING", "Icon name is missing i.e. changeIcon('YOUR_ICON_NAME_HERE')");
+ return;
+ }
+ if (this.componentClass.isEmpty()) {
+ this.componentClass = activity.getComponentName().getClassName(); // i.e. MyActivity
+ }
+
+ final String activeClass = this.packageName + MAIN_ACTVITY_BASE_NAME + iconName;
+
+ if (this.componentClass.equals(activeClass)) {
+ promise.reject("ICON_ALREADY_USED", "This icons is the current active icon. " + this.componentClass);
+ return;
+ }
+
+ try {
+ activity.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(this.packageName, activeClass),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP
+ );
+ promise.resolve(iconName);
+ } catch (Exception e) {
+ promise.reject("ICON_INVALID", e.getLocalizedMessage());
+ return;
+ }
+
+ this.classesToKill.add(this.componentClass);
+ this.componentClass = activeClass;
+ activity.getApplication().registerActivityLifecycleCallbacks(this);
+// The completeIconChange() is what makes the current active class disabled.
+// Move it to onActivityPaused or onActivityStopped etc to change the icon only when the app closes or goes to background
+ completeIconChange();
+ }
+
+ private void completeIconChange() {
+ final Activity activity = getCurrentActivity();
+ if (activity == null) return;
+
+// Works for minSdkVersion = 23
+ for (String className : classesToKill) {
+ activity.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(this.packageName, className),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP
+ );
+ }
+/*
+ // Works for minSdkVersion = 24 and above
+ classesToKill.forEach((cls) -> activity.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(this.packageName, cls),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP
+ ));
+*/
+ classesToKill.clear();
+ }
+
+ @Override
+ public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
+
+ }
+
+ @Override
+ public void onActivityStarted(@NonNull Activity activity) {
+
+ }
+
+ @Override
+ public void onActivityResumed(@NonNull Activity activity) {
+
+ }
+
+ @Override
+ public void onActivityPaused(@NonNull Activity activity) {
+
+ }
+
+ @Override
+ public void onActivityStopped(@NonNull Activity activity) {
+
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {
+
+ }
+
+ @Override
+ public void onActivityDestroyed(@NonNull Activity activity) {
+
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/fun/upup/musicfree/appIconUtil/AppIconUtilPackage.java b/android/app/src/main/java/fun/upup/musicfree/appIconUtil/AppIconUtilPackage.java
new file mode 100644
index 00000000..424a258e
--- /dev/null
+++ b/android/app/src/main/java/fun/upup/musicfree/appIconUtil/AppIconUtilPackage.java
@@ -0,0 +1,35 @@
+package fun.upup.musicfree.appIconUtil;
+
+import com.facebook.react.ReactPackage;
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.ViewManager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class AppIconUtilPackage implements ReactPackage {
+
+ private final String packageName;
+
+ public AppIconUtilPackage(String packageName) {
+ this.packageName = packageName;
+ }
+
+ @Override
+ public List createViewManagers(ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List createNativeModules(
+ ReactApplicationContext reactContext) {
+ List modules = new ArrayList<>();
+
+ modules.add(new AppIconUtilModule(reactContext, this.packageName));
+
+ return modules;
+ }
+
+}
\ No newline at end of file
diff --git a/android/app/src/main/musicfree_logo_1-playstore.png b/android/app/src/main/musicfree_logo_1-playstore.png
new file mode 100644
index 00000000..213604a8
Binary files /dev/null and b/android/app/src/main/musicfree_logo_1-playstore.png differ
diff --git a/android/app/src/main/res/drawable-v24/musicfree_logo_1_foreground.xml b/android/app/src/main/res/drawable-v24/musicfree_logo_1_foreground.xml
new file mode 100644
index 00000000..d790786b
--- /dev/null
+++ b/android/app/src/main/res/drawable-v24/musicfree_logo_1_foreground.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/musicfree_logo_1.xml b/android/app/src/main/res/mipmap-anydpi-v26/musicfree_logo_1.xml
new file mode 100644
index 00000000..d7fd15f5
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/musicfree_logo_1.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/musicfree_logo_1_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/musicfree_logo_1_round.xml
new file mode 100644
index 00000000..d7fd15f5
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/musicfree_logo_1_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-hdpi/musicfree_logo_1.png b/android/app/src/main/res/mipmap-hdpi/musicfree_logo_1.png
new file mode 100644
index 00000000..206e1450
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/musicfree_logo_1.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/musicfree_logo_1_round.png b/android/app/src/main/res/mipmap-hdpi/musicfree_logo_1_round.png
new file mode 100644
index 00000000..0e5b0ead
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/musicfree_logo_1_round.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/musicfree_logo_1.png b/android/app/src/main/res/mipmap-mdpi/musicfree_logo_1.png
new file mode 100644
index 00000000..ae1844f6
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/musicfree_logo_1.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/musicfree_logo_1_round.png b/android/app/src/main/res/mipmap-mdpi/musicfree_logo_1_round.png
new file mode 100644
index 00000000..45e631df
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/musicfree_logo_1_round.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/musicfree_logo_1.png b/android/app/src/main/res/mipmap-xhdpi/musicfree_logo_1.png
new file mode 100644
index 00000000..38e3a779
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/musicfree_logo_1.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/musicfree_logo_1_round.png b/android/app/src/main/res/mipmap-xhdpi/musicfree_logo_1_round.png
new file mode 100644
index 00000000..98dad35a
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/musicfree_logo_1_round.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/musicfree_logo_1.png b/android/app/src/main/res/mipmap-xxhdpi/musicfree_logo_1.png
new file mode 100644
index 00000000..673d5133
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/musicfree_logo_1.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/musicfree_logo_1_round.png b/android/app/src/main/res/mipmap-xxhdpi/musicfree_logo_1_round.png
new file mode 100644
index 00000000..42268056
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/musicfree_logo_1_round.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/musicfree_logo_1.png b/android/app/src/main/res/mipmap-xxxhdpi/musicfree_logo_1.png
new file mode 100644
index 00000000..579d1b8f
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/musicfree_logo_1.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/musicfree_logo_1_round.png b/android/app/src/main/res/mipmap-xxxhdpi/musicfree_logo_1_round.png
new file mode 100644
index 00000000..999c364e
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/musicfree_logo_1_round.png differ
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
index 7d20811f..3537a279 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,3 +1,3 @@
- #FFF7C1
+ #F7F7F1
\ No newline at end of file
diff --git a/android/app/src/main/res/values/musicfree_logo_1_background.xml b/android/app/src/main/res/values/musicfree_logo_1_background.xml
new file mode 100644
index 00000000..f236b946
--- /dev/null
+++ b/android/app/src/main/res/values/musicfree_logo_1_background.xml
@@ -0,0 +1,4 @@
+
+
+ #F1F2F3
+
\ No newline at end of file
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
index 3ef64030..1280cb6a 100644
--- a/android/app/src/main/res/values/styles.xml
+++ b/android/app/src/main/res/values/styles.xml
@@ -5,7 +5,7 @@
- @drawable/rn_edit_text_material
-