【问题标题】:How to make an Android FCM notification service always running in background?如何使 Android FCM 通知服务始终在后台运行?
【发布时间】:2018-05-16 09:34:50
【问题描述】:

我目前正在开发一个应用程序,该应用程序使用主题来通知用户新的变化。它实际上工作得很好,但前提是应用程序当前正在运行。如果应用程序在后台或关闭,则不会推送任何通知。这就是我想要改变的。应用程序/通知服务应始终在后台运行。

我已经在 SO 上找到了一些解决方案,但它们是否不是服务器-客户端解决方案(使用 FCM)或者它们并没有真正起作用。

这是在我的服务器上运行的 FCM/Notification-Class

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");
}
}

这些是我在 Android 上运行的 FCM 类:

1. FCM_Instance_ID_Service.java

公共类 FCM_Instance_ID_Service 扩展 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);
}
}

这是我的 ma​​nifest.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>

有人有想法吗?

【问题讨论】:

  • 您的应用是否接收推送以及如何接收推送取决于推送的内容,而不是您的应用中服务的可用性(除非应用被强制停止),因为它是为你,通过安卓。但是看起来您只发送“数据”而不是“通知”有效负载,因此即使应用程序在后台,它也应该可以工作。你如何验证它是否有效?
  • 你的意思是处于保持/关闭状态还是一般?

标签: android firebase firebase-cloud-messaging android-notifications


【解决方案1】:

我认为这不是 FCM 的问题,也不是通知服务的问题。我认为这是某些设备的问题。在类似的帖子中查看我的答案,也许这对您有所帮助。

Notifications not received on Android

【讨论】:

  • 谢谢!我从没想过设备本身。我正在使用华硕 Zenfone,它提供了一个管理器应用程序,可以从后台工作应用程序中“清理”设备。关闭此功能后,它似乎在后台工作。但是还有一个谜,为什么像whatsapp这样的应用没有这个问题。
  • 因为默认情况下,WhatsApp 在这些冲突设备中受到保护。如果此解决方案对您有用,我将非常感谢您接受答案:)
  • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
  • @Kumar 我不明白你的评论。我刚刚将此答案与我在其他帖子中写的另一个答案联系起来。请注意,此答案对问题的作者有所帮助。
  • 嗨,马克。尽管链接中的帖子可能会回答这个问题,但这个帖子没有。如果您想从其他帖子中指出答案,那么在 cmets 中进行就足够了——如果它可能是重复的,请随时标记该帖子。诸如此类的答案被标记为“仅链接答案”,并且在 SO 社区中通常不受欢迎(因此不赞成)。希望这可以解决问题。干杯,欢迎来到 Stack Overflow!
猜你喜欢
  • 2011-02-03
  • 2018-02-04
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多