I'm developing the server part of a system that has to send messages to a device. This was working fine with the GoogleLogin method, but I want to migrate it to OAuth 2.0 since the other authentication method has been deprecated.
In the Google API console I created a project and then I created a key for a service account.
This is the code I'm using to authenticate the server:
public boolean authenticateServer(){
try {
File privateKey =
new File(getClass().getResource("/something-privatekey.p12").toURI());
GoogleCredential cred =
new GoogleCredential.Builder().setTransport(new NetHttpTransport())
.setJsonFactory(new JacksonFactory())
.setServiceAccountId("[email protected]")
.setServiceAccountScopes("https://android.apis.google.com/c2dm")
.setServiceAccountPrivateKeyFromP12File(privateKey)
.addRefreshListener(this)
.build();
boolean success = cred.refreshToken();
this.credential = cred;
return success;
}
catch (Exception ex) {
//handle this
}
return false;
}
When I execute this, the method onTokenResponse
gets called and I get an access_token
with token_type
"Bearer" expiring in 3600 seconds. So far, so good.
This is the code I'm using to send the message to the device, which is always giving me a 401 status (not authorized). Any ideas?
private static String UTF8 = "UTF-8";
public void sendMessage(String text, String registrationId) {
try {
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder
.append("registration_id")
.append("=")
.append(registrationId);
postDataBuilder.append("&")
.append("collapse_key")
.append("=")
.append("0");
postDataBuilder.append("&")
.append("data.payload")
.append("=")
.append(URLEncoder.encode(text, UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
URL url = new URL("https://android.apis.google.com/c2dm/send");
HostnameVerifier hVerifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(hVerifier);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty(
"Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty(
"Content-Length", Integer.toString(postData.length));
conn.setRequestProperty(
"Authorization", "Bearer " + credential.getAccessToken());
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int sw = conn.getResponseCode();
System.out.println("" + sw);
}
catch (IOException ex){
//handle this
}
}
Thanks!
Since C2DM is in a beta status as of now, the only way to make it work using OAuth2.0 is to create a Web application client Id, instead of a Service account (in the Google APIs console).
I've followed the steps in http://michsan.web.id/content/how-code-android-c2dm-oauth-2 and it worked perfectly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With