Codename One Windows推送问题咨询:桌面版与UWP版异常
问题1:Windows Desktop Build推送注册回调未触发
我们的应用采用Windows Desktop Build构建,打包为MSIX后通过微软商店分发,现需添加推送通知功能。已实现推送注册逻辑,Android和iOS端运行正常,但Windows Desktop Build下注册回调未触发,请问桌面版客户端是否支持推送通知?
问题2:UWP构建推送发送报错
使用UWP构建时,推送注册正常并能获取到推送密钥,但通过Codename One推送服务发送消息时(Java后端POST请求或浏览器手动GET)出现以下错误:
javax.ws.rs.ProcessingException: URI is not absolute org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255) org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:667) org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664) org.glassfish.jersey.internal.Errors.process(Errors.java:315) org.glassfish.jersey.internal.Errors.process(Errors.java:297) org.glassfish.jersey.internal.Errors.process(Errors.java:228) org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664) ar.com.fernandospr.wns.client.WnsClient.push(WnsClient.java:135) ar.com.fernandospr.wns.client.WnsClient.push(WnsClient.java:172) ar.com.fernandospr.wns.WnsService.pushToast(WnsService.java:153) ar.com.fernandospr.wns.WnsService.pushToast(WnsService.java:141) com.codename1.server.push.SendPush.service(SendPush.java:708) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
疑似问题出在设备ID的cn1-win-前缀(示例:cn1-win-aHR0cHM6Ly93bn.....):移除该前缀后服务器返回“无效设备ID”,移除其他字符则仍返回内部服务器错误。
后端发送代码
param为存储推送设置的实体类,param.getServiceURL()对应Codename One推送服务地址,测试阶段硬编码了Windows SID和Claim Secret:
HttpURLConnection connection = (HttpURLConnection) new URL(param.getServiceURL()).openConnection(); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); String queryString = "token=" + param.getAndroidToken(); queryString = queryString + "&type=" + URLEncoder.encode(String.valueOf(param.getPushType()), "UTF-8"); queryString = queryString + "&body=" + URLEncoder.encode(theMessage, "UTF-8"); if (param.isTestPush()) { //Limit device to Testing Device String x = "&device=" + URLEncoder.encode(param.getTestPushKey().trim(), "UTF-8"); queryString = queryString.concat(x); } else { //Add Devices to send to for (String deviceId : devices) { String x = "&device=" + URLEncoder.encode(deviceId, "UTF-8"); queryString = queryString.concat(x); } } //Android queryString = queryString + "&auth=" + URLEncoder.encode(param.getAuthorizationKey(), "UTF-8"); //iOS queryString = queryString + "&certPassword=" + URLEncoder.encode(param.getIosCertPassword(), "UTF-8"); queryString = queryString + "&cert=" + URLEncoder.encode(param.getIosCertUrl(), "UTF-8"); //Windows queryString = queryString + "&sid=" + URLEncoder.encode("ms-app://s-1-15-2-.....", "UTF-8"); queryString = queryString + "&client_secret=" + URLEncoder.encode("VUbR8T1O......", "UTF-8"); try ( OutputStream output = connection.getOutputStream()) { output.write(queryString.getBytes("UTF-8")); } int c = connection.getResponseCode(); if (c == 200) { //Success - Read JSON to check indavidual device sent status } else { //Error - Sending Failed - Read connection.getErrorStream and print to logs }
解决方案
针对问题1:Windows Desktop Build推送支持情况
Codename One的Windows Desktop Build(基于Swing/JavaFX)不原生支持推送通知,这类桌面应用未集成Windows推送服务(WNS)的能力,因此无法触发推送注册回调。只有UWP构建的版本才能支持WNS推送,建议采用UWP构建来实现Windows平台的推送功能。
针对问题2:UWP推送发送报错修复
错误URI is not absolute源于WNS请求地址格式错误,结合设备ID和请求参数问题,修复步骤如下:
保留设备ID前缀:
cn1-win-前缀是Codename One服务识别Windows设备的标识,绝对不能移除,移除后服务无法识别设备类型,会返回“无效设备ID”。精简请求参数:推送时需根据目标平台传递对应参数,Windows推送不需要Android的
auth、iOS的cert/certPassword参数,否则会导致服务逻辑混淆。修改后的参数构建代码如下:
HttpURLConnection connection = (HttpURLConnection) new URL(param.getServiceURL()).openConnection(); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); // Windows推送不需要Android全局token,留空即可 String queryString = "token="; queryString += "&type=" + URLEncoder.encode(String.valueOf(param.getPushType()), "UTF-8"); queryString += "&body=" + URLEncoder.encode(theMessage, "UTF-8"); if (param.isTestPush()) { queryString += "&device=" + URLEncoder.encode(param.getTestPushKey().trim(), "UTF-8"); } else { for (String deviceId : devices) { queryString += "&device=" + URLEncoder.encode(deviceId, "UTF-8"); } } // 仅保留Windows相关参数 queryString += "&sid=" + URLEncoder.encode("ms-app://s-1-15-2-.....", "UTF-8"); queryString += "&client_secret=" + URLEncoder.encode("VUbR8T1O......", "UTF-8"); try (OutputStream output = connection.getOutputStream()) { output.write(queryString.getBytes("UTF-8")); } int c = connection.getResponseCode(); if (c == 200) { //Success - Read JSON to check individual device sent status } else { //Error - Sending Failed - Read connection.getErrorStream and print to logs }
- 额外检查项:
- 确认Windows SID和Client Secret从微软开发者后台正确获取,且应用已启用WNS推送权限;
- 确保设备ID完整无截断,
cn1-win-后的Base64编码内容是完整的WNS推送URI。
内容的提问来源于stack exchange,提问作者ASD Solutions

