2013-09-08 8 views
7

Próbuję skonfigurować Google Cloud Messaging dla mojej aplikacji i używam Google App Engine na moim serwerze. Mam klucz API, ale nie mogę nawiązać połączenia z serwerami Google do przesyłania wiadomości w chmurze. Oto mój kod.Nie można połączyć się z serwerem Google Cloud Messaging (GCM) za pomocą Google App Engine (GAE)

HttpClient client = new DefaultHttpClient(); 
HttpPost post = new HttpPost("https://android.googleapis.com/gcm/send"); 
     try { 

      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
      nameValuePairs.add(new BasicNameValuePair("registration_id", regId)); 
      nameValuePairs.add(new BasicNameValuePair("data.message", messageText));  

      post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

      post.setHeader("Authorization", "key=*MY_API_KEY_HERE*"); 
      post.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); 


      Header[] s=post.getAllHeaders(); 


      System.out.println("The header from the httpclient:"); 

      for(int i=0; i < s.length; i++){ 
      Header hd = s[i]; 

      System.out.println("Header Name: "+hd.getName() 
        +"  "+" Header Value: "+ hd.getValue()); 
      } 


      HttpResponse response = client.execute(post); 
      BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
      String line = ""; 
      while ((line = rd.readLine()) != null) { 
      System.out.println(line); 
      } 

      } catch (IOException e) { 
       e.printStackTrace(); 
     } 

Kiedy patrzę na dziennik, nagłówki są ustawiane prawidłowo. Jednakże pojawia się błąd, który mówi

org.apache.http.impl.client.DefaultRequestDirector tryConnect: I/O wyjątek (java.net.SocketException) złowionych po podłączeniu do hosta docelowego: Permission denied: Próba aby uzyskać dostęp do zablokowanego odbiorcy bez pozwolenia. (zmapowany-IPv4)

Włączyłem komunikację w chmurze Google w konsoli Google APIs i kilka razy sprawdziłem klucz API. Nie mam pojęcia, dlaczego mnie odrzucono. Czy jest jakiś słoik na wojnie, czy coś, co muszę umieścić w manifeście?

Dzięki za przeczytanie tego! Mark

+0

Czy to możliwe, że zdefiniował zestaw białych list adresów IP z kluczem API, a adres IP, z którym próbujesz się połączyć z GCM, nie znajduje się na tej liście? – Eran

+0

Nie, dostęp API jest ustawiony na dowolny dozwolony adres IP. –

+0

Skąd czerpiesz swój klucz API?Wszystko, co mogę znaleźć, to kluczowa para. –

Odpowiedz

2

Miałem ten sam problem i używałem czegoś podobnego do tego, z czego korzystasz.

  1. miałem w celu umożliwienia rozliczenia na mojej aplikacji GAE (który prawdopodobnie masz, ale nie byłem świadomy, że musiałbym)
  2. Czytaj https://developers.google.com/appengine/docs/ java/gniazda/i https://developers.google.com/appengine/docs/java/urlfetch/

Dlatego mój kod, który wyglądał jak twoja przedtem wygląda następującą:

String json ="{}"; 
URL url = new URL("https://android.googleapis.com/gcm/send"); 
HTTPRequest request = new HTTPRequest(url, HTTPMethod.POST); 
request.addHeader(new HTTPHeader("Content-Type","application/json")); 
request.addHeader(new HTTPHeader("Authorization", "key=<>")); 
request.setPayload(json.getBytes("UTF-8")); 
HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request); 
0

i również wdrażał GCM z GAE, i miałem taki błąd:

com.google.apphosting.api.ApiProxy$FeatureNotEnabledException: The Socket API will be enabled for this application once billing has been enabled in the admin console. 

Nikunj odpowiedział mi również. Po wdrożeniu tego, co zasugerował, powiadomienia są dostarczane do urządzenia, bez potrzeby włączania rozliczeń dla mojej aplikacji GAE. Oto moja realizacja, na wszelki wypadek, może być przydatny dla kogoś z tym samym problemem:

private void sendNotificationRequestToGcm(List<String> registrationIds) { 
    LOG.info("In sendNotificationRequestToGcm method!"); 
    JSONObject json = new JSONObject(); 
    JSONArray jasonArray = new JSONArray(registrationIds); 
    try { 
     json.put("registration_ids", jasonArray); 
    } catch (JSONException e2) { 
     LOG.severe("JSONException: " + e2.getMessage()); 
    } 
    String jsonString = json.toString(); 
    LOG.info("JSON payload: " + jsonString); 

    com.google.appengine.api.urlfetch.HTTPResponse response; 
    URL url; 
    HTTPRequest httpRequest; 
    try { 
     //GCM_URL = https://android.googleapis.com/gcm/send 
     url = new URL(GCM_URL); 
     httpRequest = new HTTPRequest(url, HTTPMethod.POST); 
     httpRequest.addHeader(new HTTPHeader("Content-Type","application/json")); 
     httpRequest.addHeader(new HTTPHeader("Authorization", "key=" + API_KEY)); 
     httpRequest.setPayload(jsonString.getBytes("UTF-8")); 
     LOG.info("Sending POST request to: " + GCM_URL); 
     response = URLFetchServiceFactory.getURLFetchService().fetch(httpRequest); 
     LOG.info("Status: " + response.getResponseCode());    
     List<HTTPHeader> hdrs = response.getHeaders(); 
     for(HTTPHeader header : hdrs) { 
      LOG.info("Header: " + header.getName()); 
      LOG.info("Value: " + header.getValue()); 
     }    
    } catch (UnsupportedEncodingException e1) { 
     LOG.severe("UnsupportedEncodingException" + e1.getMessage()); 
    } catch (MalformedURLException e1) { 
     LOG.severe("MalformedURLException" + e1.getMessage()); 
    } catch (IOException e) { 
     LOG.severe("URLFETCH IOException" + e.getMessage()); 
    } 
} 

nadzieję, że to pomoże ktoś ...

-1

Najprostszym sposobem jest użycie gcm-server.jar (które można dostać od here).

Następnie kod trzeba wysłać wiadomość GCM będzie wyglądać następująco:

Sender sender = new Sender(apiKey); 
Message message = new Message.Builder() 
    .addData("message", "this is the message") 
    .addData("other-parameter", "some value") 
    .build(); 
Result result = sender.send(message, registrationId, numOfRetries); 

Oto Gradle zależność: compile 'com.google.gcm:gcm-server:1.0.0' i mvnrepository url

source