package eu.hgross.blaubot.android; import android.bluetooth.BluetoothAdapter; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.net.wifi.p2p.WifiP2pManager; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import eu.hgross.blaubot.android.bluetooth.BlaubotBluetoothAdapter; import eu.hgross.blaubot.android.bluetooth.BlaubotBluetoothBeacon; import eu.hgross.blaubot.android.geo.GeoLocationBeaconAndroid; import eu.hgross.blaubot.android.nfc.BlaubotNFCBeacon; import eu.hgross.blaubot.android.wifi.BlaubotWifiAdapter; import eu.hgross.blaubot.android.wifip2p.BlaubotWifiP2PBeacon; import eu.hgross.blaubot.core.Blaubot; import eu.hgross.blaubot.core.BlaubotDevice; import eu.hgross.blaubot.core.BlaubotUUIDSet; import eu.hgross.blaubot.core.IBlaubotAdapter; import eu.hgross.blaubot.core.IBlaubotDevice; import eu.hgross.blaubot.core.acceptor.ConnectionMetaDataDTO; import eu.hgross.blaubot.core.acceptor.discovery.BlaubotBeaconStore; import eu.hgross.blaubot.core.acceptor.discovery.IBlaubotBeacon; import eu.hgross.blaubot.core.connector.IBlaubotConnector; import eu.hgross.blaubot.ethernet.BlaubotBonjourBeacon; import eu.hgross.blaubot.ethernet.BlaubotEthernetAdapter; import eu.hgross.blaubot.ethernet.BlaubotEthernetMulticastBeacon; import eu.hgross.blaubot.geobeacon.GeoBeaconConstants; import eu.hgross.blaubot.geobeacon.GeoLocationBeacon; /** * Factory to create {@link Blaubot} instances for Android. * * @author Henning Gross {@literal (mail.to@henning-gross.de)} */ public class BlaubotAndroidFactory extends eu.hgross.blaubot.core.BlaubotFactory { /** * Creates an android specific GeoLocationBeacon using WebSockets. * This will utilize Android's geolocation service for geo data. * If you want to provide the geo data yourself, see {@link BlaubotAndroidFactory#createWebSocketGeoLocationBeacon(IBlaubotDevice, String, int)}. * In order to use this beacon, you have to host a {@link eu.hgross.blaubot.geobeacon.GeoBeaconServer}. * Note that you have to put blaubot-websockets as a dependency to your project. * * @param ownDevice the ownDevice (Blaubot-Instance device) * @param beaconServerHost the hostname or ip of the beacon server * @param beaconServerPort the port on which the beacon server listens * @return the geolocation beacon for android * @throws ClassNotFoundException if blaubot-websockets is not in the classpath */ public static GeoLocationBeaconAndroid createWebSocketGeoLocationBeaconForAndroid(IBlaubotDevice ownDevice, String beaconServerHost, int beaconServerPort) throws ClassNotFoundException { IBlaubotConnector connector = createBlaubotWebsocketAdapter(ownDevice, beaconServerHost, beaconServerPort).getConnector(); // hacky ... ConnectionMetaDataDTO webSocketMetaDataDTO = createWebSocketMetaDataDTO(beaconServerHost, "/blaubot", beaconServerPort); BlaubotBeaconStore beaconStore = new BlaubotBeaconStore(); beaconStore.putConnectionMetaData(GeoBeaconConstants.GEO_BEACON_SERVER_UNIQUE_DEVICE_ID, webSocketMetaDataDTO); GeoLocationBeaconAndroid geoLocationBeacon = new GeoLocationBeaconAndroid(beaconStore, connector); return geoLocationBeacon; } /** * Creates a blaubot instance using ethernet adapter and the NFC beacon. * * Note that you have to call some lifecycle methods onResume and onPause. * See BlaubotAndroid. * * @param appUUID the app's uuid * @param acceptorPort the port of the connector's accepting socket * @param ownInetAddress the own {@link InetAddress} of the network to act on * @return the blaubot instance */ public static BlaubotAndroid createEthernetBlaubotWithNFCBeacon(UUID appUUID, int acceptorPort, InetAddress ownInetAddress) { if (ownInetAddress == null || appUUID == null) throw new NullPointerException(); IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotEthernetAdapter ethernetAdapter = new BlaubotEthernetAdapter(ownDevice, acceptorPort, ownInetAddress); BlaubotNFCBeacon nfcBeacon = new BlaubotNFCBeacon(); return (BlaubotAndroid) createBlaubot(appUUID, ownDevice, ethernetAdapter, nfcBeacon); } /** * Creates a blaubot instance using the bluetooth beacon and sockets to communicate. * Note: requires broadcast capable network * * @param appUUID the app's uuid * @param acceptorPort the port of the connector's accepting socket * @param ownInetAddress the own {@link InetAddress} of the network to act on * @return the blaubot instance */ public static BlaubotAndroid createEthernetBlaubotWithBluetoothBeacon(UUID appUUID, int acceptorPort, InetAddress ownInetAddress) { if (ownInetAddress == null || appUUID == null) { throw new NullPointerException("InetAddress or appUUID was null."); } IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotEthernetAdapter ethernetAdapter = new BlaubotEthernetAdapter(ownDevice, acceptorPort, ownInetAddress); BlaubotBluetoothBeacon bluetoothBeacon = new BlaubotBluetoothBeacon(); return createBlaubot(appUUID, ownDevice, ethernetAdapter, bluetoothBeacon); } /** * Creates a Blaubot instance from a given adapter and multiple beacons. * * @param appUuid the app's unique uuid * @param ownDevice the own device containing this device's unique identifier * @param adapter the adapter to be used (Sockets, WebSockets, Bluetooth, ...) * @param beacons the becaons to be used (Bluetooth, NFC, Multicast, Bonjour, ...) * @return the blaubot instance */ public static BlaubotAndroid createBlaubot(UUID appUuid, IBlaubotDevice ownDevice, IBlaubotAdapter adapter, IBlaubotBeacon... beacons) { BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUuid); List<IBlaubotAdapter> adapters = new ArrayList<>(); adapters.add(adapter); BlaubotAndroid blaubotInstance = new BlaubotAndroid(ownDevice, uuidSet, adapters, Arrays.asList(beacons)); return blaubotInstance; } /** * Sets up a default {@link Blaubot} instance using only the bluetooth adapter. * * @param appUUID the app's unique uuid * @param beaconPort the port on which the beacon accepts connections via tcp * @param beaconBroadcastPort the port on which the beacons broadcasts and receives udp multicasts * @return blaubot instance */ public static BlaubotAndroid createBluetoothBlaubotWithMulticastBeacon(UUID appUUID, int beaconPort, int beaconBroadcastPort) { IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); final InetAddress ownInetAddress = getLocalIpAddress(); if (ownInetAddress == null || appUUID == null) throw new NullPointerException(); final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { throw new RuntimeException("Bluetooth is not supported by this device: No bluetooth default adapter found."); } BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUUID); BlaubotBluetoothAdapter bluetoothAdapter = new BlaubotBluetoothAdapter(uuidSet, ownDevice); BlaubotEthernetMulticastBeacon multicastBeacon = new BlaubotEthernetMulticastBeacon(beaconPort, beaconBroadcastPort); return (BlaubotAndroid) createBlaubot(appUUID, ownDevice, bluetoothAdapter, multicastBeacon); } /** * Sets up a default {@link Blaubot} instance using only bluetooth for discovery and network connections. * * @param appUUID the app's unique uuid * @return blaubot instance */ public static BlaubotAndroid createBluetoothBlaubot(UUID appUUID) { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { throw new RuntimeException("Bluetooth is not supported by this device: No bluetooth default adapter found. "); } IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUUID); BlaubotBluetoothAdapter bluetoothAdapter = new BlaubotBluetoothAdapter(uuidSet, ownDevice); BlaubotBluetoothBeacon blaubotBluetoothBeacon = new BlaubotBluetoothBeacon(); return (BlaubotAndroid) createBlaubot(appUUID, ownDevice, bluetoothAdapter, blaubotBluetoothBeacon); } /** * Creates a bluetooth driven blaubot intance using NFC as beacon. * Please ensure, that you delegate the android lifecycle events to the blaubot instance * as described in {@link BlaubotAndroid}. * * @param appUuid the app's uuid * @return the android blaubot instance */ public static BlaubotAndroid createBluetoothBlaubotWithNFCBeacon(UUID appUuid) { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { throw new RuntimeException("Bluetooth is not supported by this device: No bluetooth default adapter found."); } IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUuid); BlaubotBluetoothAdapter bluetoothAdapter = new BlaubotBluetoothAdapter(uuidSet, ownDevice); BlaubotNFCBeacon nfcBeacon = new BlaubotNFCBeacon(); return (BlaubotAndroid) createBlaubot(appUuid, ownDevice, bluetoothAdapter, nfcBeacon); } /** * Creates a bluetooth driven blaubot intance using NFC and Bluetooth as beacons. * Please ensure, that you delegate the android lifecycle events to the blaubot instance * as described in {@link BlaubotAndroid}. * * @param appUuid the app's uuid * @return the android blaubot instance */ public static BlaubotAndroid createBluetoothBlaubotWithBluetoothAndNFCBeacon(UUID appUuid) { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { throw new RuntimeException("Bluetooth is not supported by this device: No bluetooth default adapter found."); } IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUuid); BlaubotBluetoothAdapter bluetoothAdapter = new BlaubotBluetoothAdapter(uuidSet, ownDevice); BlaubotBluetoothBeacon bluetoothBeacon = new BlaubotBluetoothBeacon(); BlaubotNFCBeacon nfcBeacon = new BlaubotNFCBeacon(); return (BlaubotAndroid) createBlaubot(appUuid, ownDevice, bluetoothAdapter, bluetoothBeacon, nfcBeacon); } /** * Sets up a default {@link Blaubot} instance using only the WIFIDirect adapter. * WARNING: This experimental and not recommended in production environments. * * @param appUUID the app's unique uuid * @param p2pWifiManager android's p2p wifi manager service * @param wifiManager the android wifi manager service * @param beaconChannel the beaconChannel (wifip2p) to be used for beacon transmissions * @param acceptorChannel the acceptorChannel (wifip2p) on which connection are going to be accepted * @return blaubot instance */ public static BlaubotAndroid createWifiP2PBlaubot(UUID appUUID, WifiP2pManager p2pWifiManager, WifiManager wifiManager, WifiP2pManager.Channel beaconChannel, WifiP2pManager.Channel acceptorChannel) { BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUUID); IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); //BlaubotWifiP2PAdapter adapter = new BlaubotWifiP2PAdapter(uuidSet, p2pWifiManager, wifiManager, acceptorChannel); BlaubotBluetoothAdapter bluetoothAdapter = new BlaubotBluetoothAdapter(uuidSet, ownDevice); BlaubotWifiP2PBeacon blaubotWifiP2PBeacon = new BlaubotWifiP2PBeacon(p2pWifiManager, beaconChannel, 1987); List<IBlaubotAdapter> adapters = new ArrayList<IBlaubotAdapter>(); List<IBlaubotBeacon> beacons = new ArrayList<>(); adapters.add(bluetoothAdapter); beacons.add(blaubotWifiP2PBeacon); BlaubotAndroid blaubotInstance = new BlaubotAndroid(ownDevice, uuidSet, adapters, beacons); return blaubotInstance; } /** * Sets up a default {@link Blaubot} instance using Wifi by creating wifi access points and socket * connections. Discovery is done by the NFC beacon. * WARNING: This experimental and not recommended in production environments. * * @param appUUID the app's unique uuid * @param connectivityManager the connectivity system service * @param wifiManager the android wifi manager * @param acceptorPort the port to accept connections on * @return blaubot instance */ public static BlaubotAndroid createWifiApWithNfcBeaconBlaubot(UUID appUUID, ConnectivityManager connectivityManager, WifiManager wifiManager, int acceptorPort) { BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUUID); IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotWifiAdapter blaubotWifiAdapter = new BlaubotWifiAdapter(ownDevice, uuidSet, acceptorPort, wifiManager, connectivityManager); BlaubotNFCBeacon nfcBeacon = new BlaubotNFCBeacon(); return (BlaubotAndroid) createBlaubot(appUUID, ownDevice, blaubotWifiAdapter, nfcBeacon); } /** * Sets up a default {@link Blaubot} instance using Wifi by creating wifi access points and socket * connections. Discovery is done by the Bluetooth beacon. * WARNING: This experimental and not recommended in production environments. * * @param appUUID the app's unique uuid * @param connectivityManager the connectivity system service * @param wifiManager the android wifi manager * @param acceptorPort the port to accept connections on * @return blaubot instance */ public static BlaubotAndroid createWifiApWithBluetoothBeaconBlaubot(UUID appUUID, ConnectivityManager connectivityManager, WifiManager wifiManager, int acceptorPort) { BlaubotUUIDSet uuidSet = new BlaubotUUIDSet(appUUID); IBlaubotDevice ownDevice = new BlaubotDevice(UUID.randomUUID().toString()); BlaubotWifiAdapter blaubotWifiAdapter = new BlaubotWifiAdapter(ownDevice, uuidSet, acceptorPort, wifiManager, connectivityManager); BlaubotBluetoothBeacon bluetoothBeacon = new BlaubotBluetoothBeacon(); return (BlaubotAndroid) createBlaubot(appUUID, ownDevice, blaubotWifiAdapter, bluetoothBeacon); } }