尝试实施将Apple推送通知发送到iPhone客户端应用程序的Java程序...找到以下库:Java APNs
创建以下代码(来自Javapns)以在我的应用程序中使用:
try {
PayLoad payLoad = new PayLoad();
payLoad.addAlert("My alert message");
payLoad.addBadge(45);
payLoad.addSound("default");
PushNotificationManager pushManager = PushNotificationManager.getInstance();
pushManager.addDevice("iPhone", "f4201f5d8278fe39545349d0868a24a3b60ed732");
log.warn("Initializing connectiong with APNS...");
// Connect to APNs
pushManager.initializeConnection(HOST, PORT,
"/etc/Certificates.p12", "password",
SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
Device client = pushManager.getDevice("Lambo");
// Send Push
log.warn("Sending push notification...");
PushNotificationManager.getInstance().sendNotification(client, payLoad);
}
catch (Exception e) {
throw new ApnsPushNotificationException("Unable to send push " + e);
}
当我运行这个应用程序时(你可以看到Log4j语句),没有例外情况发生:
WARN [MyCode] Initializing connectiong with APNS...
WARN [MyCode] Sending push notification...
但是我的客户端应用程序没有收到任何通知!
此外,在iPhone开发人员计划门户网站(IDPP)上执行了以下操作:
创建了基于APNS的SSL证书和密钥
创建并安装了配置文件
在服务器上安装了SSL证书和密钥。
多次阅读Apple推送通知服务指南并注意到以下几点:
(1)在第15页,它指出设备令牌与设备UDID不同(我当前错误地将其作为PushNotificationManager.addDevice()方法中的第二个参数传入(参见上文))。
在第17页,它指出:
“APN使用唯一设备证书中包含的信息生成设备令牌。设备令牌包含设备的标识符。然后使用令牌密钥加密设备令牌并将其返回给设备。设备返回设备作为NSData对象的请求应用程序的令牌。然后,应用程序必须以二进制或十六进制格式将设备令牌传递给其提供者。“
(2)在阅读第33-34页后,我发现我没有包含Objective-C代码,让app注册了APN。
我不是Objective-C开发人员,所以我可以恢复设备代码,还是必须从证书中获取它?
我从哪里获取设备令牌(抱歉,其他人编写了Objective-C客户端应用程序,我是Java开发人员)?
问题(S):
(1)除了不知道从何处获取设备令牌和移动客户端代码注册外,还有其他我没有查看或错过的内容吗?
(2)我是否正确使用Javapns库?
感谢您抽出宝贵时间阅读此内容......
答案 0 :(得分:18)
作为一种可耻的自我宣传,我鼓励使用java-apns
库。您的代码如下所示:
ApnsService service =
APNS.newService()
.withCert("/etc/Certificates.p12", "password")
.withSandboxDestination() // or .withProductionDestination()
.build();
String payload =
APNS.newPayload()
.alertBody("My alert message")
.badge(45)
.sound("default")
.build();
String deviceToken = "f4201f5d8278fe39545349d0868a24a3b60ed732";
log.warn("Sending push notification...");
service.push(deviceToken, payload);
答案 1 :(得分:8)
只是一点提示,为了将收到的令牌转换为适合javapns注册的格式,这段代码就可以解决问题:
- (NSString *)convertTokenToDeviceID:(NSData *)token {
NSMutableString *deviceID = [NSMutableString string];
// iterate through the bytes and convert to hex
unsigned char *ptr = (unsigned char *)[token bytes];
for (NSInteger i=0; i < 32; ++i) {
[deviceID appendString:[NSString stringWithFormat:@"%02x", ptr[i]]];
}
return deviceID;
}
答案 2 :(得分:1)
您的Java代码看起来很稳固!但是,请不要忘记通过PushNotificationManager.closeConnection()
关闭连接。自己清理后很重要。
作为旁注,我注意到您正在添加设备'iPhone',但之后查询'Lambo'。这表明存在错误。
代码中显示的设备令牌不正确。设备令牌,当前为32位长值,将其变为64个字符。我假设在将通知推送到无效令牌时服务器无声地失败!
获取设备令牌的唯一方法是从应用程序本身。正如Push Notification guide建议的那样,iPhone应用程序需要在启动时注册通知。在application:didRegisterForRemoteNotificationsWithDeviceToken:
中,iPhone需要将设备令牌发送到您的java提供程序服务器。 (出于调试目的,您只需NSLog
设备令牌并使用它;它不会在运行中发生变化。)
我建议您在java提供程序服务器中创建一个服务器来接收设备令牌。设置ServerSocket
以接收来自iPhone及其设备令牌的连接(以及您需要的任何其他信息),并将令牌插入数据库中。
答案 3 :(得分:1)
我试过这个并且在发送通知时我一直被绞死,没有任何东西被发送。
问题源于以下功能:
public void sendNotification(Device device, PayLoad payload)
似乎bufferedreader有NULL
BufferedReader in =
new BufferedReader(new InputStreamReader(this.socket.getInputStream() ) );
因此,当这部分代码被点击时,它就会挂起无限循环
logger.debug( "In: [" + in.readLine() + "]" );
此输出为[null]
然后就在那之后循环执行:
while ( ! this.socket.isInputShutdown() ) {
while( in.ready() ) {
logger.debug("ready now");
logger.debug(in.readLine());
System.out.println( this.socket.getInputStream().read() );
}
}
代码进入第一个while循环,等待BufferedReader进入就绪状态 并且一直在等待.....广告是你的悬挂
答案 4 :(得分:0)
您似乎错过了令牌
pushManager.addDevice("iPhone", "f4201f5d8278fe39545349d0868a24a3b60ed732");
进行身份识别和代币检查:
获取令牌的唯一方法是从iPhone应用程序。有效令牌看起来像这样: 1d2d6f34 c5028bca c50df5f9 1992c912 ce7deae8 3bbe7da5 447f6a68 cfecdc0e
答案 5 :(得分:0)
JavaPNS最近更新为2.0,并修复了截至发布日期的所有报告问题。它确实解决了您所描述的问题,并且使用该库比以往更简单(您现在可以通过一行代码推送通知)。