关闭应用程序时,Android Push通知不起作用 [英] Android Push notifications not working when app is closed

查看:131
本文介绍了关闭应用程序时,Android Push通知不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 OkSse 订阅我的服务器发送事件.

I'm using OkSse to subscribe to my Server Sent Events.

每当服务器发送新消息时,无论该应用程序处于前景,最小化还是完全关闭状态,都应显示一条通知.

Whenever a new message is sent by the server, a notification should appear whether the app is in foreground,minimized or fully closed.

最小化或处于前台状态时,通知将按预期工作,但是完全关闭时,此通知仅适用于某些设备品牌.

The notifications work as expected when minimized or in foreground but when fully closed, this only works on some device brands.

正在研究,我发现:

只有小米等制造商在手机上才注意到此问题, Oppo,One Plus,Vivo,联想,华为,三星等.

this issue is noticed only on phones by manufacturers like Xiaomi, Oppo, One Plus, Vivo, Lenovo, Huawei, Samsung, and a few others.

WhatsApp, Facebook, Slack, Gmail, etc..如何在关闭应用程序的情况下显示通知?

How does WhatsApp, Facebook, Slack, Gmail, etc.. display notifications even if app is closed?

我不使用FCM,只需订阅Sse.

我也有清单:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver android:name="com.goparty.communication.NotificationsAlarmReceiver">
    <intent-filter>
        <action android:name="android.media.action.DISPLAY_NOTIFICATION" />
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

我该如何实现?

我设法通过使用IntentServiceBroadcastReceiver使它工作,但是对于Oreo版本,它崩溃了.

I managed to make it work by using an IntentService and BroadcastReceiver but this crashes for Oreo versions.

更多阅读之后,我发现JobIntentService是定位Android O及更高版本时替换IntentService.

After more reading I found that JobIntentService is the replacement of IntentService when targeting Android O and above.

JobIntentService的过渡非常简单,但是再次,当我关闭应用程序时,我的解决方案无法正常工作.

The transition to JobIntentService was pretty straight forward but again, my solution is not working when I close the app.

即使关闭了应用程序,通知的全部目的也可以正常工作.

The whole purpose of notifications are to work even when the app is closed.

使用IntentService在后台工作是通过发送带有新服务意图的broadcast来完成的.

Using IntentService worked in the background by sending a broadcast with a new intent of my service.

我正在和JobIntentService做同样的事,没有运气.

I'm doing the same with JobIntentService with no luck.

这是我的代码:

public class NotificationService extends JobIntentService {

    private static final int JOB_ID = 1;
    private NotificationManager notificationManager;

    public static void enqueueWork(Context context, Intent intent) {
        enqueueWork(context, NotificationService.class, JOB_ID, intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Logger.logGoParty(getClass().getSimpleName() + "#onCreate");
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Logger.logGoParty("Running in background.");
        sendBroadcast(new Intent(getApplicationContext(), NotificationService.class));
    }

    @Override
    protected void onHandleWork(@NonNull Intent intent) {
        Logger.logGoParty(getClass().getSimpleName() + "#onHandleWork");
        Logger.logGoParty("Sse initialized");

        Request request = new Request.Builder().url("the sse url").build();
        OkSse okSse = new OkSse();

        ServerSentEvent sse = okSse.newServerSentEvent(request, new ServerSentEvent.Listener() {
            @Override
            public void onOpen(ServerSentEvent sse, Response response) {
                Logger.logGoParty(response.toString());
            }

            @Override
            public void onMessage(ServerSentEvent sse, String id, String event, String message) {
                Logger.logGoParty("Sse#onMessage: " + message);
                try {
                    JSONObject promoJson = new JSONObject(message);

                    sendNotification(...);

                } catch (JSONException e) {
                    Logger.logGoParty("JSONException: " + e.toString());
                }
            }
                // ...
        });
    }

    private void sendNotification(String promoImageUrl, String notificationContent, String title) {

        try {
            URL url = new URL(promoImageUrl);
            Bitmap bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());


            NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
            style.bigPicture(bitmap);

            Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

            Intent intent = new Intent(this, MapsActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            intent.putExtra("page-to-open", "promotions");
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);


            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, GoParty.PROMO_CHANNEL_ID)
                    .setSmallIcon(R.mipmap.ic_launcher_round)
                    .setContentTitle(title)
                    .setAutoCancel(true)
                    .setSound(defaultSound)
                    .setContentText(notificationContent)
                    .setContentIntent(pendingIntent)
                    .setStyle(style)
                    .setLargeIcon(bitmap)
                    .setWhen(System.currentTimeMillis())
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setCategory(NotificationCompat.CATEGORY_MESSAGE);

            notificationManager.notify(0, notificationBuilder.build());

            Log.i("GoParty", "Notification sent ----- ");

        } catch (MalformedURLException e) {
            Logger.logGoParty(e.toString());
        } catch (IOException e) {
            Logger.logGoParty(e.toString());
        }
    }
}

通知接收者:

public class NotificationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        Intent notificationIntent = new Intent(context, NotificationService.class);
        NotificationService.enqueueWork(context, notificationIntent);
    }
}

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.goparty">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


    <application
        android:name=".scopes.application.GoParty"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps"
            android:screenOrientation="portrait">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.goparty.LoginActivity" />
        </activity>

        <service
            android:name=".jobs.NotificationService"
            android:permission="android.permission.BIND_JOB_SERVICE" />

        <receiver android:name=".receivers.NotificationReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

推荐答案

这背后的主要原因是自动启动"和电池优化"(MIUI)设备尝试在电池设置"中为您的应用更改不优化"选项

Main Reason behind this is AutoLaunch and Battery Optimization(MIUI) devices try to change don't optimize option for your app in Battery setting

 private void initOPPO() {
        try {

            Intent i = new Intent(Intent.ACTION_MAIN);
            i.setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.floatwindow.FloatWindowListActivity"));
            startActivity(i);
        } catch (Exception e) {
            e.printStackTrace();
            try {

                Intent intent = new Intent("action.coloros.safecenter.FloatWindowListActivity");
                intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.floatwindow.FloatWindowListActivity"));
                startActivity(intent);
            } catch (Exception ee) {

                ee.printStackTrace();
                try {

                    Intent i = new Intent("com.coloros.safecenter");
                    i.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.sysfloatwindow.FloatWindowListActivity"));
                    startActivity(i);
                } catch (Exception e1) {

                    e1.printStackTrace();
                }
            }

        }
    }

    private static void autoLaunchVivo(Context context) {
        try {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.iqoo.secure",
                    "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity"));
            context.startActivity(intent);
        } catch (Exception e) {
            try {
                Intent intent = new Intent();
                intent.setComponent(new ComponentName("com.vivo.permissionmanager",
                        "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
                context.startActivity(intent);
            } catch (Exception ex) {
                try {
                    Intent intent = new Intent();
                    intent.setClassName("com.iqoo.secure",
                            "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager");
                    context.startActivity(intent);
                } catch (Exception exx) {
                    ex.printStackTrace();
                }
            }
        }
    }

用法

if (Build.MANUFACTURER.equalsIgnoreCase("oppo")) {
                                initOPPO();
                            } else if (Build.MANUFACTURER.equalsIgnoreCase("vivo")) {
                                autoLaunchVivo(BaseSettingActivity.this);
                            } else if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) {
                                try {
                                    Intent intent = new Intent();
                                    intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
                                    startActivity(intent);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }

这篇关于关闭应用程序时,Android Push通知不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