私は 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>
どうやってこれを達成できますか?
IntentService
とBroadcastReceiver
を使用して機能させることに成功しましたが、これはOreo
バージョンにクラッシュします。
もっと 読み取りAndroid O
以上をターゲットにするときのJobIntentService
がIntentService
の置き換えであることがわかりました。
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>
これは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();
}
}
_
あなたのアプローチ:通知のためにOKSSEを使うことは、背景サービスを実行する必要があることを意味します。
問題1:Androidバックグラウンドサービス制限 リンク
JobIntentService 内部的にJobServiceを使用し、実行中のサービスを続行しません。実行期限が適用されるため、無関係に実行されません。後で実行を続けるために停止し、再スケジュールされます。それであなたの場合はうまくいきません。
問題2:デバイスXiaomi、Oppo、One Plus、Vivo、Lenovo、Huawei、Samsungには、JobintentServiceを停止させるバッテリ最適化チェックがあります。
解決:
1)醜い前景サービスを実行し、お勧めできません
2)FireBaseの優先順位通知 リンク 強くお勧めします
アプリがバッテリ最適化モードに設定されていても、上記のデバイスに実装しました。通知が表示されます。