Android 推送通知在应用程序关闭时不起作用

2024-01-12

我在用着OkSse https://github.com/heremaps/oksse订阅我的服务器发送事件。

每当服务器发送新消息时,无论应用程序是否处于运行状态,都应该出现通知前景、最小化或完全关闭.

通知按预期工作最小化或在前台但当全封闭,这仅适用于某些设备品牌.

研究一个bit https://medium.freecodecamp.org/why-your-push-notifications-never-see-the-light-of-day-3fa297520793, 我找到:

仅在小米等制造商的手机上才会注意到此问题, Oppo、一加、Vivo、联想、华为、三星等。

如何WhatsApp, Facebook, Slack, Gmail, etc..即使应用程序关闭也显示通知?

我不使用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>

我怎样才能实现这个目标?

Update

我设法让它工作通过使用IntentService and BroadcastReceiver但这会崩溃Oreo版本。

更多之后reading https://developer.android.com/reference/android/support/v4/app/JobIntentService我找到JobIntentService是替代IntentService当瞄准时Android O以上。

过渡到JobIntentService非常简单,但同样,当我关闭应用程序时,我的解决方案不起作用。

通知的全部目的是即使在应用程序关闭时也能正常工作。

Using IntentService通过发送一个在后台工作broadcast我的服务有了新的意图。

我也在做同样的事情JobIntentService没有运气。

这是我的代码:

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>

您的方法:使用 OkSse 进行通知意味着需要不断运行后台服务。

问题一:Android后台服务限制link https://developer.android.com/about/versions/oreo/background#services

求职意向服务 https://developer.android.com/reference/android/support/v4/app/JobIntentService.html内部将使用 JobService 并且它不会是持续运行的服务。由于执行时间限制,它不会无动于衷地运行。它将停止并重新安排稍后继续执行。所以在你的情况下,这是行不通的。

问题 2:小米、Oppo、一加、Vivo、联想、华为、三星的设备有电池优化检查,导致 JobIntentService 停止。

解决方案:

1)运行前台服务,这很丑陋,不推荐

2) Firebase 高优先级通知link https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message强烈推荐

