Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gcm.server;
import static com.google.android.gcm.server.Constants.GCM_SEND_ENDPOINT;
import static com.google.android.gcm.server.Constants.JSON_CANONICAL_IDS;
import static com.google.android.gcm.server.Constants.JSON_ERROR;
import static com.google.android.gcm.server.Constants.JSON_FAILURE;
import static com.google.android.gcm.server.Constants.JSON_MESSAGE_ID;
import static com.google.android.gcm.server.Constants.JSON_MULTICAST_ID;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_BADGE;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_BODY;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_BODY_LOC_ARGS;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_BODY_LOC_KEY;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_CLICK_ACTION;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_COLOR;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_ICON;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_SOUND;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_TAG;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_TITLE;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_TITLE_LOC_ARGS;
import static com.google.android.gcm.server.Constants.JSON_NOTIFICATION_TITLE_LOC_KEY;
import static com.google.android.gcm.server.Constants.JSON_PAYLOAD;
import static com.google.android.gcm.server.Constants.JSON_REGISTRATION_IDS;
import static com.google.android.gcm.server.Constants.JSON_TO;
import static com.google.android.gcm.server.Constants.JSON_RESULTS;
import static com.google.android.gcm.server.Constants.JSON_SUCCESS;
import static com.google.android.gcm.server.Constants.PARAM_COLLAPSE_KEY;
import static com.google.android.gcm.server.Constants.PARAM_DELAY_WHILE_IDLE;
import static com.google.android.gcm.server.Constants.PARAM_DRY_RUN;
import static com.google.android.gcm.server.Constants.PARAM_PRIORITY;
import static com.google.android.gcm.server.Constants.PARAM_RESTRICTED_PACKAGE_NAME;
import static com.google.android.gcm.server.Constants.PARAM_TIME_TO_LIVE;
import static com.google.android.gcm.server.Constants.TOKEN_CANONICAL_REG_ID;
import static com.google.android.gcm.server.Constants.TOPIC_PREFIX;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Helper class to send messages to the GCM service using an API Key.
*/
public class Sender {
protected static final String UTF8 = "UTF-8";
/**
* Initial delay before first retry, without jitter.
*/
protected static final int BACKOFF_INITIAL_DELAY = 1000;
/**
* Maximum delay before a retry.
*/
protected static final int MAX_BACKOFF_DELAY = 1024000;
protected final Random random = new Random();
protected static final Logger logger =
Logger.getLogger(Sender.class.getName());
private final String key;
/**
* Default constructor.
*
* @param key API key obtained through the Google API Console.
*/
public Sender(String key) {
this.key = nonNull(key);
}
/**
* Sends a message to one device, retrying in case of unavailability.
*
*
* Note: this method uses exponential back-off to retry in
* case of service unavailability and hence could block the calling thread
* for many seconds.
*
* @param message message to be sent, including the device's registration id.
* @param to registration token, notification key, or topic where the message will be sent.
* @param retries number of retries in case of service unavailability errors.
*
* @return result of the request (see its javadoc for more details).
*
* @throws IllegalArgumentException if to is {@literal null}.
* @throws InvalidRequestException if GCM didn't returned a 200 or 5xx status.
* @throws IOException if message could not be sent.
*/
public Result send(Message message, String to, int retries)
throws IOException {
int attempt = 0;
Result result;
int backoff = BACKOFF_INITIAL_DELAY;
boolean tryAgain;
do {
attempt++;
if (logger.isLoggable(Level.FINE)) {
logger.fine("Attempt #" + attempt + " to send message " +
message + " to regIds " + to);
}
result = sendNoRetry(message, to);
tryAgain = result == null && attempt <= retries;
if (tryAgain) {
int sleepTime = backoff / 2 + random.nextInt(backoff);
sleep(sleepTime);
if (2 * backoff < MAX_BACKOFF_DELAY) {
backoff *= 2;
}
}
} while (tryAgain);
if (result == null) {
throw new IOException("Could not send message after " + attempt +
" attempts");
}
return result;
}
/**
* Sends a message without retrying in case of service unavailability. See
* {@link #send(Message, String, int)} for more info.
*
* @return result of the post, or {@literal null} if the GCM service was
* unavailable or any network exception caused the request to fail,
* or if the response contains more than one result.
*
* @throws InvalidRequestException if GCM didn't returned a 200 status.
* @throws IllegalArgumentException if to is {@literal null}.
*/
public Result sendNoRetry(Message message, String to) throws IOException {
nonNull(to);
Map