165 lines
7.2 KiB
Java
165 lines
7.2 KiB
Java
package io.guh.nymeaapp;
|
|
|
|
import com.google.firebase.messaging.RemoteMessage;
|
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
|
import com.google.android.gms.common.ConnectionResult;
|
|
import com.google.android.gms.common.GooglePlayServicesUtil;
|
|
|
|
import android.util.Log;
|
|
import android.content.Intent;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.app.PendingIntent;
|
|
import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationManager;
|
|
import android.net.Uri;
|
|
import android.content.Context;
|
|
import android.provider.Settings.System;
|
|
import android.os.Build;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.res.Resources;
|
|
|
|
import androidx.core.app.NotificationCompat;
|
|
|
|
import java.util.Random;
|
|
|
|
public class NymeaAppNotificationService extends FirebaseMessagingService {
|
|
|
|
private static final String TAG = "nymea-app: NymeaAppNotificationService";
|
|
private static final String DEFAULT_CHANNEL_ID = "default-channel";
|
|
private static final String DEFAULT_CHANNEL_NAME = "nymea notifications";
|
|
|
|
private int hashId(String id) {
|
|
int hash = 7;
|
|
for (int i = 0; i < id.length(); i++) {
|
|
hash = hash * 31 + id.charAt(i);
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
public static boolean checkPlayServices() {
|
|
Log.d(TAG, "Checking for Google Play services");
|
|
try {
|
|
Context context = NymeaAppActivity.getAppContext();
|
|
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
|
|
return resultCode == ConnectionResult.SUCCESS;
|
|
} catch (Exception e) {
|
|
Log.d(TAG, e.toString());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onNewToken(String token) {
|
|
Log.d(TAG, "Refreshed token: " + token);
|
|
}
|
|
|
|
@Override
|
|
public void onMessageReceived(RemoteMessage remoteMessage) {
|
|
|
|
// https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/RemoteMessage
|
|
|
|
super.onMessageReceived(remoteMessage);
|
|
|
|
RemoteMessage.Notification notification = remoteMessage.getNotification();
|
|
String title = notification != null ? notification.getTitle() : null;
|
|
String body = notification != null ? notification.getBody() : null;
|
|
if (title == null) {
|
|
title = remoteMessage.getData().get("title");
|
|
}
|
|
if (body == null) {
|
|
body = remoteMessage.getData().get("body");
|
|
}
|
|
|
|
Log.d(TAG, "Notification from: " + remoteMessage.getFrom());
|
|
Log.d(TAG, "Notification title: " + title);
|
|
Log.d(TAG, "Notification body: " + body);
|
|
Log.d(TAG, "Notification priority: " + remoteMessage.getPriority());
|
|
Log.d(TAG, "Notification data: " + remoteMessage.getData());
|
|
Log.d(TAG, "Notification message ID: " + remoteMessage.getMessageId());
|
|
|
|
if (title == null && body == null && remoteMessage.getData().isEmpty()) {
|
|
Log.w(TAG, "No notification payload received, skipping notification creation.");
|
|
return;
|
|
}
|
|
|
|
Intent intent = new Intent(this, NymeaAppActivity.class);
|
|
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
intent.setAction(Intent.ACTION_SEND);
|
|
intent.putExtra("notificationData", remoteMessage.getData().get("nymeaData"));
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
|
|
|
// We can't directly access R.drawable.notificationicon from here:
|
|
// When the package is branded, the package name is not "io.guh.nymeaapp" and resources in
|
|
// the res/ folder are built into the app's package which isn't the same as this files package.
|
|
// Because of this, we need to dynamically fetch the resource from the package resources
|
|
int resId = getResources().getIdentifier("notificationicon", "drawable", getPackageName());
|
|
Log.d(TAG, "Notification icon resource: " + resId + " Package:" + getPackageName());
|
|
if (resId == 0) {
|
|
resId = getApplicationInfo().icon;
|
|
Log.w(TAG, "Notification icon resource missing, using application icon: " + resId);
|
|
}
|
|
|
|
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
if (notificationManager == null) {
|
|
Log.w(TAG, "NotificationManager not available, cannot display notification.");
|
|
return;
|
|
}
|
|
|
|
String channelId = resolveStringResource("notification_channel_id", DEFAULT_CHANNEL_ID);
|
|
String channelName = resolveStringResource("notification_channel_name", DEFAULT_CHANNEL_NAME);
|
|
|
|
// Since android Oreo notification channel is needed.
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
NotificationChannel existingChannel = notificationManager.getNotificationChannel(channelId);
|
|
if (existingChannel == null) {
|
|
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
|
|
notificationManager.createNotificationChannel(channel);
|
|
}
|
|
}
|
|
|
|
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
|
|
.setContentTitle(title)
|
|
.setContentText(body)
|
|
.setSmallIcon(resId)
|
|
.setAutoCancel(true)
|
|
.setContentIntent(pendingIntent)
|
|
.setPriority(NotificationCompat.PRIORITY_HIGH);
|
|
|
|
boolean sound = remoteMessage.getData().get("sound") == null || remoteMessage.getData().get("sound").equals("true");
|
|
Log.d(TAG, "Notification sound enabled: " + (sound ? "true" : "false"));
|
|
if (sound) {
|
|
notificationBuilder.setSound(android.provider.Settings.System.DEFAULT_RINGTONE_URI);
|
|
}
|
|
|
|
// Action tests
|
|
// Intent actionIntent = new Intent(this, NymeaAppActivity.class);
|
|
// actionIntent.setAction(Intent.ACTION_SEND);
|
|
// actionIntent.putExtra("foobar", "baz");
|
|
// PendingIntent actionPendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, actionIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
// notificationBuilder.addAction(resId, "30%", actionPendingIntent);
|
|
// notificationBuilder.addAction(resId, "50%", actionPendingIntent);
|
|
// notificationBuilder.addAction(resId, "70%", actionPendingIntent);
|
|
// Action tests end
|
|
|
|
Log.d(TAG, "Posting Notification: " + remoteMessage.getMessageId());
|
|
notificationManager.notify(0, notificationBuilder.build());
|
|
}
|
|
|
|
private String resolveStringResource(String resourceName, String fallback) {
|
|
int resId = getResources().getIdentifier(resourceName, "string", getPackageName());
|
|
if (resId != 0) {
|
|
try {
|
|
String resolved = getString(resId);
|
|
if (resolved != null && !resolved.isEmpty()) {
|
|
return resolved;
|
|
}
|
|
} catch (Resources.NotFoundException e) {
|
|
Log.w(TAG, "String resource not found for " + resourceName + ", using fallback");
|
|
}
|
|
}
|
|
return fallback;
|
|
}
|
|
}
|