В течение нескольких последних недель я работал техническим архитектором в мобильном приложении для крупного банка (или, я бы сказал, в отделе страхования этого банка). Приложение было написано в PhoneGap и Sencha Touch. Поддерживались две платформы: iOS и Android. Я отвечал (помимо всего прочего) за разработку уведомлений для iOS и Android. Уведомление просто сообщило страховому агенту, сколько случаев и действий было обновлено / изменено.
Отправка уведомлений на устройства iOS
Чтобы использовать Apple Push Notification Service (APNS), помимо стандартного сертификата разработчика и действительного профиля обеспечения, вам нужна еще одна вещь. Вам необходим сертификат APNS, который используется для взаимной авторизации. Вы можете сгенерировать его на портале Apple для обеспечения iOS. Как только он у вас есть, вы готовы отправлять уведомления.
APNS использует двоичный протокол. Конечно, вам не нужно реализовывать это с нуля. Вы можете использовать очень хорошую и тщательно протестированную библиотеку notnoop java-apns, которая доступна здесь: https://github.com/notnoop/java-apns .
Использовать его чрезвычайно просто, следующий код работает нормально ( Notificationэто мой внутренний класс):
@Service
@Qualifier("Apns")
public class ApnsPushNotificationServiceImpl implements PushNotificationService {
private Resource certResource;
private String certPassword;
private boolean useProductionServer;
private String serverAddress;
private static final int DEFAULT_APNS_PORT = 2195;
public void setCertResource(Resource certResource) {
this.certResource = certResource;
}
public void setCertPassword(String certPassword) {
this.certPassword = certPassword;
}
public void setUseProductionServer(boolean useProductionServer) {
this.useProductionServer = useProductionServer;
}
public void setServerAddress(String serverAddress) {
this.serverAddress = serverAddress;
}
public void pushNotification(Notification notification) {
List<Notification> notList = new ArrayList<Notification>();
notList.add(notification);
pushNotifications(notList);
}
public void pushNotifications(List<Notification> notifications) {
ApnsService service = createApnsService();
service.start();
for (Notification notification : notifications) {
doSendNotification(notification, service);
}
service.stop();
}
private ApnsService createApnsService() {
ApnsService service = null;
ApnsServiceBuilder serviceBuilder = APNS.newService()
.withCert(certResource.getInputStream(), certPassword);
if (null != serverAddress && serverAddress.length() > 0) {
serviceBuilder.withGatewayDestination(serverAddress,
DEFAULT_APNS_PORT);
} else if (useProductionServer) {
serviceBuilder.withProductionDestination();
} else {
serviceBuilder.withSandboxDestination();
}
service = serviceBuilder.build();
return service;
}
private void doSendNotification(Notification notification,
ApnsService service) {
PayloadBuilder payloadBuilder = APNS.newPayload();
payloadBuilder = payloadBuilder.badge(notification.getBadge());
payloadBuilder = payloadBuilder.sound(notification.getSound());
if (notification.getBody() != null) {
payloadBuilder = payloadBuilder.alertBody(notification.getBody());
}
String payload = payloadBuilder.build();
service.push(notification.getDeviceToken(), payload);
}
Отправка уведомлений на устройства Android
По сравнению с уведомлениями iOS реализация обмена сообщениями устройств Android Cloud 2 (AC2DM) была простой задачей. Мне не нужна третья библиотека. Благодаря простым и понятным сервисам Google RESTful я смог написать код, отвечающий за передачу уведомлений на устройства Android менее чем за час.
Весь процесс состоит из 2 этапов. Первый — аутентификация, второй — фактическое нажатие уведомления. Исходный код выглядит следующим образом:
@Service
@Qualifier("Ac2dm")
public class Ac2dmPushNotificationServiceImpl implements PushNotificationService {
private String sendingRoleAccount;
private String sendingRolePassword;
public void pushNotification(Notification notification) {
List<Notification> notList = new ArrayList<Notification<();
notList.add(notification);
pushNotifications(notList);
}
public void pushNotifications(List<Notification> notifications) {
try {
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(
"https://www.google.com/accounts/ClientLogin");
method.addParameter("Email", sendingRoleAccount);
method.addParameter("Passwd", sendingRolePassword);
method.addParameter("accountType", "HOSTED_OR_GOOGLE");
method.addParameter("source", "unit-test");
method.addParameter("service", "ac2dm");
client.executeMethod(method);
byte[] responseBody = method.getResponseBody();
String response = new String(responseBody);
String auth = response.split("\n")[2];
String token = auth.split("=")[1];
for (Notification notification : notifications) {
doSendNotification(notification, token, client);
}
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private void doSendNotification(Notification notification, String token, HttpClient client) throws HttpException, IOException {
PostMethod method = new PostMethod("https://android.apis.google.com/c2dm/send");
method.addParameter("registration_id", notification.getDeviceToken());
method.addParameter("collapse_key", "collapse");
method.addParameter("data.payload", notification.getBadge().toString());
Header header = new Header("Authorization", "GoogleLogin auth="+token);
method.addRequestHeader(header);
client.executeMethod(method);
byte[] responseBody = method.getResponseBody();
String response = new String(responseBody);
}
public void setSendingRoleAccount(String sendingRoleAccount) {
this.sendingRoleAccount = sendingRoleAccount;
}
public void setSendingRolePassword(String sendingRolePassword) {
this.sendingRolePassword = sendingRolePassword;
}
Замечание по WebSphere и IBM Java 5
Когда приложение было развернуто на сервере UAT, и мы попытались запустить интеграционный тест, отвечающий за отправку уведомлений на один из наших тестовых iPhone, мы увидели сообщение «java.security.InvalidKeyException: Illegal key size» в журнал. После многих часов исследований выяснилось, что IBM Java 5 поддерживает только 512 размеров ключей. Нам пришлось обновить jav-файлы безопасности Java 5 IBM, чтобы он читал сертификат APNS.
-1 для IBM!
Резюме
Это заняло у меня некоторое время, но когда вы видите уведомления, приходящие на ваше устройство, а затем с помощью PhoneGap вы запускаете приложение JavaScript, которое выглядит как нативное приложение, и вы чувствуете себя хорошо ?
ура,
Лукаш