All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avos.avoscloud.AVPush Maven / Gradle / Ivy

There is a newer version: 0.2.1
Show newest version
package com.avos.avoscloud;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.json.JSONObject;

import com.alibaba.fastjson.JSON;
import com.avos.avoscloud.internal.InternalConfigurationController;

/**
 * 

* The AVPush is a local representation of data that can be sent as a push notification. *

*

* The typical workflow for sending a push notification from the client is to construct a new * AVPush, use the setter functions to fill it with data, and then use AVPush.sendInBackground() to * send it. *

*/ public class AVPush { private static final String INSTALLATIONTAG = "_Installation"; private static final String deviceTypeTag = "deviceType"; private static final Set DEVICE_TYPES = new HashSet(); static { DEVICE_TYPES.add("android"); DEVICE_TYPES.add("ios"); } private final Set channelSet; private com.avos.avoscloud.AVQuery pushQuery; private String cql; private long expirationTime; private long expirationTimeInterval; private final Set pushTarget; private final Map pushData; private volatile AVObject notification; private Date pushDate = null; private boolean production = true; static { AVPowerfulUtils.createSettings(AVPush.class.getSimpleName(), "push", ""); } /** * Creates a new push notification. The default channel is the empty string, also known as the * global broadcast channel, but this value can be overridden using AVPush.setChannel(String), * AVPush.setChannels(Collection) or AVPush.setQuery(AVQuery). Before sending the push * notification you must call either AVPush.setMessage(String) or AVPush.setData(JSONObject). */ public AVPush() { channelSet = new HashSet(); pushData = new HashMap(); pushTarget = new HashSet(DEVICE_TYPES); pushQuery = new AVQuery(INSTALLATIONTAG); } public Set getChannelSet() { return channelSet; } /** * 返回推送后创建的_Notification对象。 * * @return _Notification对象 */ public AVObject getNotification() { return notification; } public AVQuery getPushQuery() { return pushQuery; } public Date getPushDate() { return pushDate; } public long getExpirationTime() { return expirationTime; } public long getExpirationTimeInterval() { return expirationTimeInterval; } public Set getPushTarget() { return pushTarget; } public Map getPushData() { return pushData; } /** * Clears both expiration values, indicating that the notification should never expire. */ public void clearExpiration() { expirationTime = 0L; expirationTimeInterval = 0L; } /** * Sends this push notification while blocking this thread until the push notification has * successfully reached the AVOSCloud servers. Typically, you should use AVPush.sendInBackground() * instead of this, unless you are managing your own threading. */ public void send() { sendInBackground(true, null); } /** * A helper method to concisely send a push to a query. This method is equivalent to * *
   * AVPush push = new AVPush();
   * push.setData(data);
   * push.setQuery(query);
   * push.sendInBackground();
   * 
* * @param data The entire data of the push message. See the push guide for more details on the * data format. * @param query A AVInstallation query which specifies the recipients of a push. * @throws AVException if query is not valid */ static void sendDataInBackground(JSONObject data, AVQuery query) throws AVException { if (!query.getClassName().equals(INSTALLATIONTAG)) { throw new AVException(AVException.OTHER_CAUSE, "only installation query is valid"); } AVPush push = new AVPush(); push.setData(data); push.setQuery(query); push.sendInBackground(); } /** * A helper method to concisely send a push to a query. This method is equivalent to * *
   * AVPush push = new AVPush();
   * push.setData(data);
   * push.setQuery(query);
   * push.sendInBackground(callback);
   * 
* * @param data The entire data of the push message. See the push guide for more details on the * data format. * @param query A AVInstallation query which specifies the recipients of a push. * @param callback callback.done(e) is called when the send completes. */ public static void sendDataInBackground(JSONObject data, AVQuery query, SendCallback callback) { if (!query.getClassName().equals(INSTALLATIONTAG)) { if (callback != null) { callback.done(new AVException(AVException.OTHER_CAUSE, "only installation query is valid")); } } AVPush push = new AVPush(); push.setData(data); push.setQuery(query); push.sendInBackground(false, callback); } /** * Sends this push notification in a background thread. This is preferable to using send(), unless * your code is already running from a background thread. */ public void sendInBackground() { sendInBackground(false, null); } /** * Sends this push notification in a background thread. This is preferable to using send(), unless * your code is already running from a background thread. * * @param callback callback.done(e) is called when the send completes. */ public void sendInBackground(SendCallback callback) { sendInBackground(false, callback); } private Map pushChannelsData() { return AVUtils.createStringObjectMap("channels", channelSet); } private Map postDataMap() throws AVException { Map map = new HashMap(); if (pushQuery != null) { if (pushTarget.size() == 0) { pushQuery.whereNotContainedIn(deviceTypeTag, DEVICE_TYPES); } else if (pushTarget.size() == 1) { pushQuery.whereEqualTo(deviceTypeTag, pushTarget.toArray()[0]); } Map pushParameters = pushQuery.assembleParameters(); if (pushParameters.keySet().size() > 0 && !AVUtils.isBlankString(cql)) { throw new IllegalStateException("You can't use AVQuery and Cloud query at the same time."); } for (String k : pushParameters.keySet()) { map.put(k, JSON.parse(pushParameters.get(k))); } } if (!AVUtils.isBlankString(cql)) { map.put("cql", cql); } if (channelSet.size() > 0) { map.putAll(pushChannelsData()); } if (this.expirationTime > 0) { map.put("expiration_time", this.expirationDateTime()); } if (this.expirationTimeInterval > 0) { map.put("push_time", AVUtils.stringFromDate(new Date())); map.put("expiration_interval", new Long(this.expirationTimeInterval)); } if (this.pushDate != null) { map.put("push_time", AVUtils.stringFromDate(pushDate)); } if (!production) { map.put("prod", "dev"); } map.putAll(pushData); return map; } /** * Sends this push notification in a background thread. This is preferable to using send(), unless * your code is already running from a background thread. * * @param callback callback.done(e) is called when the send completes. */ private void sendInBackground(boolean sync, SendCallback callback) { final SendCallback internalCallback = callback; String path = "push"; try { Map map = postDataMap(); String jsonString = AVUtils.jsonStringFromMapWithNull(map); PaasClient.storageInstance().postObject(path, jsonString, sync, new GenericObjectCallback() { @Override public void onSuccess(String content, AVException e) { notification = new AVObject("_Notification"); AVUtils.copyPropertiesFromJsonStringToAVObject(content, notification); if (internalCallback != null) { internalCallback.internalDone(null); } } @Override public void onFailure(Throwable error, String content) { if (internalCallback != null) { internalCallback.internalDone(AVErrorUtils.createException(error, content)); } } }); } catch (AVException e) { if (callback != null) { callback.internalDone(e); } else { LogUtil.log.e("AVPush sent exception", e); } } } /** * A helper method to concisely send a push message to a query. This method is equivalent to * *
   * AVPush push = new AVPush();
   * push.setMessage(message);
   * push.setQuery(query);
   * push.sendInBackground();
   * 
* * @param message The message that will be shown in the notification. * @param query A AVInstallation query which specifies the recipients of a push. */ public static void sendMessageInBackground(String message, AVQuery query) { if (!query.getClassName().equals(INSTALLATIONTAG)) { InternalConfigurationController.globalInstance().getInternalLogger() .e(AVPush.class.getSimpleName(), "only installation query is valid"); return; } AVPush push = new AVPush(); push.setMessage(message); push.setQuery(query); push.sendInBackground(false, null); } /** * A helper method to concisely send a push message to a query. This method is equivalent to * *
   * AVPush push = new AVPush();
   * push.setMessage(message);
   * push.setQuery(query);
   * push.sendInBackground(callback);
   * 
* * @param message The message that will be shown in the notification. * @param query A AVInstallation query which specifies the recipients of a push. * @param callback callback.done(e) is called when the send completes. */ public static void sendMessageInBackground(String message, AVQuery query, SendCallback callback) { if (!query.getClassName().equals(INSTALLATIONTAG)) { if (callback != null) { callback.done(new AVException(AVException.OTHER_CAUSE, "only installation query is valid")); } } AVPush push = new AVPush(); push.setMessage(message); push.setQuery(query); push.sendInBackground(false, callback); } /** * Sets the channel on which this push notification will be sent. The channel name must start with * a letter and contain only letters, numbers, dashes, and underscores. A push can either have * channels or a query. Setting this will unset the query. * * @param channel set push channel */ public void setChannel(String channel) { channelSet.clear(); channelSet.add(channel); } /** * Sets the collection of channels on which this push notification will be sent. Each channel name * must start with a letter and contain only letters, numbers, dashes, and underscores. A push can * either have channels or a query. Setting this will unset the query. * * @param channels set push channels */ public void setChannels(Collection channels) { channelSet.clear(); channelSet.addAll(channels); } /** * Sets the entire data of the push message. See the push guide for more details on the data * format. This will overwrite any data specified in AVPush.setMessage(String). * * @param data push data */ public void setData(Map data) { this.pushData.put("data", data); } /** * Sets the entire data of the push message. See the push guide for more details on the data * format. This will overwrite any data specified in AVPush.setMessage(String). * * @param data push data */ public void setData(JSONObject data) { try { Map map = new HashMap(); Iterator iter = data.keys(); while (iter.hasNext()) { String key = (String) iter.next(); Object value = data.get(key); map.put(key, value); } this.pushData.put("data", map); } catch (Exception exception) { throw new AVRuntimeException(exception); } } private Date expirationDateTime() { return new Date(expirationTime); } /** * Set the push date at which the push will be sent. * * @param date The push date. */ public void setPushDate(Date date) { this.pushDate = date; } /** * Sets a UNIX epoch timestamp at which this notification should expire, in seconds (UTC). This * notification will be sent to devices which are either online at the time the notification is * sent, or which come online before the expiration time is reached. Because device clocks are not * guaranteed to be accurate, most applications should instead use * AVPush.setExpirationTimeInterval(long). * * @param time expire date */ public void setExpirationTime(long time) { this.expirationTime = time; } /** * Sets the time interval after which this notification should expire, in seconds. This * notification will be sent to devices which are either online at the time the notification is * sent, or which come online within the given number of seconds of the notification being * received by AVOSCloud's server. An interval which is less than or equal to zero indicates that * the message should only be sent to devices which are currently online. * * @param timeInterval expirationTimeInterval */ public void setExpirationTimeInterval(long timeInterval) { this.expirationTimeInterval = timeInterval; } /** * Sets the message that will be shown in the notification. This will overwrite any data specified * in AVPush.setData(JSONObject). * * @param message set push message */ public void setMessage(String message) { pushData.clear(); Map map = AVUtils.createStringObjectMap("alert", message); pushData.put("data", map); } public void setPushToAndroid(boolean pushToAndroid) { if (pushToAndroid) { this.pushTarget.add("android"); } else { this.pushTarget.remove("android"); } } public void setPushToIOS(boolean pushToIOS) { if (pushToIOS) { this.pushTarget.add("ios"); } else { this.pushTarget.remove("ios"); } } public void setPushToWindowsPhone(boolean pushToWP) { if (pushToWP) { this.pushTarget.add("wp"); } else { this.pushTarget.remove("wp"); } } /** * Sets the query for this push for which this push notification will be sent. This query will be * executed in the AVOSCloud cloud; this push notification will be sent to Installations which * this query yields. A push can either have channels or a query. Setting this will unset the * channels. * * @param query A query to which this push should target. This must be a AVInstallation query. */ public void setQuery(AVQuery query) { this.pushQuery = query; } /** * 可以通过 cql来针对push进行筛选 * * 请注意cql 的主体应该是_Installation表 * * 请在设置cql的同时,不要设置pushTarget(ios,android,wp) * * @param cql cql for push * @since 2.6.7 */ public void setCloudQuery(String cql) { this.cql = cql; } public boolean getProductionMode() { return this.production; } /** * 设定iOS推送是否是生产环境 * * * @since 2.6.9 * @param production,true为生产环境,默认是true */ public void setProductionMode(boolean production) { this.production = production; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy