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应用程序,以便在应用程序处于后台时显示横幅. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
