通知在 Android 8.0+ 中延迟

Posted

技术标签:

【中文标题】通知在 Android 8.0+ 中延迟【英文标题】:Notifications are delayed in Android 8.0+ 【发布时间】:2018-01-25 22:51:38 【问题描述】:

我在推送 android O 时遇到延迟。通知被延迟,甚至根本不显示。它发生在两种状态:前景和背景。但是对于任何其他android版本都没有这样的问题。我为 api 26+ 提供了通知渠道。试图改变优先级,禁用电池优化。但没有任何效果。

现在我的城市飞艇实现如下:

public class UrbanAirshipWrapper 
    private static class MyNotificationFactory extends DefaultNotificationFactory 
        public MyNotificationFactory(@NonNull Context context) 
            super(context);

            if (Build.VERSION.SDK_INT >= 26) 
                String channelId = "defaultChannel";
                NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationChannel channel = new NotificationChannel(channelId, context.getString(R.string.notification_default_channel), NotificationManager.IMPORTANCE_DEFAULT);

                channel.setSound(null, null);
                if (notificationManager != null) 
                    notificationManager.createNotificationChannel(channel);
                    setNotificationChannel(channelId);
                
            

            setSmallIconId(R.drawable.ic_notification);
            setColor(ContextCompat.getColor(context, R.color.notification));
        

        @Override
        public NotificationCompat.Builder extendBuilder(@NonNull NotificationCompat.Builder builder, @NonNull PushMessage message, int notificationId) 
            if (notificationAllowed(message)) 
                return soundBuilder(builder, message);
             else 
                return null; // preventing notification
            
        


        private boolean notificationAllowed(@NonNull PushMessage message) 
            Bundle pushBundle = message.getPushBundle();
            String centerId = pushBundle.getString(CENTER_ID);
            String objectNumber = pushBundle.getString(OBJECT_NUMBER);
            String type = pushBundle.getString(NOTIFICATION_TYPE);

            // not allowed arm_error for currently visible area
            if (TYPE_ARM_ERROR.equals(type) || TYPE_DISARM_ERROR.equals(type)) 
                if (centerId != null && objectNumber != null && (centerId + objectNumber).equals(sCurrentCenterPlusObject)) 
                    return false;
                
            

            return true; // allowed by default
        

        private NotificationCompat.Builder soundBuilder(@NonNull NotificationCompat.Builder builder, @NonNull PushMessage message) 
            Bundle pushBundle = message.getPushBundle();
            String sound = pushBundle.getString(SOUND);

            if (TextUtils.isEmpty(sound)) 
                if (Build.VERSION.SDK_INT < 26) 
                    builder.setSound(null);
                 else 
                    RingtoneManager.getRingtone(getContext(), Settings.System.DEFAULT_NOTIFICATION_URI).play();
                
             else 
                Uri uri = Uri.parse("android.resource://" + getContext().getPackageName() + "/raw/" + sound);

                if (Build.VERSION.SDK_INT < 26) 
                    builder.setSound(uri);
                 else 
                    RingtoneManager.getRingtone(getContext(), uri).play();
                
            

            return builder;
        
    

    public static String sCurrentCenterPlusObject;

    private UrbanAirshipWrapper()  

    @SuppressWarnings("deprecation")
    public static void initialize(Application application, String prodAppKey, String prodAppSecret, String gcmSender) 
        AirshipConfigOptions options = new AirshipConfigOptions.Builder()
            .setInProduction(true)
            .setProductionAppKey(prodAppKey)
            .setProductionAppSecret(prodAppSecret)
            .setGcmSender(gcmSender).build();

        UAirship.takeOff(application, options);
        UAirship.shared().getPushManager().setUserNotificationsEnabled(true);
        UAirship.shared().getPushManager().setNotificationFactory(new MyNotificationFactory(application));
    

通知是通过 GCM 发送的,它只是没有任何图像的数据消息。但是当推送延迟显示时出现以下错误:

01-25 21:58:46.336 27657-27910/com.example.app W/EnhancedIntentService: Service took too long to process intent: com.google.android.c2dm.intent.RECEIVE App may get closed.

我认为这可能是问题的根源。我已经尝试禁用我的自定义通知工厂。我还禁用了与通知相关的接收器和服务。但问题依然存在。

有没有办法解决这个问题?

【问题讨论】:

EnhancedIntentService 是你的班级吗?如果是这样,您可能希望发布该类的代码。 不。 EnhancedIntentService 不是我的。我发现了类似的问题here。但是我禁用了我所有的通知服务,它并没有起到什么作用。 【参考方案1】:

我找到了解决方案。就我而言,问题出在谷歌服务插件中。我试图从build.gradle 中删除它。它奏效了。通知开始及时到达。

// This line causes the problem in my build.gradle
apply plugin: 'com.google.gms.google-services'

我还发现GcmReceiver 及时收到了通知,即使我没有禁用谷歌服务插件。因此,如果您遇到此类问题,解决方案可能在 GcmReceiver 附近。

在 urbanairship 团队的帮助下,我找到了以下解决方法。

<receiver
    android:name="com.urbanairship.push.GcmPushReceiver"
    android:permission="com.google.android.c2dm.permission.SEND">

    <intent-filter android:priority="100">
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="$applicationId" />
    </intent-filter>
</receiver>

您需要在清单中添加它。它会提升 UA 接收器的优先级。

【讨论】:

删除apply plugin: 'com.google.gms.google-services' 有什么帮助?如果我删除它,它根本不会初始化 Firabase 在我的情况下优先级 == 100 帮助 警告:删除 com.google.gms.google-services 将禁用您的整个 Firebase 消息传递实现!

以上是关于通知在 Android 8.0+ 中延迟的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 8.0 中未显示使用 parse sdk 的推送通知

推送通知未在Android 8.0中使用解析sdk显示

Android 8.0 功能和 API

Android 8.0+ 通知不显示的适配

Android8.0适配那点事

Titanium 推送通知(Android 接收通知延迟)