I'm currently working on an App that works with topics to inform users about new changes. It actually works pretty good, but only if the app is currently running. If the app is in the background or closed no notification is getting pushed. And that's what I want to change. The app/Notificationservice should allways run in background.
I've allready found some solutions on SO, but wether they weren't Server-Client solutions (with FCM) or they didn't realy worked.
this is the FCM/Notification-Class running on my server:
public static void pushFCMNotification(String DeviceIdKey, String title, String content) throws Exception {
String authKey = AUTH_KEY_FCM;
String FMCurl = API_URL_FCM;
URL url = new URL(FMCurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "key=" + authKey);
conn.setRequestProperty("Content-Type", "application/json");
JSONObject data = new JSONObject();
data.put("to", DeviceIdKey.trim());
JSONObject info = new JSONObject();
info.put("title", title); // Notification title
info.put("content-text", content); // Notification body
info.put("click_action", ".MainActivity");
data.put("data", info);
System.out.println(data.toString());
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data.toString());
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
}
//test method
public static void main(String[] args) throws Exception {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
FCMNotification.pushFCMNotification("/topics/general", dateFormat.format(date), "dracky");
}
}
These are my FCM classes running on Android:
1. FCM_Instance_ID_Service.java
public class FCM_Instance_ID_Service extends FirebaseInstanceIdService { final String tokenPreferenceKey = "fcm_token";
final static String infoTopicName = "info";
private static final String REG_TOKEN = "REG_TOKEN";
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.edit().putString(tokenPreferenceKey, FirebaseInstanceId.getInstance().getToken()).apply();
FirebaseMessaging.getInstance().subscribeToTopic(infoTopicName);
}
}
2. FCM_Messaging_Service.java
public class FCM_Messaging_Service extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getFrom().equals("/topics/" + FCM_Instance_ID_Service.infoTopicName)) {
displayNoification(remoteMessage.getData().get("title"), remoteMessage.getData().get("content-text"), this);
} else {
displayNoification(remoteMessage.getData().get("title"), remoteMessage.getData().get("content-text"), this);
}
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(500);
}
//startAlarm(true, false);
}
@SuppressLint("NewApi")
public void displayNoification(String title, String contentText, Context context) {
Notification notification = null;
notification = new Notification.Builder(this)
.setContentTitle(title)
.setContentText(contentText)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setLights(Color.RED, 3000, 3000)
.setSound(Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.alarm))
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher))
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(14, notification);
}
}
This is my manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.ddns.kodiakscloud.fastalker">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name=".MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".FCM_Messaging_Service">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".FCM_Instance_ID_Service">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<activity android:name=".BrowserActivity" />
<activity android:name=".ReviewActivity" />
<activity android:name=".WatchListActivity"></activity>
</application>
</manifest>
Does anybody have an idea?