为什么我无法从 Android 中的服务读取字符串资源

Why Can't I Read String Resources from a Service in Android

所以我很确定这是 Context 的一个问题,我知道那里有很多相关的问题(我已经阅读过)但是我找不到与我的具体情况相匹配的问题所以希望有人可以提供帮助。 我正在 API 28,最小 24,语言级别 7 和 运行 在 Android 7 Samsung 平板电脑上构建。

情况

在我的项目中,我有一个 Service 旨在在设备启动时启动,它确实如此。为了亲自验证这一点,我让服务发出通知。一旦我开始工作,我就清理了代码并将所有标题、名称等移动到 strings.xml 文件中的字符串资源中。

问题

通知不再出现。如果我使用硬编码字符串,一切都很好,如果我尝试使用字符串资源,则通知失败。我的猜测是,这与 Context (从中请求字符串)有关,并且它无法访问它们。然而,在硬编码字符串的情况下,图标资源(可绘制)和颜色资源都被成功查询,所以我不清楚字符串有什么区别。我可以对字符串进行硬编码,然后收工,但我觉得这违背了 Android 最佳实践。我还应该注意,如果我实际启动应用程序,资源一切正常,这只是“启动”条件下的问题。

有人知道我做错了什么吗?

根据要求:代码

这个有效:

public static void notify(Context context, String text){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
                "CHANNEL",
                "My App",
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("Service status update channel");
        NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
    NotificationCompat.Builder n  = new NotificationCompat.Builder(context, "CHANNEL")
            .setContentTitle("Status")
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
            .setOngoing(true)
            .setAutoCancel(false)
            .setOnlyAlertOnce(true);
    NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
    notificationManager.notify(notification_id, n.build());
}

这不是:

public static void notify(Context context, String text){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
                context.getString(R.string.notification_channel),
                context.getString(R.string.notification_channel_name),
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription(context.getString(R.string.notification_channel_desc));
        NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
    NotificationCompat.Builder n  = new NotificationCompat.Builder(context, context.getString(R.string.notification_channel))
            .setContentTitle(context.getString(R.string.notification_title))
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
            .setOngoing(true)
            .setAutoCancel(false)
            .setOnlyAlertOnce(true);
    NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
    notificationManager.notify(notification_id, n.build());
}

我从 ServiceonStartCommand

调用这个方法
@Override
public int onStartCommand(Intent intent, int flags, int startId){
    UIHelper.notify(getApplicationContext(), "hello");
    return IntentService.START_STICKY;
}

将您对 getApplicationContext() 的调用替换为 this:

UIHelper.notify(this, "hello");

此外,使用 context.getResources().getString() 而不是 context.getString()

不幸的是,我真的无法解释为什么会这样。

我的想法是您正在制作前台服务,因此该服务的通知应该属于服务本身(它扩展了上下文)而不是应用程序。

理论上context.getString()context.getResources().getString()是完全一样的(其实只是一种代理方式),虽然只是在Marshmallow中引入