Java GCM推送通知不会传递到设备

Java GCM推送通知不会传递到设备,java,android,jakarta-ee,push-notification,google-cloud-messaging,Java,Android,Jakarta Ee,Push Notification,Google Cloud Messaging,我们(帕诺斯和雷纳-见下面的评论)有一台服务器和几个安卓设备 我们希望通过GCM将推送通知从服务器发送到Android设备 现在我们向GCM服务器发出post请求。GCM服务器的响应是一切正常(success==1,甚至消息id)! 但推送通知从未发送到设备 如果我们使用相同的数据和Chrome插件邮递员,通知会立即发送 我们尝试了很多不同的解决方案。我们总是收到GCM服务器的反馈,表示一切正常,但推送通知不会发送 我们也试过这个: 是用于邮递员请求的数据,该请求工作正常。 Rainer已经提到

我们(帕诺斯和雷纳-见下面的评论)有一台服务器和几个安卓设备

我们希望通过GCM将推送通知从服务器发送到Android设备

现在我们向GCM服务器发出post请求。GCM服务器的响应是一切正常(success==1,甚至消息id)! 但推送通知从未发送到设备

如果我们使用相同的数据和Chrome插件邮递员,通知会立即发送

我们尝试了很多不同的解决方案。我们总是收到GCM服务器的反馈,表示一切正常,但推送通知不会发送

我们也试过这个:

是用于邮递员请求的数据,该请求工作正常。 Rainer已经提到,我们在Java端尝试了几种实现,似乎我们始终能够与服务通信,并收到迄今为止看起来正确的响应:

{
    "multicast_id":7456542468425129822,
    "success":1,
    "failure":0,
    "canonical_ids":0,
    "results":
    [{
        "message_id":"0:1457548597263237%39c590d7f9fd7ecd"
    }]
} 

不确定我是否在正确的轨道上,但您是指下游HTTP消息(纯文本)

尝试将以下JSON发送到服务(来自Postman),再次得到肯定响应,但这次通知没有到达设备(为了说明这一点,目前设备上没有应用程序主动监听传入的通知->首先,我们只想确保它们通常到达设备上):


感谢大家在这里提供的帮助,但老实说,这个问题确实令人沮丧。与接口\服务通信时,如果请求中包含可能会最终阻止GCM向设备发送推送通知的有害内容,则该接口\服务似乎无法返回有用的响应,这让人感觉很痛苦。I如果邮递员也会不及格,我会说,好吧,你不能这么傻:-)

