be.mjosoft.ios.apn.APNService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of MjoSoft-APNService Show documentation
Show all versions of MjoSoft-APNService Show documentation
Java library for easy integration into the Apple Push Notification Service in a Java application.
package be.mjosoft.ios.apn;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
/**
* This class is used to send message to the Apple Push Notification Service.
* @author mj
*/
public class APNService
{
protected static String host = "gateway.push.apple.com";
protected static int port = 2195;
protected static String hostDevel = "gateway.sandbox.push.apple.com";
protected static int portDevel = 2195;
protected boolean develMode;
protected SSLSocketFactory sslSocketFactory;
protected Socket socket;
/**
* Constructor.
* Switches into production mode.
*/
public APNService()
{
this(false);
}
/**
* Constructor.
* @param develMode true switches into development mode, false switches into production mode.
*/
public APNService(boolean develMode)
{
this.develMode = develMode;
}
/**
* Initialises the permanent connection with the Apple Push Notification Service.
* @param certificateFile the certificate file.
* @param certificatePWD the certificate password.
* @param certificateType the certificate type.
* @throws APNException if an error occured.
*/
public void initConnexion(String certificateFile, String certificatePWD, String certificateType) throws APNException
{
try{
initConnexion(new FileInputStream(certificateFile), certificatePWD, certificateType);
}catch(FileNotFoundException ex){
throw new APNException(ex);
}
}
/**
* Initialises the permanent connection with the Apple Push Notification Service.
* @param certificateFile the certificate file.
* @param certificatePWD the certificate password.
* @param certificateType the certificate type.
* @throws APNException if an error occured.
*/
public void initConnexion(File certificateFile, String certificatePWD, String certificateType) throws APNException
{
try{
initConnexion(new FileInputStream(certificateFile), certificatePWD, certificateType);
}catch(FileNotFoundException ex){
throw new APNException(ex);
}
}
/**
* Initialises the permanent connection with the Apple Push Notification Service.
* @param certificateStream the certificate file stream.
* @param certificatePWD the certificate password.
* @param certificateType the certificate type.
* @throws APNException if an error occured.
*/
public void initConnexion(InputStream certificateStream, String certificatePWD, String certificateType) throws APNException
{
try
{
KeyStore keyStore = KeyStore.getInstance(certificateType);
keyStore.load(certificateStream, certificatePWD.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("sunx509");
keyManagerFactory.init(keyStore, certificatePWD.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("sunx509");
trustManagerFactory.init(keyStore);
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(keyManagerFactory.getKeyManagers(), null, null);
sslSocketFactory = sslCtx.getSocketFactory();
connect();
}
catch(Exception ex)
{
throw new APNException(ex);
}
}
/**
* Connects to the Apple Push Notification Service.
* @throws APNException if an error occured.
*/
protected void connect() throws APNException
{
try
{
if(develMode){
socket = (SSLSocket)sslSocketFactory.createSocket(hostDevel, portDevel);
}else{
socket = (SSLSocket)sslSocketFactory.createSocket(host, port);
}
}
catch(IOException ex)
{
throw new APNException(ex);
}
}
/**
* Ends the connection to the Apple Push Notification Service.
*/
public void endConnection()
{
try{
socket.close();
}catch(Exception ex){}
}
/**
* Sends a message to a device.
* @param deviceToken the token of the device to send the message.
* @param message the message to send.
* @throws APNException if an error occured.
*/
public void sendAPN(String deviceToken, APNMessage message) throws APNException
{
deviceToken = deviceToken == null ? "" : deviceToken.replaceAll(" ", "").replaceAll("<", "").replaceAll(">", "");
byte binary[] = createBinary(deviceToken, message);
int nbTry = 3;
while(nbTry > 0)
{
try
{
OutputStream out = socket.getOutputStream();
out.write(binary, 0, binary.length);
out.flush();
break;
}
catch(Exception ex)
{
nbTry--;
endConnection();
try{
connect();
}catch(Exception exx){}
}
}
if(nbTry == 0){
// Failed.
throw new APNException("The message cannot be send!");
}
}
/**
* Create the binary message to send to the Apple Push Notification Service.
* @param deviceToken the token of the device to which send the message.
* @param message the message to send.
* @return the binary representation of the message to send.
*/
protected byte[] createBinary(String deviceToken, APNMessage message)
{
// Prepare the token part.
deviceToken = deviceToken.toUpperCase();
byte deviceTokenBinary[] = new byte[deviceToken.length() / 2];
for(int i = 0, k = 0; i < deviceToken.length(); i += 2)
{
String byteS = deviceToken.substring(i, i + 2);
int byteInt = Integer.parseInt(byteS, 16);
deviceTokenBinary[k++] = (byte)byteInt;
}
byte[] messageBytes = null;
try{
messageBytes = message.toString().getBytes("UTF-8");
}catch(Exception ex){
ex.printStackTrace();
}
// Writes the bytes.
int nbBytes = 3 + deviceTokenBinary.length + 2 + messageBytes.length;
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(nbBytes);
// Command (one byte)
bytesOut.write((byte)0);
// Token length (2 bytes) (big endian)
bytesOut.write((byte)(deviceTokenBinary.length & 0xff00) >> 8);
bytesOut.write((byte)(deviceTokenBinary.length & 0xff));
// Token (32 bytes)
try{
bytesOut.write(deviceTokenBinary);
}catch(Exception ex){
ex.printStackTrace();
}
// Payload length (2 bytes) (bid endian)
bytesOut.write((byte)(messageBytes.length & 0xff00) >> 8);
bytesOut.write((byte)(messageBytes.length & 0xff));
// Payload (message)
try{
bytesOut.write(messageBytes);
}catch(Exception ex){
ex.printStackTrace();
}
return bytesOut.toByteArray();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy