糟糕的通知:Android Nougat上无法展开StatusBarNotification的RemoteViews。

14
我将翻译如下:

我使用OneSignal SDK来显示通知。 我在OneSignalPushService.java中执行此操作。

OneSignalPushService.java:

public class OneSignalPushService extends NotificationExtenderService {

    @Override
    protected boolean onNotificationProcessing(OSNotificationReceivedResult notification) {

        if (!TinyDbWrap.getInstance().isPushEnabled()) {
            KLog.d(this.getClass().getSimpleName(), "Notification will not displayed");
            return true;
        }

        OverrideSettings overrideSettings = new OverrideSettings();
        overrideSettings.extender = new NotificationCompat.Extender() {
            @Override
            public NotificationCompat.Builder extend(NotificationCompat.Builder notificationBuilder) {
                notificationBuilder.setDefaults(0);
                notificationBuilder.setContentTitle(getApplicationContext().getResources().getString(R.string.app_name));

                boolean is_in_silent_mode = false; /*or true by user's settings in app*/
                /*TinyDbWrap.getInstance()... - it stores user's settings*/
                KLog.d(OneSignalPushService.class.getSimpleName(), "Notification isSoundPushEnabled: " + TinyDbWrap.getInstance().isSoundPushEnabled());
                if (!is_in_silent_mode && TinyDbWrap.getInstance().isSoundPushEnabled()) {
                    notificationBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
                } else {
                    notificationBuilder.setSound(null);
                }

                KLog.d(OneSignalPushService.class.getSimpleName(), "Notification isVibrationPushEnabled: " + TinyDbWrap.getInstance().isVibrationPushEnabled());
                if (!is_in_silent_mode && TinyDbWrap.getInstance().isVibrationPushEnabled()) {
                    notificationBuilder.setVibrate(new long[]{0, 100, 200, 300, 400});
                } else {
                    notificationBuilder.setVibrate(new long[]{0});
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    notificationBuilder.setColor(ContextCompat.getColor(getApplicationContext(), R.color.bg_first_item_white_scheme));
                }
                notificationBuilder.setLights(ContextCompat.getColor(getApplicationContext(), R.color.time_white_sheme), 500, 500);
                return notificationBuilder;
            }
        };

        OSNotificationDisplayedResult result = displayNotification(overrideSettings);
        if (result != null) {
            KLog.d(OneSignalPushService.class.getSimpleName(), "Notification displayed with id: " + result.androidNotificationId);
        }

        return true;
    }

}

这在我所有的设备上都很好用,但是:

我在Crashlytics上只在使用Android Nougat的设备上收到了大量此类问题:

Fatal Exception: android.app.RemoteServiceException: Bad notification posted from package my.package: Couldn't expand RemoteViews for: StatusBarNotification(pkg=my.package user=UserHandle{0} id=-1542711428 tag=null key=0|my.package|-1542711428|null|10184: Notification(pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x19 color=0xff56a0d3 vis=PUBLIC semFlags=0x0 semPriority=0)) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1813) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6776) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

不幸的是,我无法在我的设备上重现此问题以了解如何消除它。

我尝试更改图形资源,例如通知图标,以清理项目,以遵循此建议

我注意到,在发布应用程序的新版本后,这个问题出现的设备数量会在一周内增加,然后这些数字会减少到零。

此问题也向GoogleOneSignal SDK开发人员报告了。

我正在寻找任何解决方法、任何想法或建议,以帮助消除此问题。


{btsdaf} - Dima Kozhevin
{btsdaf} - Amjad Khan
@Dima kozhevin 这个问题解决了还是仍然存在? - Amjad Khan
那么,你找到任何解决方案了吗? - Ian Medeiros
@IanMedeiros 这个解决方法对我很有帮助。 - Dima Kozhevin
显示剩余6条评论
2个回答

12

我认为这个崩溃是因为你的通知包含了对 PendingIntent bundle 中图标的整数引用,而该整数在发布到 NotificationManager 时被引用。

在获取整数引用和挂起意图触发之间,应用程序已更新,所有 drawable 引用都发生了变化。曾经引用正确可绘制对象的整数现在引用的可能是不正确的可绘制对象或根本没有(最终导致崩溃)

这可以从以下证据中看出:

我注意到当我发布应用程序的新版本后,此问题的设备数量增加了一个星期, 然后这些数字降至零。

解决方法是在应用程序更新后重新构建所有通知。


@DimaKozhevin Google开发人员在Android N上对通知进行了一些更改https://android-developers.googleblog.com/2016/06/notifications-in-android-n.html,也许这影响了此错误的更正。关于重新创建通知,我不确定接收器是否有效,最好检查一下。 - Dmitriy Puchkov
Google开发人员总是进行一些更改。这是一个非常普遍的说法。你能提出解决这个问题的建议吗?无论如何,我已经为你的答案点赞了。感谢你对我的问题的关注。 - Dima Kozhevin
谢谢,我只能建议将它包装在 try-catch 块中。 - Dmitriy Puchkov
1
@DmitriyPuchkov 我也遇到了同样的问题,没有使用OneSignal SDK。这个问题发生在我身上,导致异常的原因是重新创建一个持久通知。不幸的是,这不能用try catch包装,整个流程完全通过内部类进行。 - Kirill Kulakov
我遇到了同样的问题,在'MY_PACKAGE_REPLACED'之后,我重新构建了所有的通知。但是这并没有起到作用。在更新后,我仍然在Nougat Android版本的Motorola设备上遇到崩溃问题。 - kolombo
显示剩余3条评论

0

OneSignal的开发者建议下一步采取一个解决方法

AndroidManifest.xml中的<application>标签下添加以下内容

<manifest ...>
    <application ...>
        ...
        <receiver android:name="com.onesignal.UpgradeReceiver" tools:node="remove" />
    </application>
</manifest>

当我采用了这个临时解决方案后,这些崩溃问题就消失了。


此解决方案仅适用于Android Nougat。我遇到了这个崩溃,但嫌疑人是Kitkat(4.4.2),几乎所有的Kitkat都受到影响。 - Nanda Z

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