下面是我们已经使用过的一些快速脏的实现

  • 范例

        try 
        {
           URL url = new URL(apiUrl);
           HttpsURLConnection conn = (HttpsURLConnection);//also tried HttpURLConnection
           url.openConnection();
           conn.setDoOutput(true);
           conn.setRequestMethod("POST");
           conn.setRequestProperty("Content-Type", "application/json");
           conn.setRequestProperty("Authorization", "key="+apiKey);
    
           conn.setDoOutput(true);
    
           String json = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
    
           OutputStream os = conn.getOutputStream();
           os.write(json.getBytes());
           os.flush();
       }
       catch(Exception exc)
       {
         System.out.println("Error while trying to send push notification: "+exc);
       }
    
    HttpClient httpClient = HttpClientBuilder.create().build(); 
    
    try 
    {
        HttpPost request = new HttpPost(apiUrl);
        StringEntity params =new StringEntity("{\"priority\":\"high\",\"notification\":{\title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}");
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Authorization", "key="+apiKey);
        request.setEntity(params);
        HttpResponse response = httpClient.execute(request);
    
        // check response
        System.out.println(response.getStatusLine().toString());
    }catch (Exception exc) {
        System.out.println("Error while trying to send push notification: "+exc);
    } finally {
        httpClient.getConnectionManager().shutdown(); //Deprecated
    }
    
    try
    {
        String charset = "UTF-8"; 
        URLConnection connection = new URL(apiUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Accept-Charset", charset);
        connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
        connection.setRequestProperty("Authorization", "key="+apiKey);
    
        String param = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
        try (OutputStream output = connection.getOutputStream()) 
        {
            output.write(param.getBytes(charset));
        }
    
        InputStream response = connection.getInputStream();
    }
    catch(Exception exc)
    {
        System.out.println("Error while trying to send push notification: "+exc);
    }
    
    try 
    {
        // prepare JSON
        JSONObject jGcmData = new JSONObject();
        JSONObject jData = new JSONObject();
    
        jData.put("message", "{ \"data\": {\"score\": \"5x1\",\"time\": \"15:10\"},\"to\" : \""+deviceToken+"\"}");
    
        jGcmData.put("to", deviceToken);
    
        jGcmData.put("data", jData);
    
        // Create connection to send GCM Message request.
        URL url = new URL("https://android.googleapis.com/gcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Authorization", "key=" + apiKey);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
    
        // Send GCM message content.
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(jGcmData.toString().getBytes());
    
        // Read GCM response.
        InputStream inputStream = conn.getInputStream();
        String resp = IOUtils.toString(inputStream);
        System.out.println(resp);
     } catch (IOException e) {
        System.out.println("Unable to send GCM message. "+e);
    }
    
  • 范例

        try 
        {
           URL url = new URL(apiUrl);
           HttpsURLConnection conn = (HttpsURLConnection);//also tried HttpURLConnection
           url.openConnection();
           conn.setDoOutput(true);
           conn.setRequestMethod("POST");
           conn.setRequestProperty("Content-Type", "application/json");
           conn.setRequestProperty("Authorization", "key="+apiKey);
    
           conn.setDoOutput(true);
    
           String json = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
    
           OutputStream os = conn.getOutputStream();
           os.write(json.getBytes());
           os.flush();
       }
       catch(Exception exc)
       {
         System.out.println("Error while trying to send push notification: "+exc);
       }
    
    HttpClient httpClient = HttpClientBuilder.create().build(); 
    
    try 
    {
        HttpPost request = new HttpPost(apiUrl);
        StringEntity params =new StringEntity("{\"priority\":\"high\",\"notification\":{\title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}");
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Authorization", "key="+apiKey);
        request.setEntity(params);
        HttpResponse response = httpClient.execute(request);
    
        // check response
        System.out.println(response.getStatusLine().toString());
    }catch (Exception exc) {
        System.out.println("Error while trying to send push notification: "+exc);
    } finally {
        httpClient.getConnectionManager().shutdown(); //Deprecated
    }
    
    try
    {
        String charset = "UTF-8"; 
        URLConnection connection = new URL(apiUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Accept-Charset", charset);
        connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
        connection.setRequestProperty("Authorization", "key="+apiKey);
    
        String param = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
        try (OutputStream output = connection.getOutputStream()) 
        {
            output.write(param.getBytes(charset));
        }
    
        InputStream response = connection.getInputStream();
    }
    catch(Exception exc)
    {
        System.out.println("Error while trying to send push notification: "+exc);
    }
    
    try 
    {
        // prepare JSON
        JSONObject jGcmData = new JSONObject();
        JSONObject jData = new JSONObject();
    
        jData.put("message", "{ \"data\": {\"score\": \"5x1\",\"time\": \"15:10\"},\"to\" : \""+deviceToken+"\"}");
    
        jGcmData.put("to", deviceToken);
    
        jGcmData.put("data", jData);
    
        // Create connection to send GCM Message request.
        URL url = new URL("https://android.googleapis.com/gcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Authorization", "key=" + apiKey);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
    
        // Send GCM message content.
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(jGcmData.toString().getBytes());
    
        // Read GCM response.
        InputStream inputStream = conn.getInputStream();
        String resp = IOUtils.toString(inputStream);
        System.out.println(resp);
     } catch (IOException e) {
        System.out.println("Unable to send GCM message. "+e);
    }
    
  • 范例

        try 
        {
           URL url = new URL(apiUrl);
           HttpsURLConnection conn = (HttpsURLConnection);//also tried HttpURLConnection
           url.openConnection();
           conn.setDoOutput(true);
           conn.setRequestMethod("POST");
           conn.setRequestProperty("Content-Type", "application/json");
           conn.setRequestProperty("Authorization", "key="+apiKey);
    
           conn.setDoOutput(true);
    
           String json = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
    
           OutputStream os = conn.getOutputStream();
           os.write(json.getBytes());
           os.flush();
       }
       catch(Exception exc)
       {
         System.out.println("Error while trying to send push notification: "+exc);
       }
    
    HttpClient httpClient = HttpClientBuilder.create().build(); 
    
    try 
    {
        HttpPost request = new HttpPost(apiUrl);
        StringEntity params =new StringEntity("{\"priority\":\"high\",\"notification\":{\title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}");
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Authorization", "key="+apiKey);
        request.setEntity(params);
        HttpResponse response = httpClient.execute(request);
    
        // check response
        System.out.println(response.getStatusLine().toString());
    }catch (Exception exc) {
        System.out.println("Error while trying to send push notification: "+exc);
    } finally {
        httpClient.getConnectionManager().shutdown(); //Deprecated
    }
    
    try
    {
        String charset = "UTF-8"; 
        URLConnection connection = new URL(apiUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Accept-Charset", charset);
        connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
        connection.setRequestProperty("Authorization", "key="+apiKey);
    
        String param = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
        try (OutputStream output = connection.getOutputStream()) 
        {
            output.write(param.getBytes(charset));
        }
    
        InputStream response = connection.getInputStream();
    }
    catch(Exception exc)
    {
        System.out.println("Error while trying to send push notification: "+exc);
    }
    
    try 
    {
        // prepare JSON
        JSONObject jGcmData = new JSONObject();
        JSONObject jData = new JSONObject();
    
        jData.put("message", "{ \"data\": {\"score\": \"5x1\",\"time\": \"15:10\"},\"to\" : \""+deviceToken+"\"}");
    
        jGcmData.put("to", deviceToken);
    
        jGcmData.put("data", jData);
    
        // Create connection to send GCM Message request.
        URL url = new URL("https://android.googleapis.com/gcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Authorization", "key=" + apiKey);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
    
        // Send GCM message content.
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(jGcmData.toString().getBytes());
    
        // Read GCM response.
        InputStream inputStream = conn.getInputStream();
        String resp = IOUtils.toString(inputStream);
        System.out.println(resp);
     } catch (IOException e) {
        System.out.println("Unable to send GCM message. "+e);
    }
    
  • 范例

        try 
        {
           URL url = new URL(apiUrl);
           HttpsURLConnection conn = (HttpsURLConnection);//also tried HttpURLConnection
           url.openConnection();
           conn.setDoOutput(true);
           conn.setRequestMethod("POST");
           conn.setRequestProperty("Content-Type", "application/json");
           conn.setRequestProperty("Authorization", "key="+apiKey);
    
           conn.setDoOutput(true);
    
           String json = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
    
           OutputStream os = conn.getOutputStream();
           os.write(json.getBytes());
           os.flush();
       }
       catch(Exception exc)
       {
         System.out.println("Error while trying to send push notification: "+exc);
       }
    
    HttpClient httpClient = HttpClientBuilder.create().build(); 
    
    try 
    {
        HttpPost request = new HttpPost(apiUrl);
        StringEntity params =new StringEntity("{\"priority\":\"high\",\"notification\":{\title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}");
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Authorization", "key="+apiKey);
        request.setEntity(params);
        HttpResponse response = httpClient.execute(request);
    
        // check response
        System.out.println(response.getStatusLine().toString());
    }catch (Exception exc) {
        System.out.println("Error while trying to send push notification: "+exc);
    } finally {
        httpClient.getConnectionManager().shutdown(); //Deprecated
    }
    
    try
    {
        String charset = "UTF-8"; 
        URLConnection connection = new URL(apiUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Accept-Charset", charset);
        connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
        connection.setRequestProperty("Authorization", "key="+apiKey);
    
        String param = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
        try (OutputStream output = connection.getOutputStream()) 
        {
            output.write(param.getBytes(charset));
        }
    
        InputStream response = connection.getInputStream();
    }
    catch(Exception exc)
    {
        System.out.println("Error while trying to send push notification: "+exc);
    }
    
    try 
    {
        // prepare JSON
        JSONObject jGcmData = new JSONObject();
        JSONObject jData = new JSONObject();
    
        jData.put("message", "{ \"data\": {\"score\": \"5x1\",\"time\": \"15:10\"},\"to\" : \""+deviceToken+"\"}");
    
        jGcmData.put("to", deviceToken);
    
        jGcmData.put("data", jData);
    
        // Create connection to send GCM Message request.
        URL url = new URL("https://android.googleapis.com/gcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Authorization", "key=" + apiKey);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
    
        // Send GCM message content.
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(jGcmData.toString().getBytes());
    
        // Read GCM response.
        InputStream inputStream = conn.getInputStream();
        String resp = IOUtils.toString(inputStream);
        System.out.println(resp);
     } catch (IOException e) {
        System.out.println("Unable to send GCM message. "+e);
    }
    

  • 您也可以发布您使用的URL。有一个新的GCM enpoint,如下所示:

    我还不确定是什么导致了你这边的问题。但是,以下各项已经过测试并正在发挥作用:

    public class Main {
    
        public static void main(String[] args) {
        // write your code here
    
            try {
    
                String url = "https://gcm-http.googleapis.com/gcm/send";
    
                URL obj = new URL(url);
                HttpsURLConnectionImpl conn = (HttpsURLConnectionImpl) obj.openConnection();
    
    
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setDoOutput(true);
    
                conn.setRequestMethod("POST");
                conn.setRequestProperty ("Authorization", "key=***");
    
                String title = "Short title";
                String body = "A body :D";
                String token = "****";
                String data =  "{ \"notification\": { \"title\": \"" + title +"\", \"body\": \"" + body + "\" }, \"to\" : \"" + token + "\", \"priority\" : \"high\" }";
                OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
                out.write(data);
                out.close();
    
                String text = getText(new InputStreamReader(conn.getInputStream()));
                System.out.println(text);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static String getText(InputStreamReader in) throws IOException {
            StringBuilder sb=new StringBuilder();
            BufferedReader br = new BufferedReader(in);
            String read;
            while((read=br.readLine()) != null) {
                sb.append(read);
            }
            br.close();
            return sb.toString();
        }
    }
    

    迈克,以你为例,这对我们也有好处。在将您的实现与我们这边的比较之后,我发现唯一真正的区别是使用的URL!! 不知何故,我们的Java实现中使用的URL是

    看来这是对的,顺便说一下,它也被用于我们的邮递员测试


    但是为什么我们失败测试的URL仍然有效并返回响应呢

    在json中将优先级设置为high对我来说解决了这个问题

    'registration_ids' => $id,
    'priority' => 'high',
    'data' => $load
    

    在我们的案例中,客户端Android设备存在间歇性互联网连接问题,即网络中断,从而导致通知传递失败。我们使用以下JAVA GCM代码解决了可靠性问题:

    gcmPayload.setTime_to_live(messageExpiryTime); //in seconds. Set notification message expiry to give user time to receive it in case they have intermittent internet connection, or phone was off
    gcmPayload.setPriority("high");
    
    和APNS代码:

    ApnsService apnsService = APNS.newService().withCert(certificateStream, configurations.getApnPassword()).withProductionDestination().build();
    PayloadBuilder payloadBuilder = APNS.newPayload();
    ...
    payloadBuilder.instantDeliveryOrSilentNotification(); //same as content-available=true
    String payload = payloadBuilder.build();
    
    Integer now =  (int)(new Date().getTime()/1000);
    //use EnhancedApnsNotification to set message expiry time
    for(String deviceToken : deviceTokens) {
        EnhancedApnsNotification notification = new EnhancedApnsNotification(EnhancedApnsNotification.INCREMENT_ID() /* Next ID */,
            now + messageExpiryTime /* Expiry time in seconds */,
            deviceToken /* Device Token */,
            payload);
            apnsService.push(notification);
    }
    

    如果你的后端服务器时间不同于客户端移动应用程序时间,请记住考虑时区。

    你能分享一些关于邮递员请求的代码和更多信息吗?设备上安装了谷歌播放服务吗?您的防火墙是否允许通过tcp 5228-5230进行空闲连接?如果连接断开,gcm服务最多需要15分钟才能重新连接。全部已安装。港口开放。我们尝试了wifi和手机网络。当我们通过邮递员发送时,我们会收到推送通知。如果您通过邮递员接收到通知,那么在设备端一切正常。能否添加用于发送设备未接收到的请求的代码?我猜想HTTP请求与您的代码有所不同。您是否可以尝试向设备发送一条非通知消息,并查看您是否在Gcm服务中收到该消息(可能添加一条
    Log
    语句)。