0

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?

Marc Estrada
  • 1,657
  • 10
  • 20
Kodiak
  • 43
  • 2
  • 8
  • whether or not and how a push is received by your app depends on the content of the push, not the availability of the service in your app (unless the app was force stopped) because it is managed for you, by android. However looks like you are sending only "data" and not "notification" payloads, so it should be working even if the app is in the background. How do you verify if it is working? – Tim May 16 '18 at 09:47
  • Do you mean in hold/closed state or in general? – Kodiak May 16 '18 at 10:20

1 Answers1

-1

I think this is not a problem of FCM nor notification service. I think it's a problem of some devices. Check my answer in a similar post and maybe this helps you.

Notifications not received on Android

Marc Estrada
  • 1,657
  • 10
  • 20
  • 1
    Thanks! I never thought about the device itself. I'm using an Asus Zenfone wich provides a manager-app that "cleans" the device from background working apps. After turning off this feature it seems like it's working in background. But there is still the mystery, why apps like whatsapp don't have this problem. – Kodiak May 16 '18 at 10:55
  • Because WhatsApp is protected in these conflictive devices by default. If this solution worked for you, I'll appreciate so much you accept the answer :) – Marc Estrada May 16 '18 at 10:59
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](/review/low-quality-posts/19743492) – Kumar Saurabh May 16 '18 at 11:58
  • @Kumar I don't understand your comment. I've just linked this answer with another answer also writed by me in other post. Note that the this answer helped the question's author. – Marc Estrada May 16 '18 at 12:11
  • 1
    Hey Marc. Although the post in the link may answer the question, this one doesn't. If you want to point out an answer from a different post, doing it in the comments should be enough -- better yet if it's a possible duplicate, feel free to flag the post. Answers such as this is tagged as "*link-only answers*" and is usually frowned upon (hence the downvotes) in the SO community. Hope this clears things up. Cheers and welcome to Stack Overflow! – AL. May 16 '18 at 13:48
  • Thanks @AL. understood – Marc Estrada May 17 '18 at 08:56