更改通知 RemoteViews 的背景颜色

4

我遇到了一个问题,无法在应用程序主题中更改背景颜色。

NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this);

TypedValue typedValue = new TypedValue();

getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);

int iPrimaryColor = typedValue.data;

getTheme().resolveAttribute(R.attr.colorPrimaryDark, typedValue, true);

int iPrimaryDarkColor = typedValue.data;

Intent notIntent = new Intent(getApplicationContext(), MainActivity.class);
notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

PendingIntent notOpenOnClick = PendingIntent.getActivity(getApplicationContext(), 0, notIntent, PendingIntent.FLAG_UPDATE_CURRENT);

RemoteViews smallContentView = new RemoteViews(getPackageName(), R.layout.notification_small);
RemoteViews bigContentView = new RemoteViews(getPackageName(), R.layout.notification_expanded);

nBuilder.setSmallIcon(R.drawable.not_icon)
    .setOngoing(true)
    .setContentTitle(getCurrentSong().getTitle())
    .setContentIntent(notOpenOnClick);

Notification not = nBuilder.build();

smallContentView.setInt(R.id.not_linLayout, "setBackgroundColor", iPrimaryColor);
smallContentView.setInt(R.id.not_imvDivider, "setBackgroundColor", iPrimaryDarkColor);

bigContentView.setInt(R.id.not_linLayout, "setBackgroundColor", iPrimaryColor);
bigContentView.setInt(R.id.not_imvDivider, "setBackgroundColor", iPrimaryDarkColor);

setListeners(smallContentView);
setListeners(bigContentView);

not.contentView = smallContentView;
not.bigContentView = bigContentView;

if (isPlaying()) {
    not.contentView.setImageViewResource(R.id.not_btnPlayPause, R.drawable.ic_pause_48dp);
    not.bigContentView.setImageViewResource(R.id.not_btnPlayPause, R.drawable.ic_pause_48dp);
}
else {
    not.contentView.setImageViewResource(R.id.not_btnPlayPause, R.drawable.ic_play_48dp);
    not.bigContentView.setImageViewResource(R.id.not_btnPlayPause, R.drawable.ic_play_48dp);
}

我已经尝试过这个方法,但我的通知背景仍然是白色的。 ID是正确的,View linLayout是一个LinearLayout。
请记住:整个代码是在服务中调用的!
谢谢!

看起来您正在尝试构建媒体控制通知。请不要使用自定义通知,而是使用[NotificationCompat.MediaStyle](https://developer.android.com/reference/android/support/v7/app/NotificationCompat.MediaStyle.html) - ianhanniballake
好的,但为什么使用MediaStyle更好呢? - the_dani
1)适用于API 7+设备;2)使用Lollipop+内置样式;3)自动适应新的Android N通知样式;4)具有自定义背景颜色的内置支持;5)具有解决在早期版本的前台服务中关闭通知问题的内置支持;6)支持添加您的MediaSession令牌以使Android Wear控件工作。这只是其中的几个功能。 - ianhanniballake
你应该观看2016年媒体播放I/O的最佳实践演讲。链接 - ianhanniballake
好的,太棒了,谢谢 :) - the_dani
2个回答

9

通过利用NotificationCompat.MediaStyle,这些可以更容易地完成。它从预API 24设备上的setColor()调用中提取背景颜色(并在API 24+设备上将该颜色用作强调)。这也意味着您不再需要编写任何自定义RemoteViews代码,因为它仅依赖于您添加到通知的媒体控件操作:

NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this);
nBuilder.setSmallIcon(R.drawable.not_icon)
  .setContentTitle(getCurrentSong().getTitle())
  .setContentIntent(notOpenOnClick);
// This is what sets the background color on <N devices
// It is an accent color on N+ devices
nBuilder.setColor(getResources().getColor(R.color.colorPrimary));
// Add actions via nBuilder.addAction()
// Set the style, setShowActionsInCompactView(0) means the first
// action you've added will be shown the non-expanded view
nBuilder.setStyle(new NotificationCompat.MediaStyle()
  .setShowActionsInCompactView(0));

你应该仔细阅读所有可用的MediaStyle方法,并查看2016年媒体播放I/O最佳实践演讲,以获取有关使用通知的示例代码和最佳实践。特别是在演讲30分钟处

2
你可以贴出一个示例代码吗?我尝试找到一些有用的东西,但是例如背景颜色仍然保持黑色。 - the_dani

5

setColorized文档说明:

设置此通知是否应该着色。当设置时,将使用使用setColor(int)设置的颜色作为此通知的背景颜色

这仅应用于用户高优先级的持续任务,如导航、持续通话或其他类似的高优先级事件。

对于大多数样式,只有在通知是前台服务通知时才会应用着色。

但是,对于附有媒体会话的MediaStyle和DecoratedMediaCustomViewStyle通知不存在此要求。

在O之前的任何版本上调用此方法都不会影响通知,也不会着色。

Kotlin代码:

import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import androidx.core.app.NotificationCompat
import androidx.media.app.NotificationCompat.DecoratedMediaCustomViewStyle

// create a MediaSession so that we can create a DecoratedMediaCustomViewStyle
val mediaSession = MediaSessionCompat(applicationContext,"tag")
mediaSession.setFlags(0)
mediaSession.setPlaybackState(PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_NONE,0,0f)
        .build())

// create & display the colorized notification
notificationManager.notify(
        0,
        NotificationCompat
                .Builder(this,notificationChannel)
                .setStyle(DecoratedMediaCustomViewStyle()
                        .setMediaSession(mediaSession.sessionToken))
                .setSmallIcon(R.drawable.ic_app_foreground)
                .setColor(getColor(android.R.color.black))
                .setColorized(true)
                .setContentText("Hello, World!")
                .build())

....

// cleanup upon dismissing the notification
mediaSession.release()

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