我已经在上述设备上实现了它,即使应用程序设置为电池优化模式,您也会收到通知。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 推送通知在应用程序关闭时不起作用 的相关文章

  • 与其他图标相比,AppCompat ShareActionProvider 图标太大

    我将 ActionBarSherlock 更改为 AppCompat v7 我已经完成了使其工作所需的所有更改 但是共享图标 使用 ShareActionProvider 发生了一些奇怪的情况 与其他图标相比 共享图标太大 我还使用支持库进
  • 对话框上的 EditText 不返回任何文本

    我太累了 找不到错误 我没有发现任何错误 但我没有从 editText 收到任何文本 请看下面的代码 活动密码 xml
  • 应用程序位于前台时的 IOS Expo 推送通知

    从博览会文档中阅读 对于 iOS 明智的做法是处理以下推送通知 当应用程序处于前台时收到 因为否则用户 永远不会见到他们 应用程序运行时到达的通知 iOS 上的前台不会显示在系统通知列表中 A 常见的解决方案是手动显示通知 为了 例如 如果
  • 在 Android 中长按时从操作模式中删除后退/主页按钮

    我已经在里面长按实现了上下文操作模式recycler view 为此我打电话给ActionModeCallback从创建动作模式开始 创建动作模式时 默认显示后退箭头 检查如下 单击后退箭头 操作模式将关闭 现在我想要hide or rem
  • 如何从一个代码库创建多个 Android 应用

    我有一个 Android 代码库 它使用带有设置的 API 来获取多个应用程序的不同数据 所有应用程序都使用相同的代码库 但进行一两个设计调整 那么如何重用主代码库而不必每次都复制整个 Android 项目呢 iPhone 在同一个项目中使
  • Renderscript 示例构建错误

    所以我想尝试使用 RenderScript 的示例 并在 Eclipse 中导入了 HelloWorld 但它给了我这样的错误 2011 10 25 13 10 48 HelloWorld home mileoresko workspace
  • 如何以编程方式断开拨出呼叫

    我使用以下代码以编程方式断开呼叫 但它不起作用 private void callDisconnect try TelephonyManager manager TelephonyManager this getSystemService
  • Web 视图未在 Android 中加载本地 html 文件

    I am integrating html in android I have created a web view But i am not able load local html page Surprisingly web view
  • Firebase ANR - 甚至不使用 firebase

    随着 GMS 的最新更新 引入了新的 ANR 如果您退出应用程序 然后返回 则 ANR 就会初始化 线程跟踪似乎指向 Firebase 但我什至从未开始使用 Firebase 我猜它一定是新的 GMS 包的一部分 06 11 00 34 0
  • 如何在进入新活动之前终止线程和处理程序

    大家好 在我尝试清理处理程序时 这段代码可能有点混乱 因为我一直在尝试追踪崩溃发生的位置 我有一个对话框活动 显示密码输入 进度条由线程和处理程序动画显示 似乎当我试图查看进度条是否完成并尝试终止线程时 当我尝试进入新活动时 我这样做的方式
  • 如何在 Android NDK 中创建新的 NativeWindow 而无需 Android 操作系统源代码?

    我想编译一个 Android OpenGL 控制台应用程序 您可以直接从控制台启动 Android x86 运行 或者从 Android x86 GUI 内的 Android 终端应用程序运行 这个帖子 如何在 Android NDK 中创
  • 为什么Android应用程序在发布到市场后尺寸会增加?

    我最近在 Android 市场上发布了我的应用程序 显示应用程序大小为 5 4MB 而实际 apk 大小为 2 8MB 为什么显示多出2MB 我应该如何限制我的应用程序大小 请帮我 您的应用程序大小会增加 因为您使用了复制保护选项ON在发布
  • Android Studio IDE 上的“文本/设计”选项卡缺少新的 Android 项目

    如何在创建新项目期间自动创建的 Activity main xml 文件的 src main res layout 文件夹中启用文本 设计选项卡 如果我右键单击并在所述文件夹上创建 xml 文件 则设计 文本选项卡存在 有什么建议吗 谢谢
  • Vimeo 视频在 Android 6 设备上停止播放

    我正在尝试在我的应用程序中播放 Vimeo 的视频 问题是在 Android 6 设备上 视频会在一定时间后停止播放 在 API 较低的设备上一切正常 时间取决于质量 对于下面提供的网址的视频 播放一定分钟 1 到 3 视频质量有多低 播放
  • onBackPressed 隐藏 不破坏 Activity

    我知道如何取消后退按键 以便活动 主窗口保持可见 public void onBackPressed return 我的目标是隐藏该活动 但是 在没有完成它的情况下 您如何在 onBackPressed 事件中做到这一点 即我想达到 onP
  • 在 Honeycomb Android 3.0 中显示 Action Bar 菜单项的图标

    我正在使用 Honeycomb android 3 0 开发 Android 应用程序 我正在尝试在 Action Bar 中显示菜单 菜单有一个图标和标题 当我们单击菜单项时 它会以下拉列表的形式显示其项目 它是下拉列表中带有项目名称但不
  • 如何在没有 firebase 的情况下在 flutter 中显示推送通知?

    在我的 flutter 应用程序中 我必须在没有 firebase 的情况下显示推送通知 我的服务器会在点击特定 API 后向我发送一条消息 并且我希望将该消息显示为推送通知 你能告诉我一种方法如何在颤振中做到这一点吗 您可以使用本地通知插
  • Android - 9 补丁

    我正在尝试使用 9 块图片创建一个新的微调器背景 我尝试了很多方法来获得完美的图像 但都失败了 s Here is my 9 patch 当我用Draw 9 patch模拟时 内容看起来不错 但是带有箭头的部分没有显示 或者当它显示时 这部
  • 按字母顺序过滤 Firestore 数据以对 Google Cloud 中的文档读取进行分类/减少

    基于这样的事实Cloud Firestore 不支持全文搜索 https firebase google com docs firestore solutions search到目前为止 我决定问这个question https stack
  • 当ScrollView滚动到底部时加载更多数据

    我有一个带有动态加载内容的滚动视图 有时可能会有很多内容 所以我想在用户滚动到底部时加载更多内容 我搜索了合适的方法 发现了两种 onScrollChanged and getScrollY 但我不知道如何将它用于我的目的 请给我一些建议

随机推荐