安卓O:通知渠道本地化

16

我创建了一个类似这样的通知渠道:

NotificationChannel channel = new NotificationChannel(CHANNEL_ID_FOOBAR, getContext().getString(R.string.notification_channel_foobar), NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);

我为 R.string.notification_channel_foobar 提供了不同的翻译,该通知频道是以创建时使用的语言创建的,因此如果我最终更改设备的语言,则该通道将保留旧语言。是否有一种方法可以克服这个问题,还是这是一种限制,即设计上的问题?


你可以使用SharedPreference来实现这个功能。 - Ankita
4个回答

25

要将新语言应用于您的通知渠道,您需要在应用程序中侦听ACTION_LOCALE_CHANGED广播,并在接收器中再次调用createNotificationChannel。

重新创建渠道将更新您的字符串以适配新语言(其他任何渠道功能都不会被修改)。您可以在文档中查看它。


我不知道为什么你会被踩,因为这是正确的。唯一需要补充的是,在重新创建具有新本地化名称的通道时,需要使用相同的通道ID。 - ZoltanF
重要的是要提到,我们不想重新创建整个频道,即删除和创建,因为这将在通知设置中显示频道为n已删除,但我们只想使用上述API允许的方法更新频道名称和描述。 - Himanshu Walia

2
每次启动主活动时,您都可以简单地创建频道。这是一种非常优雅的解决方案,而无需使用任何广播接收器。这样,即使您添加更多语言,该频道也将始终从字符串资源中获得最新值。(过早优化是万恶之源。) 如果尚未创建频道,则createNotificationChannel命令将创建该频道,并且如果已经创建,则会更新该频道。
如果频道已经创建,则您唯一可以更改的是频道的名称描述,除此之外没有其他更改。重要性将被忽略,因为用户可能已手动更改了频道的重要性。但即使他们没有更改,重要性也不会更新,实际上这就是通知频道的目的。为用户提供管理其频道的自由,而不是在应用程序更新时由开发人员干扰他们。
因此,总之,通过声明:
NotificationChannel notificationChannel = new NotificationChannel("channel id", "channel new name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(notificationChannel);

在已经创建的频道中,频道名称将会被更新,但不会更改其重要性。如果你想同时更新频道描述,可以按照以下方式进行:

notificationChannel.setDescription("new description"); //set that before creating the channel

1
一旦您创建了一个频道,就不能更改任何内容。由于我们为频道名称提供“字符串”,系统将始终向用户表示此名称。
您可以尝试的一件(坏)事情是删除旧频道并创建另一个具有当前语言名称的频道。
您可以在问题跟踪器中请求此功能增强。 更新- @jmart的回答是正确的。https://dev59.com/ElYO5IYBdhLWcg3wHuIA#46670618

1
确实,我得出了同样的结论。谢谢。 - Alécio Carvalho
如官方文档所述,您可以调用createNotificationChannel()方法,然后将通知渠道再次提交给通知管理器以重命名现有的通知渠道或更新其描述(我在我的应用程序中刚刚这样做了)。链接:https://developer.android.com/guide/topics/ui/notifiers/notifications.html#UpdateChannel - jmart
谢谢@jmart,很清楚了...缺点是它将丢失用户已更改的当前通道设置,迫使他们重新配置。所以我想知道是否会有更好的解决方案,可以已经处理本地化更改。 - Alécio Carvalho
1
@AlécioCarvalho 用户设置不会丢失。在已经存在的通道上调用 createNotificationChannel 仅会修改通道的名称和描述(这是设计如此)。只有用户可以修改他们的设置,而只有您可以修改名称和描述。 - jmart
@jmart 是这样吗?更改该频道上的用户不会受到影响?嗯,有没有参考资料我可以确认一下?在文档中只提到了重命名和更改描述,而没有涉及其他设置(例如声音URI、振动设置等)。你明白我的意思吗? - Alécio Carvalho
@AlécioCarvalho "对于已经存在的通道,所有其他字段都将被忽略" 链接:https://developer.android.com/reference/android/app/NotificationManager.html#createNotificationChannel(android.app.NotificationChannel) - jmart

0

这是我的解决方案:

public class AlarmReceiver extends BroadcastReceiver {

public static String NOTIFICATION_CHANNEL_ID = "notification-id";
public static String NOTIFICATION = "Notification";
public static String DESCRIPTION = "Channel description";

@TargetApi(26)
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Log.e("RECEIVE", "received2");


    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);


    //PendingIntent pendingIntent = PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    PendingIntent pi = PendingIntent.getActivity(context, intent.getIntExtra("NotifID", 1), new Intent(context, CalendarActivity.class),PendingIntent.FLAG_CANCEL_CURRENT);

    // get current locale
    String locale; // for getting locale
    locale = Locale.getDefault().getLanguage();
    if(locale.equalsIgnoreCase("sk")) {
        NOTIFICATION = "Notifikácia";
        DESCRIPTION = "Popis";
    }

        if (VERSION.SDK_INT >= 26) {
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION, NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setDescription(DESCRIPTION);
            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.GREEN);

            notificationChannel.setLockscreenVisibility(Notification.DEFAULT_SOUND);
            notificationChannel.setVibrationPattern(new long[]{1000, 500, 500, 200, 200, 200});
            notificationChannel.enableVibration(true);
            manager.createNotificationChannel(notificationChannel);

        }



        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
        builder.setAutoCancel(true)
            .setDefaults(Notification.DEFAULT_ALL)
            .setWhen(System.currentTimeMillis())
            .setContentTitle(intent.getStringExtra("AppName"))
            .setContentText(intent.getStringExtra("lname"))
            .setSmallIcon(R.drawable.ic_launcher)
            ;

        //manager.notify(1,builder.build());
    manager.notify(intent.getIntExtra("NotifID", 1), builder.build());

}

}


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