be.mjosoft.ios.apn.APNFeedBackService 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.
The newest version!
package be.mjosoft.ios.apn;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
* This class is used to access the Apple Push Notification Feedback Service.
* @author mj
*/
public class APNFeedBackService
{
protected static String host = "feedback.push.apple.com";
protected static int port = 2196;
protected static String hostDevel = "feedback.sandbox.push.apple.com";
protected static int portDevel = 2196;
protected boolean develMode;
protected SSLSocketFactory sslSocketFactory;
protected SSLSocket socket;
/**
* Constructor.
* Switches into production mode.
*/
public APNFeedBackService()
{
this(false);
}
/**
* Constructor.
* @param develMode true switches into development mode, false switches into production mode.
*/
public APNFeedBackService(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 certificateURL the certificate url.
* @param certificatePWD the certificate password.
* @param certificateType the certificate type.
* @throws APNException if an error occured.
*/
public void initConnexion(URL certificateURL, String certificatePWD, String certificateType) throws APNException
{
try{
URLConnection con = certificateURL.openConnection();
initConnexion(con.getInputStream(), certificatePWD, certificateType);
}catch(IOException 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");
TrustManager tms = new X509TrustManager()
{
public X509Certificate[] getAcceptedIssuers(){
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType){
}
public void checkServerTrusted(X509Certificate[] certs, String authType){
}
};
sslCtx.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{tms}, null);
sslSocketFactory = sslCtx.getSocketFactory();
connect();
}
catch(Exception ex)
{
throw new APNException(ex);
}
}
/**
* Connects to the Appel 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){}
}
/**
* Retreives the list of obsolete devices.
* That means the devices that not contains the App anymore.
* @return the list of obsolete devices.
* @throws APNException if an error occured.
*/
public List retreiveObsoleteDevices() throws APNException
{
List devices = new ArrayList();
byte binary[] = new byte[38];
int nbTry = 3;
while(nbTry > 0)
{
try
{
InputStream in = socket.getInputStream();
int pos = in.read(binary, 0, 38);
while(pos >= 38)
{
devices.add(process(binary));
pos = in.read(binary, 0, 38);
}
break;
}
catch(Exception ex)
{
nbTry--;
endConnection();
try{
connect();
}catch(Exception exx){}
}
}
if(nbTry == 0){
// Failed.
throw new APNException("The service cannot be reached!");
}
return devices;
}
/**
* Parse the binary message containing information about an obsolete device.
* @param binary the message containing the information.
* @return an ObsoleteDevice object containing information about an obsolete device.
*/
protected ObsoleteDevice process(byte[] binary)
{
ObsoleteDevice device = new ObsoleteDevice();
// Timestamp (4 bytes)
long timestamp = binary[3];
long tmp = (binary[2] << 8);
timestamp += tmp & 0xFF00;
tmp = (binary[1] << 16);
timestamp += tmp & 0xFF0000;
tmp = (binary[0] << 24);
timestamp += tmp & 0xFF000000;
timestamp *= 1000;
Calendar date = new GregorianCalendar();
date.setTimeInMillis(timestamp);
device.setTimestamp(date);
// Token length
int tokenLength = binary[5];
tokenLength += (binary[4] << 8) & 0xFF00;
// Token
StringBuilder token = new StringBuilder();
for(int i = 0, k = 0; i < tokenLength; i++)
{
byte b = binary[6 + i];
int bi = b & 0x00FF;
String byteS = Integer.toHexString(bi);
if(byteS.length() < 2){
byteS = "0" + byteS;
}
token.append(byteS);
}
device.setToken(token.toString());
return device;
}
/**
* Represents a device that is no more active for the current AppId.
*/
public static class ObsoleteDevice
{
protected String token;
protected Calendar timestamp;
/**
* Returns the token of the device.
* @return the token of the device.
*/
public String getToken()
{
return token;
}
/**
* Initialises the token of the device.
* @param token the token of the device.
*/
public void setToken(String token)
{
this.token = token;
}
/**
* Returns the timestamp that device was removed.
* @return the timestamp that device was removed.
*/
public Calendar getTimestamp()
{
return timestamp;
}
/**
* Initialises the timestamp that device was removed.
* @param timestamp the timestamp that device was removed.
*/
public void setTimestamp(Calendar timestamp)
{
this.timestamp = timestamp;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy