无法展开RemoteViews - 错误通知

时间:2014-03-24 16:19:32

标签: java android notifications remoteview

最近我收到越来越多的用户收到RemoteServiceException错误的报告。我每次给出的堆栈跟踪如下:

android.app.RemoteServiceException: Bad notification posted from package com.smithyproductions.fasttracks: Couldn't expand RemoteViews for: StatusBarNotification(pkg=com.smithyproductions.fasttracks id=311095 tag=null score=0 notn=Notification(pri=0 contentView=com.smithyproductions.fasttracks/0x7f03007d vibrate=null sound=null defaults=0x0 flags=0x62 kind=[null]) user=UserHandle{0})
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:153)
   at android.app.ActivityThread.main(ActivityThread.java:5341)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:929)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
   at dalvik.system.NativeStart.main(NativeStart.java)

我似乎永远无法在HTC Sensation或HTC One X上重现这个问题,这让我相信它可能是特定于设备的。我从以下设备收到了此错误的报告:

  • 华为G610 U15
  • bq Aquaris 5 HD
  • Enspert Stairway
  • JYT JY-G5

...他们都在运行Android 4.2.1 - 也许这个版本的Android存在错误?

我已经为有类似问题的人搜索了互联网和StackOverflow,虽然很多人都有这个问题,但大多数时候他们没有正常工作的原因是因为资源ID不正确或使用不受支持RemoteViews中的视图。我不明白如果它在98%的设备上工作我会做错的事情但是我不想告诉这些人这个问题我也无能为力。

就我创建通知的方式而言,我使用NotificationCompat.Builder类和自定义RemoteViews - 本质上它是一个音乐播放器通知,因此它上面也有一些ImageButtons。

这是我设置通知的代码:

PendingIntent pi = PendingIntent.getActivity(
                getApplicationContext(), 0, new Intent(getApplicationContext(), Showcase.class),
                PendingIntent.FLAG_UPDATE_CURRENT);

RemoteViews smallContentView = new RemoteViews(getPackageName(),
                R.layout.notif_layout);

nowPlayingNotification = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.notification_icon)
                .setContentTitle(
                        "Playing: "
                                + playbackManager.getCurrentTrack()
                                        .getName()).setContentIntent(pi)
                .setOngoing(true)
                .setWhen(System.currentTimeMillis())
                .setContent(smallContentView).build();

然后我设置了RemoteViews按钮的所有回调:

Intent playIntent = new Intent(this, RemoteControlReceiver.class);
    playIntent.setAction(ACTION_TOGGLE_PLAYBACK);
    PendingIntent playPausePendingIntent = PendingIntent.getBroadcast(this,
            0, playIntent, 0);

    Intent nextIntent = new Intent(this, RemoteControlReceiver.class);
    nextIntent.setAction(ACTION_SKIP);
    PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0,
            nextIntent, 0);

    Intent stopIntent = new Intent(this, RemoteControlReceiver.class);
    stopIntent.setAction(ACTION_STOP);
    PendingIntent stopPendingIntent = PendingIntent.getBroadcast(this, 0,
            stopIntent, 0);

    nowPlayingNotification.contentView.setTextViewText(R.id.title,
            playbackManager.getCurrentTrack().getName());

    nowPlayingNotification.contentView.setProgressBar(
            android.R.id.progress, 100, mediaProgress, false);

    if (notificationIconMixBitmap != null)
        nowPlayingNotification.contentView.setImageViewBitmap(R.id.icon,
                notificationIconMixBitmap);
    else {
        nowPlayingNotification.contentView.setImageViewResource(R.id.icon,
                R.drawable.notification_icon);

    }

    nowPlayingNotification.contentView.setOnClickPendingIntent(
            R.id.playPause, playPausePendingIntent);

    if (playbackManager.getCurrentPlaybackState() == State.Paused) {
        nowPlayingNotification.contentView.setImageViewResource(
                R.id.playPause, R.drawable.play_icon_solid);
    } else {
        nowPlayingNotification.contentView.setImageViewResource(
                R.id.playPause, R.drawable.pause_icon_solid);
    }

    if (!playbackManager.isSkipAllowed()) {
        nowPlayingNotification.contentView.setImageViewResource(R.id.next,
                R.drawable.next_icon_disabled);
    } else {
        nowPlayingNotification.contentView.setImageViewResource(R.id.next,
                R.drawable.next_icon_solid);
    }

    if (playbackManager.getCurrentPlaybackState() == State.Preparing) {
        nowPlayingNotification.contentView.setProgressBar(
                android.R.id.progress, 100, mediaProgress, true);
    }

    nowPlayingNotification.contentView.setOnClickPendingIntent(R.id.next,
            nextPendingIntent);
    nowPlayingNotification.contentView.setOnClickPendingIntent(R.id.close,
            stopPendingIntent);

接着是

mNotificationManager.notify(NOTIFICATION_ID, nowPlayingNotification);

如果有人知道任何有用的信息,也许是4.2.1中公认的错误,我们将不胜感激!感谢

2 个答案:

答案 0 :(得分:2)

我在构建中看到类似的问题 - 只有Kitkat设备大量抛出这些 - Android OS版本:4.4.4,4.4.2,4.2.2,4.0.4

通过更改通知使用的可绘制来修复。

.addAction(R.drawable.ic_forward_black_24dp, VIEW_ACTION, pendingIntentView);

我们停止使用Vector Assets并开始使用Image Assets。

R.drawable.ic_forward_black_24dp不再使用 xml 文件(Vector Asset),而是使用 png 文件(图片资源)。

答案 1 :(得分:1)

我的手机也遇到了同样的问题。

您使用以下代码创建通知:

nowPlayingNotification = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.notification_icon)
                .setContentTitle(
                        "Playing: "
                                + playbackManager.getCurrentTrack()
                                        .getName()).setContentIntent(pi)

如果你的未决意图,应用程序崩溃了 - >指定要启动的意图的pi设置为null,如下所示:

  PendingIntent pi= PendingIntent.getActivity(
                getApplicationContext(),
                0,
                ***null***,
                0
            );

用新的Intent()替换null并测试是否解决了问题。

On Gingerbread .setcontentIntent(intent)是必需的,否则将抛出IllegalArgumentException。但是在Jellybean中,如果我们删除.setcontentIntent(intent)

,则不会抛出任何异常