即使App已关闭,也会收到Android推送通知

世事洞明皆学问,人情练达即文章。这篇文章主要讲述即使App已关闭,也会收到Android推送通知相关的知识,希望能为你提供帮助。
我尝试过使用Google GCM但是当应用关闭时(从任务管理器中滑动或清除),它不会收到任何推送通知。当我再次打开应用程序时,通知已经消失并丢失。
GCM正致力于: - 应用程序已打开 - 应用程序已最小化
不工作: - 应用程序已关闭(从任务管理器轻扫) - 通过清除任务管理器中所有打开的应用程序关闭应用程序
【即使App已关闭,也会收到Android推送通知】即使应用程序像Facebook或Instagram一样关闭,我也希望收到推送通知。我怎么能实现这个?这可能在GCM中有用吗?如果有,怎么样?如果没有,那么实现这个的另一种方法是什么?
这是我的代码:
androidManifest.xml中

< !-- [START gcm_receiver] --> < receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND" > < intent-filter> < action android:name="com.google.android.c2dm.intent.RECEIVE" /> < category android:name="com.example.airwyntin.notificationtest" /> < /intent-filter> < /receiver> < !-- [END gcm_receiver] --> < !-- [START gcm_listener] --> < service android:name=".MyGcmListenerService" android:exported="false" > < intent-filter> < action android:name="com.google.android.c2dm.intent.RECEIVE" /> < /intent-filter> < /service> < !-- [END gcm_listener] --> < !-- [START instanceId_listener] --> < service android:name=".MyInstanceIDListenerService" android:exported="false"> < intent-filter> < action android:name="com.google.android.gms.iid.InstanceID"/> < /intent-filter> < /service> < !-- [END instanceId_listener] --> < service android:name=".RegistrationIntentService" android:exported="false"> < /service>

my GC么listener service.java:
public class MyGcmListenerService extends GcmListenerService {private static int notifId = 0; private static final String TAG = "MyGcmListenerService"; /** * Called when message is received. * * @param from SenderID of the sender. * @param data Data bundle containing message data as key/value pairs. *For Set of keys use data.keySet(). */ // [START receive_message] @Override public void onMessageReceived(String from, Bundle data) { String message = data.getString("alert"); Log.i(TAG, "From: " + from); if (message != null) { Log.d(TAG, "From: " + from); Log.d(TAG, "Message: " + message); if (from.startsWith("/topics/")) { // message received from some topic. } else { // normal downstream message. }// [START_EXCLUDE] /** * Production applications would usually process the message here. * Eg: - Syncing with server. *- Store message in local database. *- Update UI. *//** * In some cases it may be useful to show a notification indicating to the user * that a message was received. */ sendNotification(message); // [END_EXCLUDE] }} // [END receive_message]/** * Create and show a simple notification containing the received GCM message. * * @param message GCM message received. */ private void sendNotification(String message) { Intent intent = new Intent(this, NotificationView.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("GCM Tesst Message") .setContentText(message) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); //Vibration notificationBuilder.setVibrate(new long[] { 0, 200, 200, 200, 200, 200 }); //LED //notificationBuilder.setLights(Color.RED, 3000, 3000); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notif = notificationBuilder.build(); notif.flags |= Notification.FLAG_AUTO_CANCEL; /*notif.ledARGB = 0xFFff0000; notif.flags = Notification.FLAG_SHOW_LIGHTS; notif.ledOnMS = 100; notif.ledOffMS = 100; */notificationManager.notify(notifId++ /* ID of notification */, notif); } }

my instance ID listener service.Java:
public class MyInstanceIDListenerService extends InstanceIDListenerService {private static final String TAG = "MyInstanceIDLS"; /** * Called if InstanceID token is updated. This may occur if the security of * the previous token had been compromised. This call is initiated by the * InstanceID provider. */ // [START refresh_token] @Override public void onTokenRefresh() { // Fetch updated Instance ID token and notify our app's server of any changes (if applicable). Intent intent = new Intent(this, RegistrationIntentService.class); startService(intent); } // [END refresh_token]}

registration intent service.Java:
public class RegistrationIntentService extends IntentService {private static final String TAG = "RegIntentService"; private static final String[] TOPICS = {"global"}; public RegistrationIntentService() { super(TAG); }@Override protected void onHandleIntent(Intent intent) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); try { // [START register_for_gcm] // Initially this call goes out to the network to retrieve the token, subsequent calls // are local. // R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json. // See https://developers.google.com/cloud-messaging/android/start for details on this file. // [START get_token] InstanceID instanceID = InstanceID.getInstance(this); String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); // [END get_token] Log.i(TAG, "GCM Registration Token: " + token); // TODO: Implement this method to send any registration to your app's servers. sendRegistrationToServer(token); // Subscribe to topic channels subscribeTopics(token); // You should store a boolean that indicates whether the generated token has been // sent to your server. If the boolean is false, send the token to your server, // otherwise your server should have already received the token. sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, true).apply(); // [END register_for_gcm] } catch (Exception e) { Log.d(TAG, "Failed to complete token refresh", e); // If an exception happens while fetching the new token or updating our registration data // on a third-party server, this ensures that we'll attempt the update at a later time. sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false).apply(); } // Notify UI that registration has completed, so the progress indicator can be hidden. Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE); LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); }/** * Persist registration to third-party servers. * * Modify this method to associate the user's GCM registration token with any server-side account * maintained by your application. * * @param token The new token. */ private void sendRegistrationToServer(String token) { // Add custom implementation, as needed. }/** * Subscribe to any GCM topics of interest, as defined by the TOPICS constant. * * @param token GCM token * @throws IOException if unable to reach the GCM PubSub service */ // [START subscribe_topics] private void subscribeTopics(String token) throws IOException { GcmPubSub pubSub = GcmPubSub.getInstance(this); for (String topic : TOPICS) { pubSub.subscribe(token, "/topics/" + topic, null); } } // [END subscribe_topics]}

答案根据GCM的官方声明,它适用于Google Play服务库,因此请尝试检查您的手机是否安装了Google Play服务的最新更新。有时互联网连接问题会导致网络导致GCM推送通知问题,否则您可以检查如果收件人确实收到了邮件,则收货。但是你说当应用程序不在前台时GCM无法正常工作是不正确的
另一答案当用户强行关闭应用程序时:通知不会到达
这是Android平台的一个功能。用户强制停止应用程序会使应用程序处于停止状态,并且不会运行任何代码,包括在broadcast receivers中声明的任何manifest。只有当用户明确启动应用程序时,它才处于接收器被触发的状态。
有关Force Stop的更多文档,请点击以下链接:
  • https://possiblemobile.com/2014/06/effects-android-application-termination/
  • https://developer.android.com/about/versions/android-3.1.html#launchcontrols
另一答案解决此问题的一个简单方法是,“在构建通知时将优先级设置为高”。优先级常数在-2到2(从最低到最高)的范围内变化,0是此字段的默认值。希望这会有所帮助。谢谢。

    推荐阅读