java – Google Cloud Messaging:当iOS App处于后台时,不会收到
我已按照本教程
https://developers.google.com/cloud-messaging/ios/client在我的iOS应用程序上实现GCM.我的应用服务器是一个用Java编写的谷歌应用程序引擎,我使用gcm-server.jar
https://github.com/google/gcm库.我认为我的证书很好,我可以注册,获取令牌甚至接收我的应用服务器发送的消息的内容.但是,当应用程序处于后台时,我不会收到任何通知警报,只有在我单击应用程序图标重新启动时才会收到通知.
我认为这是因为我只实现了didReceiveRemoteNotification:而不是didReceiveRemoteNotification:fetchCompletionHandler:所以我实现了它而不是第一个但我在后台时没有收到通知,更糟糕的是,应用程序崩溃说“无法识别的选择器已发送”实例didReceiveRemoteNotification:“就像userInfo中出错了一样.我确实允许在xCode中使用背景模式.这是我使用的代码: AppDelegate () @property (nonatomic,strong) NSDictionary *registrationOptions; @property (nonatomic,strong) GGLInstanceIDTokenHandler registrationHandler; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //-- Set Notification [[GCMService sharedInstance] startWithConfig:[GCMConfig defaultConfig]]; if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) { NSLog(@"Case iOS8"); // iOS 8 Notifications [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; [application registerForRemoteNotifications]; } else { NSLog(@"Case iOS7"); // iOS < 8 Notifications [application registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)]; } self.registrationHandler = ^(NSString *registrationToken,NSError *error){ if (registrationToken != nil) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:registrationToken forKey:TOKENGCM]; NSLog(@"Registration Token: %@",registrationToken); //some code } else { NSLog(@"Registration to GCM failed with error: %@",error.localizedDescription); } }; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { } - (void)applicationDidEnterBackground:(UIApplication *)application { [[GCMService sharedInstance] disconnect]; } - (void)applicationWillEnterForeground:(UIApplication *)application { } - (void)applicationDidBecomeActive:(UIApplication *)application { // Connect to the GCM server to receive non-APNS notifications [[GCMService sharedInstance] connectWithHandler:^(NSError *error) { if (error) { NSLog(@"Could not connect to GCM: %@",error.localizedDescription); } else { NSLog(@"Connected to GCM"); // ... } }]; } - (void)applicationWillTerminate:(UIApplication *)application { } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // Start the GGLInstanceID shared instance with the default config and request a registration // token to enable reception of notifications [[GGLInstanceID sharedInstance] startWithConfig:[GGLInstanceIDConfig defaultConfig]]; self.registrationOptions = @{kGGLInstanceIDRegisterAPNSOption:deviceToken,kGGLInstanceIDAPNSServerTypeSandboxOption:@NO}; [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:SENDER_ID scope:kGGLInstanceIDScopeGCM options:self.registrationOptions handler:self.registrationHandler]; } - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSLog(@"Error in registration. Error: %@",err); } - (void)onTokenRefresh { // A rotation of the registration tokens is happening,so the app needs to request a new token. NSLog(@"The GCM registration token needs to be changed."); [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:SENDER_ID scope:kGGLInstanceIDScopeGCM options:self.registrationOptions handler:self.registrationHandler]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"Notification received: %@",userInfo);//This does print the content of my message in the console if the app is in foreground UIApplicationState state = [application applicationState]; if (state == UIApplicationStateActive) { NSString *cancelTitle = @"Close"; NSString *showTitle = @"Show"; NSString *message = [[userInfo valueForKey:@"aps"] valueForKey:@"alert"]; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Some title" message:message delegate:self cancelButtonTitle:cancelTitle otherButtonTitles:showTitle,nil]; [alertView show]; } else{ NSLog(@"Notification received while inactive"); [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 99]; UIAlertView *BOOM = [[UIAlertView alloc] initWithTitle:@"BOOM" message:@"app was INACTIVE" delegate:self cancelButtonTitle:@"a-ha!" otherButtonTitles:nil]; [BOOM show]; NSLog(@"App was NOT ACTIVE"); [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification!" object:nil userInfo:userInfo]; } // This works only if the app started the GCM service [[GCMService sharedInstance] appDidReceiveMessage:userInfo]; } //Implement that causes unrecognized selector crash - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler { NSLog(@"Notification received: %@",userInfo); // This works only if the app started the GCM service [[GCMService sharedInstance] appDidReceiveMessage:userInfo]; // Handle the received message // Invoke the completion handler passing the appropriate UIBackgroundFetchResult value // [START_EXCLUDE] [[NSNotificationCenter defaultCenter] postNotificationName:@"notif" object:nil userInfo:userInfo]; handler(UIBackgroundFetchResultNoData); // [END_EXCLUDE] } @end 有人可以弄清楚当我不在前台时我没有收到通知吗? 编辑:服务器端用于发送GCM消息的Java代码: public static MulticastResult sendViaGCM(String tag,String message,List<String> deviceIdsList) throws IOException { Sender sender = new Sender(Constantes.API_KEY); // This message object is a Google Cloud Messaging object Message msg = new Message.Builder().addData("tag",tag).addData("message",message).build(); MulticastResult result = sender.send(msg,deviceIdsList,5); return result; } EDIT2:POST请求的屏幕截图 EDIT3:我现在从我的应用服务器发送的请求: public static void sendGCMMessage(String tag,List<String> deviceIdsList) { String request = "https://gcm-http.googleapis.com/gcm/send"; try{ URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); //conn.setInstanceFollowRedirects(false); conn.setRequestMethod("POST"); //Les deux headers obligatoires: conn.setRequestProperty("Content-Type","application/json"); conn.setRequestProperty("Authorization","key=" + API_KEY); //Construction du JSON: JSONObject fullJSON = new JSONObject(); JSONObject data=new JSONObject(); JSONObject notification=new JSONObject(); data.put("tag",tag); data.put("message",message); notification.put("sound","default"); notification.put("badge","1"); notification.put("title","default"); notification.put("body",message); fullJSON.put("registration_ids",deviceIdsList); fullJSON.put("notification",notification); fullJSON.put("content_available","true"); fullJSON.put("data",data); //Phase finale: OutputStreamWriter wr= new OutputStreamWriter(conn.getOutputStream()); wr.write(fullJSON.toString()); wr.flush(); wr.close();//pas obligatoire //conn.setUseCaches(false); } catch(Exception e){ e.printStackTrace(); } 解决方法
基于
GCM documentation,您可以将content_available设置为true.
(在iOS上,使用此字段表示APNS有效内容中可用的内容.当发送通知或消息并将其设置为true时,将唤醒非活动客户端应用程序.在Android上,数据消息默认唤醒应用程序. Chrome目前不受支持.) content_available与Apple的内容相对应,您可以在this Apple Push Notification Service documentation找到它. 此外,您应该使用Notification playload将消息发送到iOS应用程序,以便在应用程序处于后台时显示横幅. 这是一个示例HTTP请求: https://gcm-http.googleapis.com/gcm/send Content-Type:application/json Authorization:key=API_KEY { "to" : "REGISTRATION_TOKEN","notification" : { "sound" : "default","badge" : "1","title" : "default","body" : "Test",},"content_available" : true,} The Java library只是一个示例,您可以添加其他字段.例如,在Message.java类中,您可以添加两个私有变量,一个是private final Boolean contentAvailable,另一个是private final< String,String>通知. 您可以通过执行curl -i -H“Content-Type:application / json”-H“Authorization:key = API_KEY”-X POST -d'{“to”:“REGISTRATION_TOKEN”,在终端中尝试HTTP请求notificaiton“:{”sound“:”default“,”badge“:”1“,”title“:”default“,”body“:”test“,”content_available“:true}’https:// android .googleapis.com / gcm / send,或者在Postman中试用. 编辑: 如果您的应用程序已终止,并且您希望在设备中显示推送通知,则可以在HTTP请求正文中设置high priority(请注意,将消息设置为高优先级会导致电池消耗与正常优先级消息相比更多) . HTTP请求示例: { "to" : "REGISTRATION_TOKEN","priority" : "normal",} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – Android Webview,缩放内容以适应屏幕
- java – 作业调度setRequiresDeviceIdle(true)和setPeriodi
- JAVA并发工具类---------------(CyclicBarrier)
- java.util.concurrent.ExecutionException 问题解决方法
- java – 用于标识对象功能的标记接口或布尔方法?
- JAVA static 关键字
- java – 如何将IPV6地址转换为IPV4地址?
- SpringMVC接收多个对象的4种方法
- Apache-commons-net lib(Java)的受控日志记录
- 如何在java中找到两个时间戳的区别?