【发布时间】: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);
}
}
这是我的 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>
有人有想法吗?
【问题讨论】:
-
您的应用是否接收推送以及如何接收推送取决于推送的内容,而不是您的应用中服务的可用性(除非应用被强制停止),因为它是为你,通过安卓。但是看起来您只发送“数据”而不是“通知”有效负载,因此即使应用程序在后台,它也应该可以工作。你如何验证它是否有效?
-
你的意思是处于保持/关闭状态还是一般?
标签: android firebase firebase-cloud-messaging android-notifications