web-dev-qa-db-ja.com

Androidアプリが閉じられたときに通知が機能しない

私は oksse を使用しています。サーバーの送信イベントを購読します。

新しいメッセージがサーバーによって送信されるときはいつでも、アプリが前景になっているか、最小化または完全に閉じられているかという前景に表示されるべきです。

通知は予想どおりに機能します。最小化またはフォアグラウンド全閉のとき( - === - )、これは一部の作品ですデバイスブランド

ビット 、私はそれを見つけました:

この問題は、Xiaomi、Oppo、Plus、Vivo、Lenovo、Huawei、Samsung、および他のいくつかの製造業者によっての電話でのみ気付かれます。

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>

どうやってこれを達成できますか?

アップデート

IntentServiceBroadcastReceiverを使用して機能させることに成功しましたが、これはOreoバージョンにクラッシュします。

もっと 読み取りAndroid O以上をターゲットにするときのJobIntentServiceIntentServiceの置き換えであることがわかりました。

JobIntentServiceへの移行はかなり前進していましたが、再び、私がアプリを閉じると私の解決策は機能しません。

通知の目的は、アプリが閉じられている場合でも機能することです。

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>
6
esteban rincon

これはAutolaunch and Battery Optimization(MIUI)デバイスを変更しようとしています。電池設定でアプリのオプションを最適化しないでください。

 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();
                                }
                            }
 _
2
Ganesh Pokale

あなたのアプローチ:通知のためにOKSSEを使うことは、背景サービスを実行する必要があることを意味します。

問題1:Androidバックグラウンドサービス制限 リンク

JobIntentService 内部的にJobServiceを使用し、実行中のサービスを続行しません。実行期限が適用されるため、無関係に実行されません。後で実行を続けるために停止し、再スケジュールされます。それであなたの場合はうまくいきません。

問題2:デバイスXiaomi、Oppo、One Plus、Vivo、Lenovo、Huawei、Samsungには、JobintentServiceを停止させるバッテリ最適化チェックがあります。

解決:

1)醜い前景サービスを実行し、お勧めできません

2)FireBaseの優先順位通知 リンク 強くお勧めします

アプリがバッテリ最適化モードに設定されていても、上記のデバイスに実装しました。通知が表示されます。

1
Vikas Rathod