带有 RemoteViews 的 Android 自定义通知布局

Posted

技术标签:

【中文标题】带有 RemoteViews 的 Android 自定义通知布局【英文标题】:Android custom notification layout with RemoteViews 【发布时间】:2014-04-22 14:13:03 【问题描述】:

我正在尝试使用此 post 为我的 android 应用程序创建自定义通知,但我偶然发现了一个问题,我在过去 2 小时内试图解决该问题。

仅显示我的布局的 imageview,我不知道如何使其按预期工作。

我的代码:

package be.ac.ucl.lfsab1509.cumulus.services;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.widget.RemoteViews;
import be.ac.ucl.lfsab1509.cumulus.R;
import be.ac.ucl.lfsab1509.cumulus.activities.MainActivity;
import be.ac.ucl.lfsab1509.cumulus.entities.Song;

public class CumulusNotification 

private CumulusService mCtx;
private CumulusMediaPlayer mPlayer;
private Notification mNotification;
private NotificationCompat.Builder mBuilder;
private RemoteViews mContentView;

public CumulusNotification(CumulusService ctx, CumulusMediaPlayer player)
    mCtx = ctx;
    mPlayer = player;

    mBuilder = new NotificationCompat.Builder(
            mCtx);
    mBuilder.setSmallIcon(R.drawable.ic_stat_cumulus_notification);
    //mBuilder.setContentTitle("Cumulus is playing");
    //mBuilder.setTicker("Cumulus");
    //mBuilder.setContentText(mCtx.getCurrentSong().title());

    Intent resultIntent = new Intent(mCtx, MainActivity.class);
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    resultIntent.setAction(Intent.ACTION_MAIN);
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(mCtx);
    stackBuilder.addParentStack(MainActivity.class);
    stackBuilder.addNextIntent(resultIntent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(resultPendingIntent);

    mContentView = new RemoteViews(mCtx.getPackageName(), R.layout.statusbar);
    mContentView.setImageViewResource(R.id.notifimage, R.drawable.cumulus_icon);
    mContentView.setTextViewText(R.id.notiftitle, "Custom notification");
    mContentView.setTextViewText(R.id.notiftext, "This is a custom layout");
    mBuilder.setContent(mContentView);


public void startNotification() 
    mNotification = mBuilder.build();
    //mNotification.contentView = mContentView;
    mCtx.startForeground(R.integer.NOTIFICATION_ID, mNotification);


public void updateSong(Song song)
    mBuilder.setContentText(song.title());
    mNotification = mBuilder.build();
    mCtx.startForeground(R.integer.NOTIFICATION_ID, mNotification);


xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_
android:layout_
android:padding="10dp"
android:gravity="left" >
<ImageView android:id="@+id/notifimage"
    android:layout_
    android:layout_
    android:layout_alignParentLeft="true"
    android:layout_marginRight="10dp" />
<TextView android:id="@+id/notiftitle"
    android:layout_
    android:layout_
    android:layout_toRightOf="@id/notifimage" />
<TextView android:id="@+id/notiftext"
    android:layout_
    android:layout_
    android:layout_toRightOf="@id/notifimage"
    android:layout_below="@id/notiftitle" />
</RelativeLayout>

感谢您的帮助

【问题讨论】:

如果您发布 statusbar.xml 可以帮助您更轻松地修复布局... 完成!就像我说的,就像在原帖中一样 @HappyRave - 你能解决它吗?我面临同样的问题。谢谢 为什么两个 TextView 上都有 android:layout_toRightOf="@id/notifimage" 【参考方案1】:

问题是你没有设置正确的 contentView。

mBuilder.setContent(contentView);

但是您的远程视图是 mContentView。改成

mBuilder.setContent(mContentView);

这是一个示例

    NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher);

    RemoteViews mContentView = new RemoteViews(getPackageName(), R.layout.test_tt);
    mContentView.setImageViewResource(R.id.image, R.drawable.ic_action_search);
    mContentView.setTextViewText(R.id.title, "Custom notification");
    mContentView.setTextViewText(R.id.text, "This is a custom layout");
    mBuilder.setContent(mContentView);

    startForeground(1001, mBuilder.build());

【讨论】:

不是这样,这只是堆栈溢出的一个错字!如果这是在我的实际代码中,它甚至不会编译 ^^ 另外,从布局中删除您为 TextView 设置的样式。如果需要,它应该是一个有效的样式【参考方案2】:

您可以在此处查看工作示例: http://www.laurivan.com/android-notifications-with-custom-layout/

我想,添加

// Set Icon
.setSmallIcon(R.drawable.smallimage)
// Set Ticker Message
.setTicker("Noification is created");

到你的builder可以解决问题。

【讨论】:

【参考方案3】:

我认为这只是一个布局问题,我想得越多。我认为如果你在TextViews 上设置android:layout_alignParentRight="true",你会得到你想要的。看起来它将它们布置在ImageView 的右侧,但在布局时没有给它们任何宽度,因为它们不要求任何宽度,也没有任何内容。

如果这不起作用,请告诉我们!

【讨论】:

现在整个java文件都可用了:)【参考方案4】:

This 的帖子解释得很酷。

基本上是这样的:

RemoteViews downloadViews = new RemoteViews(context.getPackageName(), R.layout.download_notification);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Content Title")
                .setContentText("Content Text")
                .setContent(downloadViews)
                .setPriority(NotificationCompat.PRIORITY_MIN);
        final Notification notification = mBuilder.build();
        notification.bigContentView = downloadViews;

        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, notification);

【讨论】:

以上是关于带有 RemoteViews 的 Android 自定义通知布局的主要内容,如果未能解决你的问题,请参考以下文章

带有 RemoteViews 的 setBackgroundResource 不适用于布局

Android:将位图从本地存储加载到应用小部件(RemoteViews)

如何从 Android 中的 RemoteViews 中删除小部件?

《android开发艺术探索》读书笔记--RemoteViews

Android appwidget remoteviews没有更新

FCM - 如何修复 android.app.RemoteServiceException:从包发布的错误通知无法扩展 RemoteViews:StatusBarNotification