android - GCM MultiCastResult Approach -
this approach use gcm more 1000 devices. right way? cannot try unless have more 1000 users feedback appreciated , importantly checking errors correctly? , updating database in right way?
public class messagingendpoint { private static final logger log = logger.getlogger(messagingendpoint.class.getname()); /** * api keys can obtained google cloud console */ private static final string api_key = system.getproperty("gcm.api.key"); private list<registrationrecord> records; private list<string> getregistrationid() { records = ofy().load().type(registrationrecord.class).list(); list<string> records_id = new arraylist<string>(); (int = 0; < records.size(); i++) { records_id.add(records.get(i).getregid()); } return records_id; } private list<list<string>> regidinthousands(list<string> list, final int l) { list<list<string>> parts = new arraylist<list<string>>(); final int n = list.size(); (int = 0; < n; += l) { parts.add(new arraylist<string>(list.sublist(i, math.min(n, + l)))); } return parts; } * * @param message message send */ public void sendmessage(@named("message") string message) throws ioexception { if (message == null || message.trim().length() == 0) { log.warning("not sending message because empty"); return; } // crop longer messages if (message.length() > 1000) { message = message.substring(0, 1000) + "[...]"; } sender sender = new sender(api_key); message msg = new message.builder().adddata("message", message).build(); list<list<string>> regidsparts = regidinthousands(getregistrationid(), 1000); (int = 0; < regidsparts.size(); i++) { multicastresult multicastresult = sender.send(msg, regidsparts.get(i), 5); if (multicastresult.getcanonicalids() != 0) { list<result> results = multicastresult.getresults(); (int j = 0; j < results.size(); j++) { if (results.get(j).getmessageid() != null) { log.info("message sent " + regidsparts.get(i).get(j)); string canonicalregid = results.get(j).getcanonicalregistrationid(); if (canonicalregid != null) { // if regid changed, have update datastore log.info("registration id changed " + regidsparts.get(i).get(j) + " updating " + canonicalregid); regidsparts.get(i).set(j, canonicalregid); ofy().save().entity(records.get((i*1000)+j)).now(); } else { string error = results.get(j).geterrorcodename(); if (error.equals(constants.error_not_registered)) { log.warning("registration id " + regidsparts.get(i).get(j) + " no longer registered gcm, removing datastore"); // if device no longer registered gcm, remove datastore ofy().delete().entity(records.get((i*1000)+j)).now(); } else { log.warning("error when sending message : " + error); } } } } } } } }
your code looks good, thing can notice quite verbose , complicated. can take @ 1 option if considerate error handling:
public void sendmessagetomultipledevices(string key, string value, arraylist devices) {
sender sender = new sender(myapikey); message message = new message.builder().adddata(key, value).build(); try { multicastresult result = sender.send(message, devices, 5); mtlog.info(tag, "result " + result.tostring()); (int = 0; < result.gettotal(); i++) { result r = result.getresults().get(i); if (r.getmessageid() != null) { string canonicalregid = r.getcanonicalregistrationid(); if (canonicalregid != null) { // devices.get(i) has more on registration id: update database } } else { string error = r.geterrorcodename(); if (error.equals(constants.error_not_registered)) { // application has been removed devices.get(i) - unregister database } } } } catch (ioexception ex) { mtlog.err(tag, "sending message failed", ex); } }
Comments
Post a Comment