在React Native中,如何"动态地"更改Android应用程序图标?

4
我在互联网上查找了一些包,比如这个不支持React Native Android,而这个没有很好的文档...
是否有其他适用于React Native Android的模块?或者我能以编程方式动态更改应用程序图标。
例如,当系统启用暗黑主题时,图标会更改为暗黑主题。或者像日历图标一样,显示当前日期。或者时钟显示随着时间秒数变化的表针等等。

你找到了任何有用的东西吗? - Oliver D
尚未。 - JeX
有什么新闻吗? - Paul
你可以编写一个Android代码来更改应用程序图标,并创建一个与React Native的桥接以调用该方法。以下是一些示例,说明如何在Android代码中进行更改 - 动态启动器图标动态更改启动器图标 - Nitish
1个回答

6
在安卓系统上启用动态图标更改有几个步骤。看起来很繁琐,但实际上非常容易1. 将所有图标放在 mipmap 文件夹中。 2. AndroidManifest.xml(为每个图标创建活动别名)<application> 下,主要的 <activity> 不应包含 intent-filter,且 android:exported 应设置为 true。这将使 MainActivity 始终可用而不显示快捷方式图标。
<activity
    android:name=".MainActivity"
    android:label="Test App"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
    android:launchMode="singleTask"
    android:windowSoftInputMode="adjustResize"
    android:exported="true"
>
</activity>

3.现在,对于您想要显示的每个图标,请创建<activity-alias>。将android:enabled设置为true以使用默认图标。 所有已启用的图标都将显示在桌面上。因此,请确保只启用一个活动别名。

<activity-alias
    android:label="Test App :: Default"
    android:icon="@mipmap/icon1"
    android:name="First"
    android:enabled="true"
    android:targetActivity=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity-alias>

<activity-alias
android:label="Test App :: Special"
android:icon="@mipmap/icon2"
android:name="Second"
android:enabled="false"
android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

<activity-alias
    android:label="Test App :: Very Special"
    android:icon="@mipmap/icon3"
    android:name="Third"
    android:enabled="false"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

4. 创建Java类

为您的每个活动别名创建一个空类。

package com.your.package;

class First {
}

5. 创建 IconChanger 类

@ReactMethod 允许从 React Native 访问该类。你可以将 com.your.package 替换为 BuildConfig.APPLICATION_ID,以避免多次编写包名。

package your.package.name;
import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.util.Map;
import java.util.HashMap;
import android.content.pm.PackageManager;
import android.content.ComponentName;
import com.facebook.react.bridge.Promise;
import android.os.Bundle;  
import android.widget.Toast; 

public class IconChanger extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;

    public IconChanger(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public String getName() {
        return "IconChanger";
    }

    @ReactMethod
    public void changeIcon(String enableIntent, String disableIntent, Promise response) {
        try {
            PackageManager packageManager = this.reactContext.getPackageManager();
            int action;
            String activeIntent="com.your.package."+enableIntent;

            Toast.makeText( this.reactContext,"Enabling "+enableIntent,Toast.LENGTH_SHORT).show();

            packageManager.setComponentEnabledSetting(
                new ComponentName("com.your.package", activeIntent), 
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP
            );

            if(!disableIntent.equals(null) && !disableIntent.equals(enableIntent)){
                activeIntent="com.your.package.."+disableIntent;
                Toast.makeText( this.reactContext,"Disabling "+disableIntent,Toast.LENGTH_SHORT).show();

                packageManager.setComponentEnabledSetting(
                    new ComponentName("com.your.package.", activeIntent), 
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP
                );
            }
            response.resolve(enableIntent);
        } catch (Exception e) {
            response.reject("Error", e);
        }
    }
}

6. 将其注册为 NativeModule

创建 CustomPackages.java 文件

package com.your.package;
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 CustomPackages implements ReactPackage {

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new IconChanger(reactContext));

        return modules;
    }
}

7. 现在将此包添加到您的MainApplication.java文件中

@Override
protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
    packages.add(new CustomPackages());
    return packages;
}

8. 从 react-native 中访问 IconChanger

import { NativeModules } from 'react-native';
const { IconChanger } = NativeModules;
IconChanger.changeIcon(newIcon, oldIcon);

[注意事项]

  • 这将启用新的活动,然后关闭旧的活动。

  • 在应用程序关闭或后台运行时更改图标,因为更改活动会关闭应用程序。


这似乎是对这个问题非常完整的回答。你能告诉我在mipmap文件夹中不同分辨率的合适图标尺寸是多少吗?(顺便说一句,我想你是指“mipmap”而不是“minimap”,对吧?) - Carlos Zinato
1
@CarlosZinato 对于错别字我很抱歉。 图标尺寸应该是: xxxhdpi(192 x 192),xxhdpi(144 x 144),xhdpi(96 x 96),hdpi(72 x 72),mdpi(48x48) - Shuhail Alam
您也可以考虑使用这个处理本地逻辑的包:https://github.com/skb1129/react-native-change-icon - Rohan Kadkol
iOS怎么样? - Vikas chhabra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接