Full code reformat

This commit is contained in:
Alexandros Schillings
2015-07-03 14:52:14 +01:00
parent 5f55a3ea45
commit 53138d5462
42 changed files with 3637 additions and 3625 deletions
+5 -4
View File
@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest
package="uk.co.alt236.bluetoothlelib" package="uk.co.alt236.bluetoothlelib"
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="2" android:versionCode="2"
android:versionName="0.0.2" > android:versionName="0.0.2">
<uses-sdk <uses-sdk
android:minSdkVersion="18" android:minSdkVersion="18"
android:targetSdkVersion="18" /> android:targetSdkVersion="18"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme">
</application> </application>
</manifest> </manifest>
@@ -1,5 +1,10 @@
package uk.co.alt236.bluetoothlelib.device; package uk.co.alt236.bluetoothlelib.device;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
@@ -10,12 +15,9 @@ import uk.co.alt236.bluetoothlelib.resolvers.BluetoothClassResolver;
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils; import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
import uk.co.alt236.bluetoothlelib.util.ByteUtils; import uk.co.alt236.bluetoothlelib.util.ByteUtils;
import uk.co.alt236.bluetoothlelib.util.LimitedLinkHashMap; import uk.co.alt236.bluetoothlelib.util.LimitedLinkHashMap;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
// TODO: Auto-generated Javadoc // TODO: Auto-generated Javadoc
/** /**
* This is a wrapper around the default BluetoothDevice object * This is a wrapper around the default BluetoothDevice object
* As BluetoothDevice is final it cannot be extended, so to get it you * As BluetoothDevice is final it cannot be extended, so to get it you
@@ -23,29 +25,10 @@ import android.os.Parcelable;
* *
* @author Alexandros Schillings * @author Alexandros Schillings
*/ */
public class BluetoothLeDevice implements Parcelable{ public class BluetoothLeDevice implements Parcelable {
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device"; /**
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi"; * The Constant CREATOR.
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp"; */
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
protected static final int MAX_RSSI_LOG_SIZE = 10;
private final AdRecordStore mRecordStore;
private final BluetoothDevice mDevice;
private final Map<Long, Integer> mRssiLog;
private final byte[] mScanRecord;
private final int mFirstRssi;
private final long mFirstTimestamp;
private int mCurrentRssi;
private long mCurrentTimestamp;
/** The Constant CREATOR. */
public static final Parcelable.Creator<BluetoothLeDevice> CREATOR = new Parcelable.Creator<BluetoothLeDevice>() { public static final Parcelable.Creator<BluetoothLeDevice> CREATOR = new Parcelable.Creator<BluetoothLeDevice>() {
public BluetoothLeDevice createFromParcel(final Parcel in) { public BluetoothLeDevice createFromParcel(final Parcel in) {
return new BluetoothLeDevice(in); return new BluetoothLeDevice(in);
@@ -55,6 +38,24 @@ public class BluetoothLeDevice implements Parcelable{
return new BluetoothLeDevice[size]; return new BluetoothLeDevice[size];
} }
}; };
protected static final int MAX_RSSI_LOG_SIZE = 10;
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device";
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi";
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp";
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
private final AdRecordStore mRecordStore;
private final BluetoothDevice mDevice;
private final Map<Long, Integer> mRssiLog;
private final byte[] mScanRecord;
private final int mFirstRssi;
private final long mFirstTimestamp;
private int mCurrentRssi;
private long mCurrentTimestamp;
/** /**
* Instantiates a new Bluetooth LE device. * Instantiates a new Bluetooth LE device.
@@ -64,7 +65,7 @@ public class BluetoothLeDevice implements Parcelable{
* @param scanRecord the scan record of the device * @param scanRecord the scan record of the device
* @param timestamp the timestamp of the RSSI reading * @param timestamp the timestamp of the RSSI reading
*/ */
public BluetoothLeDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp){ public BluetoothLeDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
mDevice = device; mDevice = device;
mFirstRssi = rssi; mFirstRssi = rssi;
mFirstTimestamp = timestamp; mFirstTimestamp = timestamp;
@@ -116,9 +117,9 @@ public class BluetoothLeDevice implements Parcelable{
* @param timestamp the timestamp * @param timestamp the timestamp
* @param rssiReading the rssi reading * @param rssiReading the rssi reading
*/ */
private void addToRssiLog(final long timestamp, final int rssiReading){ private void addToRssiLog(final long timestamp, final int rssiReading) {
synchronized (mRssiLog) { synchronized (mRssiLog) {
if(timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD){ if (timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD) {
mRssiLog.clear(); mRssiLog.clear();
} }
@@ -176,30 +177,30 @@ public class BluetoothLeDevice implements Parcelable{
return true; return true;
} }
/**
* Gets the address.
*
* @return the address
*/
public String getAddress(){
return mDevice.getAddress();
}
/** /**
* Gets the ad record store. * Gets the ad record store.
* *
* @return the ad record store * @return the ad record store
*/ */
public AdRecordStore getAdRecordStore(){ public AdRecordStore getAdRecordStore() {
return mRecordStore; return mRecordStore;
} }
/**
* Gets the address.
*
* @return the address
*/
public String getAddress() {
return mDevice.getAddress();
}
/** /**
* Gets the bluetooth device bond state. * Gets the bluetooth device bond state.
* *
* @return the bluetooth device bond state * @return the bluetooth device bond state
*/ */
public String getBluetoothDeviceBondState(){ public String getBluetoothDeviceBondState() {
return resolveBondingState(mDevice.getBondState()); return resolveBondingState(mDevice.getBondState());
} }
@@ -208,7 +209,7 @@ public class BluetoothLeDevice implements Parcelable{
* *
* @return the bluetooth device class name * @return the bluetooth device class name
*/ */
public String getBluetoothDeviceClassName(){ public String getBluetoothDeviceClassName() {
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass()); return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
} }
@@ -226,7 +227,7 @@ public class BluetoothLeDevice implements Parcelable{
* *
* @return the first rssi * @return the first rssi
*/ */
public int getFirstRssi(){ public int getFirstRssi() {
return mFirstRssi; return mFirstRssi;
} }
@@ -235,7 +236,7 @@ public class BluetoothLeDevice implements Parcelable{
* *
* @return the first timestamp * @return the first timestamp
*/ */
public long getFirstTimestamp(){ public long getFirstTimestamp() {
return mFirstTimestamp; return mFirstTimestamp;
} }
@@ -244,7 +245,7 @@ public class BluetoothLeDevice implements Parcelable{
* *
* @return the name * @return the name
*/ */
public String getName(){ public String getName() {
return mDevice.getName(); return mDevice.getName();
} }
@@ -273,15 +274,15 @@ public class BluetoothLeDevice implements Parcelable{
* *
* @return the running average rssi * @return the running average rssi
*/ */
public double getRunningAverageRssi(){ public double getRunningAverageRssi() {
int sum = 0; int sum = 0;
int count = 0; int count = 0;
synchronized (mRssiLog) { synchronized (mRssiLog) {
final Iterator<Long> it1 = mRssiLog.keySet().iterator(); final Iterator<Long> it1 = mRssiLog.keySet().iterator();
while(it1.hasNext()){ while (it1.hasNext()) {
count ++; count++;
sum += mRssiLog.get(it1.next()); sum += mRssiLog.get(it1.next());
} }
} }
@@ -290,8 +291,8 @@ public class BluetoothLeDevice implements Parcelable{
// sum += e.getValue(); // sum += e.getValue();
// } // }
if(count > 0){ if (count > 0) {
return sum/count; return sum / count;
} else { } else {
return 0; return 0;
} }
@@ -312,7 +313,7 @@ public class BluetoothLeDevice implements Parcelable{
* *
* @return the timestamp * @return the timestamp
*/ */
public long getTimestamp(){ public long getTimestamp() {
return mCurrentTimestamp; return mCurrentTimestamp;
} }
@@ -348,7 +349,7 @@ public class BluetoothLeDevice implements Parcelable{
* @param timestamp the timestamp * @param timestamp the timestamp
* @param rssiReading the rssi reading * @param rssiReading the rssi reading
*/ */
public void updateRssiReading(final long timestamp, final int rssiReading){ public void updateRssiReading(final long timestamp, final int rssiReading) {
addToRssiLog(timestamp, rssiReading); addToRssiLog(timestamp, rssiReading);
} }
@@ -380,8 +381,8 @@ public class BluetoothLeDevice implements Parcelable{
* @param bondState the bond state * @param bondState the bond state
* @return the string * @return the string
*/ */
private static String resolveBondingState(final int bondState){ private static String resolveBondingState(final int bondState) {
switch (bondState){ switch (bondState) {
case BluetoothDevice.BOND_BONDED: case BluetoothDevice.BOND_BONDED:
return "Paired"; return "Paired";
case BluetoothDevice.BOND_BONDING: case BluetoothDevice.BOND_BONDING:
@@ -1,14 +1,17 @@
package uk.co.alt236.bluetoothlelib.device; package uk.co.alt236.bluetoothlelib.device;
import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils.IBeaconDistanceDescriptor;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.os.Parcel; import android.os.Parcel;
public class IBeaconDevice extends BluetoothLeDevice{ import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData;
import uk.co.alt236.bluetoothlelib.util.IBeaconDistanceDescriptor;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
/** The m iBeacon data. */ public class IBeaconDevice extends BluetoothLeDevice {
/**
* The m iBeacon data.
*/
private final IBeaconManufacturerData mIBeaconData; private final IBeaconManufacturerData mIBeaconData;
/** /**
@@ -34,7 +37,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* @param timestamp the timestamp of the RSSI measurement * @param timestamp the timestamp of the RSSI measurement
* @throws IllegalArgumentException if the passed device is not an iBeacon * @throws IllegalArgumentException if the passed device is not an iBeacon
*/ */
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp){ public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
super(device, rssi, scanRecord, timestamp); super(device, rssi, scanRecord, timestamp);
validate(); validate();
mIBeaconData = new IBeaconManufacturerData(this); mIBeaconData = new IBeaconManufacturerData(this);
@@ -47,7 +50,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* @param device the device * @param device the device
* @throws IllegalArgumentException if the passed device is not an iBeacon * @throws IllegalArgumentException if the passed device is not an iBeacon
*/ */
public IBeaconDevice(final BluetoothLeDevice device){ public IBeaconDevice(final BluetoothLeDevice device) {
super(device); super(device);
validate(); validate();
mIBeaconData = new IBeaconManufacturerData(this); mIBeaconData = new IBeaconManufacturerData(this);
@@ -66,7 +69,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the accuracy in meters * @return the accuracy in meters
*/ */
public double getAccuracy(){ public double getAccuracy() {
return IBeaconUtils.calculateAccuracy( return IBeaconUtils.calculateAccuracy(
getCalibratedTxPower(), getCalibratedTxPower(),
getRunningAverageRssi()); getRunningAverageRssi());
@@ -77,7 +80,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the calibrated TX power * @return the calibrated TX power
*/ */
public int getCalibratedTxPower(){ public int getCalibratedTxPower() {
return getIBeaconData().getCalibratedTxPower(); return getIBeaconData().getCalibratedTxPower();
} }
@@ -86,7 +89,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the company identifier * @return the company identifier
*/ */
public int getCompanyIdentifier(){ public int getCompanyIdentifier() {
return getIBeaconData().getCompanyIdentifier(); return getIBeaconData().getCompanyIdentifier();
} }
@@ -95,7 +98,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the distance descriptor * @return the distance descriptor
*/ */
public IBeaconDistanceDescriptor getDistanceDescriptor(){ public IBeaconDistanceDescriptor getDistanceDescriptor() {
return IBeaconUtils.getDistanceDescriptor(getAccuracy()); return IBeaconUtils.getDistanceDescriptor(getAccuracy());
} }
@@ -104,7 +107,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the iBeacon data * @return the iBeacon data
*/ */
public IBeaconManufacturerData getIBeaconData(){ public IBeaconManufacturerData getIBeaconData() {
return mIBeaconData; return mIBeaconData;
} }
@@ -113,7 +116,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the Major value * @return the Major value
*/ */
public int getMajor(){ public int getMajor() {
return getIBeaconData().getMajor(); return getIBeaconData().getMajor();
} }
@@ -122,7 +125,7 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the Minor value * @return the Minor value
*/ */
public int getMinor(){ public int getMinor() {
return getIBeaconData().getMinor(); return getIBeaconData().getMinor();
} }
@@ -131,12 +134,12 @@ public class IBeaconDevice extends BluetoothLeDevice{
* *
* @return the UUID * @return the UUID
*/ */
public String getUUID(){ public String getUUID() {
return getIBeaconData().getUUID(); return getIBeaconData().getUUID();
} }
private void validate(){ private void validate() {
if(!IBeaconUtils.isThisAnIBeacon(this)){ if (!IBeaconUtils.isThisAnIBeacon(this)) {
throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon."); throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon.");
} }
} }
@@ -1,17 +1,18 @@
package uk.co.alt236.bluetoothlelib.device.adrecord; package uk.co.alt236.bluetoothlelib.device.adrecord;
import java.util.Arrays;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import java.util.Arrays;
/** /**
* Created by Dave Smith * Created by Dave Smith
* Double Encore, Inc. * Double Encore, Inc.
* * <p/>
* Expanded by Alexandros Schillings * Expanded by Alexandros Schillings
*/ */
public final class AdRecord implements Parcelable{ public final class AdRecord implements Parcelable {
// 02 # Number of bytes that follow in first AD structure // 02 # Number of bytes that follow in first AD structure
// 01 # Flags AD type // 01 # Flags AD type
// 1A # Flags value 0x1A = 000011010 // 1A # Flags value 0x1A = 000011010
@@ -31,15 +32,11 @@ public final class AdRecord implements Parcelable{
// c5 # The 2's complement of the calibrated Tx Power // c5 # The 2's complement of the calibrated Tx Power
private static final String PARCEL_RECORD_DATA = "record_data";
private static final String PARCEL_RECORD_TYPE = "record_type";
private static final String PARCEL_RECORD_LENGTH = "record_length";
/** /**
* General FLAGS * General FLAGS
* * <p/>
* Description: Flags * Description: Flags
* * <p/>
* Information: * Information:
* Bit 0: LE Limited Discoverable Mode * Bit 0: LE Limited Discoverable Mode
* Bit 1: LE General Discoverable Mode * Bit 1: LE General Discoverable Mode
@@ -49,7 +46,6 @@ public final class AdRecord implements Parcelable{
* Bits 5-7 Reserved * Bits 5-7 Reserved
*/ */
public static final int TYPE_FLAGS = 0x01; public static final int TYPE_FLAGS = 0x01;
// SERVICE // SERVICE
public static final int TYPE_UUID16_INC = 0x02; public static final int TYPE_UUID16_INC = 0x02;
public static final int TYPE_UUID16 = 0x03; public static final int TYPE_UUID16 = 0x03;
@@ -57,23 +53,17 @@ public final class AdRecord implements Parcelable{
public static final int TYPE_UUID32 = 0x05; public static final int TYPE_UUID32 = 0x05;
public static final int TYPE_UUID128_INC = 0x06; public static final int TYPE_UUID128_INC = 0x06;
public static final int TYPE_UUID128 = 0x07; public static final int TYPE_UUID128 = 0x07;
// Local name // Local name
public static final int TYPE_LOCAL_NAME_SHORT = 0x08; public static final int TYPE_LOCAL_NAME_SHORT = 0x08;
public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09; public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09;
// TX Power Level // TX Power Level
public static final int TYPE_TX_POWER_LEVEL = 0x0A; public static final int TYPE_TX_POWER_LEVEL = 0x0A;
// SIMPLE PAIRING OPTIONAL OOB TAGS // SIMPLE PAIRING OPTIONAL OOB TAGS
public static final int TYPE_DEVICE_CLASS = 0x0D; public static final int TYPE_DEVICE_CLASS = 0x0D;
public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E; public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;
public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F; public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;
// SECURITY MANAGER TK VALUE // SECURITY MANAGER TK VALUE
public static final int TYPE_TK_VALUE = 0x10; public static final int TYPE_TK_VALUE = 0x10;
/* SECURITY MANAGER OOB FLAGS /* SECURITY MANAGER OOB FLAGS
* *
* Description: Flag (1 octet) * Description: Flag (1 octet)
@@ -86,8 +76,6 @@ public final class AdRecord implements Parcelable{
* Bits 4-7 Reserved * Bits 4-7 Reserved
*/ */
public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11; public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;
/* SLAVE CONNECTION INTERVAL RANGE /* SLAVE CONNECTION INTERVAL RANGE
* *
* Description: Slave Connection Interval Range * Description: Slave Connection Interval Range
@@ -108,32 +96,21 @@ public final class AdRecord implements Parcelable{
* Values outside the range are reserved (excluding 0xFFFF) * Values outside the range are reserved (excluding 0xFFFF)
*/ */
public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12; public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12;
// SERVICE SOLICITATION // SERVICE SOLICITATION
public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14; public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14;
public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15; public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15;
/* SERVICE DATA /* SERVICE DATA
* *
* Description: Service Data (2 or more octets) * Description: Service Data (2 or more octets)
* Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data * Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data
*/ */
public static final int TYPE_SERVICE_DATA = 0x16; public static final int TYPE_SERVICE_DATA = 0x16;
/* MANUFACTURER SPECIFIC DATA /* MANUFACTURER SPECIFIC DATA
* *
* Description: Manufacturer Specific Data (2 or more octets) * Description: Manufacturer Specific Data (2 or more octets)
* Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data * Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
*/ */
public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF; public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
/* Model Object Definition */
private final int mLength;
private final int mType;
private final byte[] mData;
public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() { public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() {
public AdRecord createFromParcel(final Parcel in) { public AdRecord createFromParcel(final Parcel in) {
return new AdRecord(in); return new AdRecord(in);
@@ -143,6 +120,13 @@ public final class AdRecord implements Parcelable{
return new AdRecord[size]; return new AdRecord[size];
} }
}; };
private static final String PARCEL_RECORD_DATA = "record_data";
private static final String PARCEL_RECORD_TYPE = "record_type";
private static final String PARCEL_RECORD_LENGTH = "record_length";
/* Model Object Definition */
private final int mLength;
private final int mType;
private final byte[] mData;
public AdRecord(final int length, final int type, final byte[] data) { public AdRecord(final int length, final int type, final byte[] data) {
mLength = length; mLength = length;
@@ -162,11 +146,11 @@ public final class AdRecord implements Parcelable{
return 0; return 0;
} }
public byte[] getData(){ public byte[] getData() {
return mData; return mData;
} }
public String getHumanReadableType(){ public String getHumanReadableType() {
return getHumanReadableAdType(mType); return getHumanReadableAdType(mType);
} }
@@ -194,8 +178,8 @@ public final class AdRecord implements Parcelable{
parcel.writeBundle(b); parcel.writeBundle(b);
} }
private static String getHumanReadableAdType(final int type){ private static String getHumanReadableAdType(final int type) {
switch(type){ switch (type) {
case TYPE_CONNECTION_INTERVAL_RANGE: case TYPE_CONNECTION_INTERVAL_RANGE:
return "Slave Connection Interval Range"; return "Slave Connection Interval Range";
case TYPE_DEVICE_CLASS: case TYPE_DEVICE_CLASS:
@@ -1,23 +1,20 @@
package uk.co.alt236.bluetoothlelib.device.adrecord; package uk.co.alt236.bluetoothlelib.device.adrecord;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils; import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
/** /**
* The Class AdRecordStore. * The Class AdRecordStore.
*/ */
public class AdRecordStore implements Parcelable{ public class AdRecordStore implements Parcelable {
private final SparseArray<AdRecord> mAdRecords;
private final String mLocalNameComplete;
private final String mLocalNameShort;
public static final Parcelable.Creator<AdRecordStore> CREATOR = new Parcelable.Creator<AdRecordStore>() { public static final Parcelable.Creator<AdRecordStore> CREATOR = new Parcelable.Creator<AdRecordStore>() {
public AdRecordStore createFromParcel(final Parcel in) { public AdRecordStore createFromParcel(final Parcel in) {
return new AdRecordStore(in); return new AdRecordStore(in);
@@ -27,6 +24,9 @@ public class AdRecordStore implements Parcelable{
return new AdRecordStore[size]; return new AdRecordStore[size];
} }
}; };
private final SparseArray<AdRecord> mAdRecords;
private final String mLocalNameComplete;
private final String mLocalNameShort;
public AdRecordStore(final Parcel in) { public AdRecordStore(final Parcel in) {
final Bundle b = in.readBundle(getClass().getClassLoader()); final Bundle b = in.readBundle(getClass().getClassLoader());
@@ -40,7 +40,7 @@ public class AdRecordStore implements Parcelable{
* *
* @param adRecords the ad records * @param adRecords the ad records
*/ */
public AdRecordStore(final SparseArray<AdRecord> adRecords){ public AdRecordStore(final SparseArray<AdRecord> adRecords) {
mAdRecords = adRecords; mAdRecords = adRecords;
mLocalNameComplete = AdRecordUtils.getRecordDataAsString( mLocalNameComplete = AdRecordUtils.getRecordDataAsString(
@@ -83,7 +83,7 @@ public class AdRecordStore implements Parcelable{
* @param record the record * @param record the record
* @return the record * @return the record
*/ */
public AdRecord getRecord(final int record){ public AdRecord getRecord(final int record) {
return mAdRecords.get(record); return mAdRecords.get(record);
} }
@@ -93,7 +93,7 @@ public class AdRecordStore implements Parcelable{
* @param record the record * @param record the record
* @return the record data as string * @return the record data as string
*/ */
public String getRecordDataAsString(final int record){ public String getRecordDataAsString(final int record) {
return AdRecordUtils.getRecordDataAsString( return AdRecordUtils.getRecordDataAsString(
mAdRecords.get(record)); mAdRecords.get(record));
} }
@@ -113,7 +113,7 @@ public class AdRecordStore implements Parcelable{
* @param record the record * @param record the record
* @return true, if is record present * @return true, if is record present
*/ */
public boolean isRecordPresent(final int record){ public boolean isRecordPresent(final int record) {
return mAdRecords.indexOfKey(record) >= 0; return mAdRecords.indexOfKey(record) >= 0;
} }
@@ -149,7 +149,7 @@ public class AdRecordStore implements Parcelable{
if (sparseArray == null) return null; if (sparseArray == null) return null;
final Collection<C> arrayList = new ArrayList<C>(sparseArray.size()); final Collection<C> arrayList = new ArrayList<C>(sparseArray.size());
for (int i = 0; i < sparseArray.size(); i++){ for (int i = 0; i < sparseArray.size(); i++) {
arrayList.add(sparseArray.valueAt(i)); arrayList.add(sparseArray.valueAt(i));
} }
@@ -8,9 +8,9 @@ import uk.co.alt236.bluetoothlelib.util.ByteUtils;
/** /**
* Parses the Manufactured Data field of an iBeacon * Parses the Manufactured Data field of an iBeacon
* * <p/>
* The parsing is based on the following schema: * The parsing is based on the following schema:
* * <p/>
* <p> * <p>
* 0 4C - Byte 1 (LSB) of Company identifier code * 0 4C - Byte 1 (LSB) of Company identifier code
* 1 00 - Byte 0 (MSB) of Company identifier code (0x004C == Apple) * 1 00 - Byte 0 (MSB) of Company identifier code (0x004C == Apple)
@@ -37,11 +37,10 @@ import uk.co.alt236.bluetoothlelib.util.ByteUtils;
* 22 00 - minor * 22 00 - minor
* 23 00 * 23 00
* 24 c5 - The 2's complement of the calibrated Tx Power * 24 c5 - The 2's complement of the calibrated Tx Power
* * <p/>
* </p> * </p>
* *
* @author Alexandros Schillings * @author Alexandros Schillings
*
*/ */
public final class IBeaconManufacturerData { public final class IBeaconManufacturerData {
@@ -53,17 +52,17 @@ public final class IBeaconManufacturerData {
private final int mMinor; private final int mMinor;
private final String mUUID; private final String mUUID;
public IBeaconManufacturerData(final BluetoothLeDevice device){ public IBeaconManufacturerData(final BluetoothLeDevice device) {
this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData()); this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData());
} }
/** /**
* Instantiates a new iBeacon manufacturer data object. * Instantiates a new iBeacon manufacturer data object.
*
* @param data the {@link uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord#TYPE_MANUFACTURER_SPECIFIC_DATA} data array * @param data the {@link uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord#TYPE_MANUFACTURER_SPECIFIC_DATA} data array
* @throws IndexOutOfBoundsException if the data array is shorter than expected * @throws IndexOutOfBoundsException if the data array is shorter than expected
*/ */
public IBeaconManufacturerData(final byte[] data){ public IBeaconManufacturerData(final byte[] data) {
mData = data; mData = data;
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray( mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(
@@ -81,7 +80,7 @@ public final class IBeaconManufacturerData {
* *
* @return the calibrated TX power * @return the calibrated TX power
*/ */
public int getCalibratedTxPower(){ public int getCalibratedTxPower() {
return mCalibratedTxPower; return mCalibratedTxPower;
} }
@@ -90,11 +89,11 @@ public final class IBeaconManufacturerData {
* *
* @return the company identifier * @return the company identifier
*/ */
public int getCompanyIdentifier(){ public int getCompanyIdentifier() {
return mCompanyIdentidier; return mCompanyIdentidier;
} }
public int getIBeaconAdvertisement(){ public int getIBeaconAdvertisement() {
return mIBeaconAdvertisment; return mIBeaconAdvertisment;
} }
@@ -103,7 +102,7 @@ public final class IBeaconManufacturerData {
* *
* @return the Major value * @return the Major value
*/ */
public int getMajor(){ public int getMajor() {
return mMajor; return mMajor;
} }
@@ -112,7 +111,7 @@ public final class IBeaconManufacturerData {
* *
* @return the Minor value * @return the Minor value
*/ */
public int getMinor(){ public int getMinor() {
return mMinor; return mMinor;
} }
@@ -121,18 +120,26 @@ public final class IBeaconManufacturerData {
* *
* @return the UUID * @return the UUID
*/ */
public String getUUID(){ public String getUUID() {
return mUUID; return mUUID;
} }
private static String calculateUUIDString(final byte[] uuid){ private static String calculateUUIDString(final byte[] uuid) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
for(int i = 0 ; i< uuid.length; i++){ for (int i = 0; i < uuid.length; i++) {
if(i == 4){sb.append('-');} if (i == 4) {
if(i == 6){sb.append('-');} sb.append('-');
if(i == 8){sb.append('-');} }
if(i == 10){sb.append('-');} if (i == 6) {
sb.append('-');
}
if (i == 8) {
sb.append('-');
}
if (i == 10) {
sb.append('-');
}
sb.append( sb.append(
Integer.toHexString(ByteUtils.getIntFromByte(uuid[i]))); Integer.toHexString(ByteUtils.getIntFromByte(uuid[i])));
@@ -4,8 +4,8 @@ import android.bluetooth.BluetoothClass;
public class BluetoothClassResolver { public class BluetoothClassResolver {
public static String resolveDeviceClass(final int btClass){ public static String resolveDeviceClass(final int btClass) {
switch (btClass){ switch (btClass) {
case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER: case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER:
return "A/V, Camcorder"; return "A/V, Camcorder";
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
@@ -60,13 +60,13 @@ public class BluetoothClassResolver {
return "Health, Data Display"; return "Health, Data Display";
case BluetoothClass.Device.HEALTH_GLUCOSE: case BluetoothClass.Device.HEALTH_GLUCOSE:
return "Health, Glucose"; return "Health, Glucose";
case BluetoothClass.Device.HEALTH_PULSE_OXIMETER : case BluetoothClass.Device.HEALTH_PULSE_OXIMETER:
return "Health, Pulse Oximeter"; return "Health, Pulse Oximeter";
case BluetoothClass.Device.HEALTH_PULSE_RATE : case BluetoothClass.Device.HEALTH_PULSE_RATE:
return "Health, Pulse Rate"; return "Health, Pulse Rate";
case BluetoothClass.Device.HEALTH_THERMOMETER : case BluetoothClass.Device.HEALTH_THERMOMETER:
return "Health, Thermometer"; return "Health, Thermometer";
case BluetoothClass.Device.HEALTH_UNCATEGORIZED : case BluetoothClass.Device.HEALTH_UNCATEGORIZED:
return "Health, Uncategorized"; return "Health, Uncategorized";
case BluetoothClass.Device.HEALTH_WEIGHING: case BluetoothClass.Device.HEALTH_WEIGHING:
return "Health, Weighting"; return "Health, Weighting";
@@ -107,7 +107,7 @@ public class BluetoothClassResolver {
case BluetoothClass.Device.WEARABLE_WRIST_WATCH: case BluetoothClass.Device.WEARABLE_WRIST_WATCH:
return "Wearable, Wrist Watch"; return "Wearable, Wrist Watch";
default: default:
return "Unknown, Unknown (class=" + btClass +")"; return "Unknown, Unknown (class=" + btClass + ")";
} }
} }
} }
@@ -318,7 +318,7 @@ public class CompanyIdentifierResolver {
private static final SparseArray<String> COMPANY_NAME_MAP = populateCompanyNameMap(); private static final SparseArray<String> COMPANY_NAME_MAP = populateCompanyNameMap();
public static String getCompanyName(final int companyId, final String fallback){ public static String getCompanyName(final int companyId, final String fallback) {
final String name = COMPANY_NAME_MAP.get(companyId); final String name = COMPANY_NAME_MAP.get(companyId);
return name == null ? fallback : name; return name == null ? fallback : name;
} }
@@ -326,318 +326,318 @@ public class CompanyIdentifierResolver {
private static SparseArray<String> populateCompanyNameMap() { private static SparseArray<String> populateCompanyNameMap() {
final SparseArray<String> map = new SparseArray<String>(); final SparseArray<String> map = new SparseArray<String>();
map.put(ERICSSON_TECHNOLOGY_LICENSING , "Ericsson Technology Licensing"); map.put(ERICSSON_TECHNOLOGY_LICENSING, "Ericsson Technology Licensing");
map.put(NOKIA_MOBILE_PHONES , "Nokia Mobile Phones"); map.put(NOKIA_MOBILE_PHONES, "Nokia Mobile Phones");
map.put(INTEL_CORP , "Intel Corp."); map.put(INTEL_CORP, "Intel Corp.");
map.put(IBM_CORP , "IBM Corp."); map.put(IBM_CORP, "IBM Corp.");
map.put(TOSHIBA_CORP , "Toshiba Corp."); map.put(TOSHIBA_CORP, "Toshiba Corp.");
map.put(THREE_COM , "3Com"); map.put(THREE_COM, "3Com");
map.put(MICROSOFT , "Microsoft"); map.put(MICROSOFT, "Microsoft");
map.put(LUCENT , "Lucent"); map.put(LUCENT, "Lucent");
map.put(MOTOROLA , "Motorola"); map.put(MOTOROLA, "Motorola");
map.put(INFINEON_TECHNOLOGIES_AG , "Infineon Technologies AG"); map.put(INFINEON_TECHNOLOGIES_AG, "Infineon Technologies AG");
map.put(CAMBRIDGE_SILICON_RADIO , "Cambridge Silicon Radio"); map.put(CAMBRIDGE_SILICON_RADIO, "Cambridge Silicon Radio");
map.put(SILICON_WAVE , "Silicon Wave"); map.put(SILICON_WAVE, "Silicon Wave");
map.put(DIGIANSWER_A_S , "Digianswer A/S"); map.put(DIGIANSWER_A_S, "Digianswer A/S");
map.put(TEXAS_INSTRUMENTS_INC , "Texas Instruments Inc."); map.put(TEXAS_INSTRUMENTS_INC, "Texas Instruments Inc.");
map.put(CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC , "Ceva, Inc. (formerly Parthus Technologies, Inc.)"); map.put(CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC, "Ceva, Inc. (formerly Parthus Technologies, Inc.)");
map.put(BROADCOM_CORPORATION , "Broadcom Corporation"); map.put(BROADCOM_CORPORATION, "Broadcom Corporation");
map.put(MITEL_SEMICONDUCTOR , "Mitel Semiconductor"); map.put(MITEL_SEMICONDUCTOR, "Mitel Semiconductor");
map.put(WIDCOMM_INC , "Widcomm, Inc"); map.put(WIDCOMM_INC, "Widcomm, Inc");
map.put(ZEEVO_INC , "Zeevo, Inc."); map.put(ZEEVO_INC, "Zeevo, Inc.");
map.put(ATMEL_CORPORATION , "Atmel Corporation"); map.put(ATMEL_CORPORATION, "Atmel Corporation");
map.put(MITSUBISHI_ELECTRIC_CORPORATION , "Mitsubishi Electric Corporation"); map.put(MITSUBISHI_ELECTRIC_CORPORATION, "Mitsubishi Electric Corporation");
map.put(RTX_TELECOM_A_S , "RTX Telecom A/S"); map.put(RTX_TELECOM_A_S, "RTX Telecom A/S");
map.put(KC_TECHNOLOGY_INC , "KC Technology Inc."); map.put(KC_TECHNOLOGY_INC, "KC Technology Inc.");
map.put(NEWLOGIC , "NewLogic"); map.put(NEWLOGIC, "NewLogic");
map.put(TRANSILICA_INC , "Transilica, Inc."); map.put(TRANSILICA_INC, "Transilica, Inc.");
map.put(ROHDE_SCHWARZ_GMBH_CO_KG , "Rohde & Schwarz GmbH & Co. KG"); map.put(ROHDE_SCHWARZ_GMBH_CO_KG, "Rohde & Schwarz GmbH & Co. KG");
map.put(TTPCOM_LIMITED , "TTPCom Limited"); map.put(TTPCOM_LIMITED, "TTPCom Limited");
map.put(SIGNIA_TECHNOLOGIES_INC , "Signia Technologies, Inc."); map.put(SIGNIA_TECHNOLOGIES_INC, "Signia Technologies, Inc.");
map.put(CONEXANT_SYSTEMS_INC , "Conexant Systems Inc."); map.put(CONEXANT_SYSTEMS_INC, "Conexant Systems Inc.");
map.put(QUALCOMM , "Qualcomm"); map.put(QUALCOMM, "Qualcomm");
map.put(INVENTEL , "Inventel"); map.put(INVENTEL, "Inventel");
map.put(AVM_BERLIN , "AVM Berlin"); map.put(AVM_BERLIN, "AVM Berlin");
map.put(BANDSPEED_INC , "BandSpeed, Inc."); map.put(BANDSPEED_INC, "BandSpeed, Inc.");
map.put(MANSELLA_LTD , "Mansella Ltd"); map.put(MANSELLA_LTD, "Mansella Ltd");
map.put(NEC_CORPORATION , "NEC Corporation"); map.put(NEC_CORPORATION, "NEC Corporation");
map.put(WAVEPLUS_TECHNOLOGY_CO_LTD , "WavePlus Technology Co., Ltd."); map.put(WAVEPLUS_TECHNOLOGY_CO_LTD, "WavePlus Technology Co., Ltd.");
map.put(ALCATEL , "Alcatel"); map.put(ALCATEL, "Alcatel");
map.put(PHILIPS_SEMICONDUCTORS , "Philips Semiconductors"); map.put(PHILIPS_SEMICONDUCTORS, "Philips Semiconductors");
map.put(C_TECHNOLOGIES , "C Technologies"); map.put(C_TECHNOLOGIES, "C Technologies");
map.put(OPEN_INTERFACE , "Open Interface"); map.put(OPEN_INTERFACE, "Open Interface");
map.put(R_F_MICRO_DEVICES , "R F Micro Devices"); map.put(R_F_MICRO_DEVICES, "R F Micro Devices");
map.put(HITACHI_LTD , "Hitachi Ltd"); map.put(HITACHI_LTD, "Hitachi Ltd");
map.put(SYMBOL_TECHNOLOGIES_INC , "Symbol Technologies, Inc."); map.put(SYMBOL_TECHNOLOGIES_INC, "Symbol Technologies, Inc.");
map.put(TENOVIS , "Tenovis"); map.put(TENOVIS, "Tenovis");
map.put(MACRONIX_INTERNATIONAL_CO_LTD , "Macronix International Co. Ltd."); map.put(MACRONIX_INTERNATIONAL_CO_LTD, "Macronix International Co. Ltd.");
map.put(GCT_SEMICONDUCTOR , "GCT Semiconductor"); map.put(GCT_SEMICONDUCTOR, "GCT Semiconductor");
map.put(NORWOOD_SYSTEMS , "Norwood Systems"); map.put(NORWOOD_SYSTEMS, "Norwood Systems");
map.put(MEWTEL_TECHNOLOGY_INC , "MewTel Technology Inc."); map.put(MEWTEL_TECHNOLOGY_INC, "MewTel Technology Inc.");
map.put(ST_MICROELECTRONICS , "ST Microelectronics"); map.put(ST_MICROELECTRONICS, "ST Microelectronics");
map.put(SYNOPSIS , "Synopsis"); map.put(SYNOPSIS, "Synopsis");
map.put(REDM_COMMUNICATIONS_LTD , "Red-M (Communications) Ltd"); map.put(REDM_COMMUNICATIONS_LTD, "Red-M (Communications) Ltd");
map.put(COMMIL_LTD , "Commil Ltd"); map.put(COMMIL_LTD, "Commil Ltd");
map.put(COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC , "Computer Access Technology Corporation (CATC)"); map.put(COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC, "Computer Access Technology Corporation (CATC)");
map.put(ECLIPSE_HQ_ESPANA_SL , "Eclipse (HQ Espana) S.L."); map.put(ECLIPSE_HQ_ESPANA_SL, "Eclipse (HQ Espana) S.L.");
map.put(RENESAS_TECHNOLOGY_CORP , "Renesas Technology Corp."); map.put(RENESAS_TECHNOLOGY_CORP, "Renesas Technology Corp.");
map.put(MOBILIAN_CORPORATION , "Mobilian Corporation"); map.put(MOBILIAN_CORPORATION, "Mobilian Corporation");
map.put(TERAX , "Terax"); map.put(TERAX, "Terax");
map.put(INTEGRATED_SYSTEM_SOLUTION_CORP , "Integrated System Solution Corp."); map.put(INTEGRATED_SYSTEM_SOLUTION_CORP, "Integrated System Solution Corp.");
map.put(MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD , "Matsushita Electric Industrial Co., Ltd."); map.put(MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD, "Matsushita Electric Industrial Co., Ltd.");
map.put(GENNUM_CORPORATION , "Gennum Corporation"); map.put(GENNUM_CORPORATION, "Gennum Corporation");
map.put(RESEARCH_IN_MOTION , "Research In Motion"); map.put(RESEARCH_IN_MOTION, "Research In Motion");
map.put(IPEXTREME_INC , "IPextreme, Inc."); map.put(IPEXTREME_INC, "IPextreme, Inc.");
map.put(SYSTEMS_AND_CHIPS_INC , "Systems and Chips, Inc."); map.put(SYSTEMS_AND_CHIPS_INC, "Systems and Chips, Inc.");
map.put(BLUETOOTH_SIG_INC , "Bluetooth SIG, Inc."); map.put(BLUETOOTH_SIG_INC, "Bluetooth SIG, Inc.");
map.put(SEIKO_EPSON_CORPORATION , "Seiko Epson Corporation"); map.put(SEIKO_EPSON_CORPORATION, "Seiko Epson Corporation");
map.put(INTEGRATED_SILICON_SOLUTION_TAIWAN_INC , "Integrated Silicon Solution Taiwan, Inc."); map.put(INTEGRATED_SILICON_SOLUTION_TAIWAN_INC, "Integrated Silicon Solution Taiwan, Inc.");
map.put(CONWISE_TECHNOLOGY_CORPORATION_LTD , "CONWISE Technology Corporation Ltd"); map.put(CONWISE_TECHNOLOGY_CORPORATION_LTD, "CONWISE Technology Corporation Ltd");
map.put(PARROT_SA , "PARROT SA"); map.put(PARROT_SA, "PARROT SA");
map.put(SOCKET_MOBILE , "Socket Mobile"); map.put(SOCKET_MOBILE, "Socket Mobile");
map.put(ATHEROS_COMMUNICATIONS_INC , "Atheros Communications, Inc."); map.put(ATHEROS_COMMUNICATIONS_INC, "Atheros Communications, Inc.");
map.put(MEDIATEK_INC , "MediaTek, Inc."); map.put(MEDIATEK_INC, "MediaTek, Inc.");
map.put(BLUEGIGA , "Bluegiga"); map.put(BLUEGIGA, "Bluegiga");
map.put(MARVELL_TECHNOLOGY_GROUP_LTD , "Marvell Technology Group Ltd."); map.put(MARVELL_TECHNOLOGY_GROUP_LTD, "Marvell Technology Group Ltd.");
map.put(THREE_DSP_CORPORATION , "3DSP Corporation"); map.put(THREE_DSP_CORPORATION, "3DSP Corporation");
map.put(ACCEL_SEMICONDUCTOR_LTD , "Accel Semiconductor Ltd."); map.put(ACCEL_SEMICONDUCTOR_LTD, "Accel Semiconductor Ltd.");
map.put(CONTINENTAL_AUTOMOTIVE_SYSTEMS , "Continental Automotive Systems"); map.put(CONTINENTAL_AUTOMOTIVE_SYSTEMS, "Continental Automotive Systems");
map.put(APPLE_INC , "Apple, Inc."); map.put(APPLE_INC, "Apple, Inc.");
map.put(STACCATO_COMMUNICATIONS_INC , "Staccato Communications, Inc."); map.put(STACCATO_COMMUNICATIONS_INC, "Staccato Communications, Inc.");
map.put(AVAGO_TECHNOLOGIES , "Avago Technologies"); map.put(AVAGO_TECHNOLOGIES, "Avago Technologies");
map.put(APT_LICENSING_LTD , "APT Licensing Ltd."); map.put(APT_LICENSING_LTD, "APT Licensing Ltd.");
map.put(SIRF_TECHNOLOGY , "SiRF Technology"); map.put(SIRF_TECHNOLOGY, "SiRF Technology");
map.put(TZERO_TECHNOLOGIES_INC , "Tzero Technologies, Inc."); map.put(TZERO_TECHNOLOGIES_INC, "Tzero Technologies, Inc.");
map.put(JM_CORPORATION , "J&M Corporation"); map.put(JM_CORPORATION, "J&M Corporation");
map.put(FREE2MOVE_AB , "Free2move AB"); map.put(FREE2MOVE_AB, "Free2move AB");
map.put(THREE_DIJOY_CORPORATION , "3DiJoy Corporation"); map.put(THREE_DIJOY_CORPORATION, "3DiJoy Corporation");
map.put(PLANTRONICS_INC , "Plantronics, Inc."); map.put(PLANTRONICS_INC, "Plantronics, Inc.");
map.put(SONY_ERICSSON_MOBILE_COMMUNICATIONS , "Sony Ericsson Mobile Communications"); map.put(SONY_ERICSSON_MOBILE_COMMUNICATIONS, "Sony Ericsson Mobile Communications");
map.put(HARMAN_INTERNATIONAL_INDUSTRIES_INC , "Harman International Industries, Inc."); map.put(HARMAN_INTERNATIONAL_INDUSTRIES_INC, "Harman International Industries, Inc.");
map.put(VIZIO_INC , "Vizio, Inc."); map.put(VIZIO_INC, "Vizio, Inc.");
map.put(NORDIC_SEMICONDUCTOR_ASA , "Nordic Semiconductor ASA"); map.put(NORDIC_SEMICONDUCTOR_ASA, "Nordic Semiconductor ASA");
map.put(EM_MICROELECTRONICMARIN_SA , "EM Microelectronic-Marin SA"); map.put(EM_MICROELECTRONICMARIN_SA, "EM Microelectronic-Marin SA");
map.put(RALINK_TECHNOLOGY_CORPORATION , "Ralink Technology Corporation"); map.put(RALINK_TECHNOLOGY_CORPORATION, "Ralink Technology Corporation");
map.put(BELKIN_INTERNATIONAL_INC , "Belkin International, Inc."); map.put(BELKIN_INTERNATIONAL_INC, "Belkin International, Inc.");
map.put(REALTEK_SEMICONDUCTOR_CORPORATION , "Realtek Semiconductor Corporation"); map.put(REALTEK_SEMICONDUCTOR_CORPORATION, "Realtek Semiconductor Corporation");
map.put(STONESTREET_ONE_LLC , "Stonestreet One, LLC"); map.put(STONESTREET_ONE_LLC, "Stonestreet One, LLC");
map.put(WICENTRIC_INC , "Wicentric, Inc."); map.put(WICENTRIC_INC, "Wicentric, Inc.");
map.put(RIVIERAWAVES_SAS , "RivieraWaves S.A.S"); map.put(RIVIERAWAVES_SAS, "RivieraWaves S.A.S");
map.put(RDA_MICROELECTRONICS , "RDA Microelectronics"); map.put(RDA_MICROELECTRONICS, "RDA Microelectronics");
map.put(GIBSON_GUITARS , "Gibson Guitars"); map.put(GIBSON_GUITARS, "Gibson Guitars");
map.put(MICOMMAND_INC , "MiCommand Inc."); map.put(MICOMMAND_INC, "MiCommand Inc.");
map.put(BAND_XI_INTERNATIONAL_LLC , "Band XI International, LLC"); map.put(BAND_XI_INTERNATIONAL_LLC, "Band XI International, LLC");
map.put(HEWLETTPACKARD_COMPANY , "Hewlett-Packard Company"); map.put(HEWLETTPACKARD_COMPANY, "Hewlett-Packard Company");
map.put(NINE_SOLUTIONS_OY , "9Solutions Oy"); map.put(NINE_SOLUTIONS_OY, "9Solutions Oy");
map.put(GN_NETCOM_A_S , "GN Netcom A/S"); map.put(GN_NETCOM_A_S, "GN Netcom A/S");
map.put(GENERAL_MOTORS , "General Motors"); map.put(GENERAL_MOTORS, "General Motors");
map.put(AD_ENGINEERING_INC , "A&D Engineering, Inc."); map.put(AD_ENGINEERING_INC, "A&D Engineering, Inc.");
map.put(MINDTREE_LTD , "MindTree Ltd."); map.put(MINDTREE_LTD, "MindTree Ltd.");
map.put(POLAR_ELECTRO_OY , "Polar Electro OY"); map.put(POLAR_ELECTRO_OY, "Polar Electro OY");
map.put(BEAUTIFUL_ENTERPRISE_CO_LTD , "Beautiful Enterprise Co., Ltd."); map.put(BEAUTIFUL_ENTERPRISE_CO_LTD, "Beautiful Enterprise Co., Ltd.");
map.put(BRIARTEK_INC , "BriarTek, Inc."); map.put(BRIARTEK_INC, "BriarTek, Inc.");
map.put(SUMMIT_DATA_COMMUNICATIONS_INC , "Summit Data Communications, Inc."); map.put(SUMMIT_DATA_COMMUNICATIONS_INC, "Summit Data Communications, Inc.");
map.put(SOUND_ID , "Sound ID"); map.put(SOUND_ID, "Sound ID");
map.put(MONSTER_LLC , "Monster, LLC"); map.put(MONSTER_LLC, "Monster, LLC");
map.put(CONNECTBLUE_AB , "connectBlue AB"); map.put(CONNECTBLUE_AB, "connectBlue AB");
map.put(SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD , "ShangHai Super Smart Electronics Co. Ltd."); map.put(SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD, "ShangHai Super Smart Electronics Co. Ltd.");
map.put(GROUP_SENSE_LTD , "Group Sense Ltd."); map.put(GROUP_SENSE_LTD, "Group Sense Ltd.");
map.put(ZOMM_LLC , "Zomm, LLC"); map.put(ZOMM_LLC, "Zomm, LLC");
map.put(SAMSUNG_ELECTRONICS_CO_LTD , "Samsung Electronics Co. Ltd."); map.put(SAMSUNG_ELECTRONICS_CO_LTD, "Samsung Electronics Co. Ltd.");
map.put(CREATIVE_TECHNOLOGY_LTD , "Creative Technology Ltd."); map.put(CREATIVE_TECHNOLOGY_LTD, "Creative Technology Ltd.");
map.put(LAIRD_TECHNOLOGIES , "Laird Technologies"); map.put(LAIRD_TECHNOLOGIES, "Laird Technologies");
map.put(NIKE_INC , "Nike, Inc."); map.put(NIKE_INC, "Nike, Inc.");
map.put(LESSWIRE_AG , "lesswire AG"); map.put(LESSWIRE_AG, "lesswire AG");
map.put(MSTAR_SEMICONDUCTOR_INC , "MStar Semiconductor, Inc."); map.put(MSTAR_SEMICONDUCTOR_INC, "MStar Semiconductor, Inc.");
map.put(HANLYNN_TECHNOLOGIES , "Hanlynn Technologies"); map.put(HANLYNN_TECHNOLOGIES, "Hanlynn Technologies");
map.put(A_R_CAMBRIDGE , "A & R Cambridge"); map.put(A_R_CAMBRIDGE, "A & R Cambridge");
map.put(SEERS_TECHNOLOGY_CO_LTD , "Seers Technology Co. Ltd"); map.put(SEERS_TECHNOLOGY_CO_LTD, "Seers Technology Co. Ltd");
map.put(SPORTS_TRACKING_TECHNOLOGIES_LTD , "Sports Tracking Technologies Ltd."); map.put(SPORTS_TRACKING_TECHNOLOGIES_LTD, "Sports Tracking Technologies Ltd.");
map.put(AUTONET_MOBILE , "Autonet Mobile"); map.put(AUTONET_MOBILE, "Autonet Mobile");
map.put(DELORME_PUBLISHING_COMPANY_INC , "DeLorme Publishing Company, Inc."); map.put(DELORME_PUBLISHING_COMPANY_INC, "DeLorme Publishing Company, Inc.");
map.put(WUXI_VIMICRO , "WuXi Vimicro"); map.put(WUXI_VIMICRO, "WuXi Vimicro");
map.put(SENNHEISER_COMMUNICATIONS_A_S , "Sennheiser Communications A/S"); map.put(SENNHEISER_COMMUNICATIONS_A_S, "Sennheiser Communications A/S");
map.put(TIMEKEEPING_SYSTEMS_INC , "TimeKeeping Systems, Inc."); map.put(TIMEKEEPING_SYSTEMS_INC, "TimeKeeping Systems, Inc.");
map.put(LUDUS_HELSINKI_LTD , "Ludus Helsinki Ltd."); map.put(LUDUS_HELSINKI_LTD, "Ludus Helsinki Ltd.");
map.put(BLUERADIOS_INC , "BlueRadios, Inc."); map.put(BLUERADIOS_INC, "BlueRadios, Inc.");
map.put(EQUINOX_AG , "equinox AG"); map.put(EQUINOX_AG, "equinox AG");
map.put(GARMIN_INTERNATIONAL_INC , "Garmin International, Inc."); map.put(GARMIN_INTERNATIONAL_INC, "Garmin International, Inc.");
map.put(ECOTEST , "Ecotest"); map.put(ECOTEST, "Ecotest");
map.put(GN_RESOUND_A_S , "GN ReSound A/S"); map.put(GN_RESOUND_A_S, "GN ReSound A/S");
map.put(JAWBONE , "Jawbone"); map.put(JAWBONE, "Jawbone");
map.put(TOPCORN_POSITIONING_SYSTEMS_LLC , "Topcorn Positioning Systems, LLC"); map.put(TOPCORN_POSITIONING_SYSTEMS_LLC, "Topcorn Positioning Systems, LLC");
map.put(QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC , "Qualcomm Retail Solutions, Inc. (formerly Qualcomm Labs, Inc.)"); map.put(QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC, "Qualcomm Retail Solutions, Inc. (formerly Qualcomm Labs, Inc.)");
map.put(ZSCAN_SOFTWARE , "Zscan Software"); map.put(ZSCAN_SOFTWARE, "Zscan Software");
map.put(QUINTIC_CORP , "Quintic Corp."); map.put(QUINTIC_CORP, "Quintic Corp.");
map.put(STOLLMAN_EV_GMBH , "Stollman E+V GmbH"); map.put(STOLLMAN_EV_GMBH, "Stollman E+V GmbH");
map.put(FUNAI_ELECTRIC_CO_LTD , "Funai Electric Co., Ltd."); map.put(FUNAI_ELECTRIC_CO_LTD, "Funai Electric Co., Ltd.");
map.put(ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG , "Advanced PANMOBIL Systems GmbH & Co. KG"); map.put(ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG, "Advanced PANMOBIL Systems GmbH & Co. KG");
map.put(THINKOPTICS_INC , "ThinkOptics, Inc."); map.put(THINKOPTICS_INC, "ThinkOptics, Inc.");
map.put(UNIVERSAL_ELECTRONICS_INC , "Universal Electronics, Inc."); map.put(UNIVERSAL_ELECTRONICS_INC, "Universal Electronics, Inc.");
map.put(AIROHA_TECHNOLOGY_CORP , "Airoha Technology Corp."); map.put(AIROHA_TECHNOLOGY_CORP, "Airoha Technology Corp.");
map.put(NEC_LIGHTING_LTD , "NEC Lighting, Ltd."); map.put(NEC_LIGHTING_LTD, "NEC Lighting, Ltd.");
map.put(ODM_TECHNOLOGY_INC , "ODM Technology, Inc."); map.put(ODM_TECHNOLOGY_INC, "ODM Technology, Inc.");
map.put(CONNECTEDEVICE_LTD , "ConnecteDevice Ltd."); map.put(CONNECTEDEVICE_LTD, "ConnecteDevice Ltd.");
map.put(ZER01TV_GMBH , "zer01.tv GmbH"); map.put(ZER01TV_GMBH, "zer01.tv GmbH");
map.put(ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD , "i.Tech Dynamic Global Distribution Ltd."); map.put(ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD, "i.Tech Dynamic Global Distribution Ltd.");
map.put(ALPWISE , "Alpwise"); map.put(ALPWISE, "Alpwise");
map.put(JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD , "Jiangsu Toppower Automotive Electronics Co., Ltd."); map.put(JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD, "Jiangsu Toppower Automotive Electronics Co., Ltd.");
map.put(COLORFY_INC , "Colorfy, Inc."); map.put(COLORFY_INC, "Colorfy, Inc.");
map.put(GEOFORCE_INC , "Geoforce Inc."); map.put(GEOFORCE_INC, "Geoforce Inc.");
map.put(BOSE_CORPORATION , "Bose Corporation"); map.put(BOSE_CORPORATION, "Bose Corporation");
map.put(SUUNTO_OY , "Suunto Oy"); map.put(SUUNTO_OY, "Suunto Oy");
map.put(KENSINGTON_COMPUTER_PRODUCTS_GROUP , "Kensington Computer Products Group"); map.put(KENSINGTON_COMPUTER_PRODUCTS_GROUP, "Kensington Computer Products Group");
map.put(SRMEDIZINELEKTRONIK , "SR-Medizinelektronik"); map.put(SRMEDIZINELEKTRONIK, "SR-Medizinelektronik");
map.put(VERTU_CORPORATION_LIMITED , "Vertu Corporation Limited"); map.put(VERTU_CORPORATION_LIMITED, "Vertu Corporation Limited");
map.put(META_WATCH_LTD , "Meta Watch Ltd."); map.put(META_WATCH_LTD, "Meta Watch Ltd.");
map.put(LINAK_A_S , "LINAK A/S"); map.put(LINAK_A_S, "LINAK A/S");
map.put(OTL_DYNAMICS_LLC , "OTL Dynamics LLC"); map.put(OTL_DYNAMICS_LLC, "OTL Dynamics LLC");
map.put(PANDA_OCEAN_INC , "Panda Ocean Inc."); map.put(PANDA_OCEAN_INC, "Panda Ocean Inc.");
map.put(VISTEON_CORPORATION , "Visteon Corporation"); map.put(VISTEON_CORPORATION, "Visteon Corporation");
map.put(ARP_DEVICES_LIMITED , "ARP Devices Limited"); map.put(ARP_DEVICES_LIMITED, "ARP Devices Limited");
map.put(MAGNETI_MARELLI_SPA , "Magneti Marelli S.p.A"); map.put(MAGNETI_MARELLI_SPA, "Magneti Marelli S.p.A");
map.put(CAEN_RFID_SRL , "CAEN RFID srl"); map.put(CAEN_RFID_SRL, "CAEN RFID srl");
map.put(INGENIEURSYSTEMGRUPPE_ZAHN_GMBH , "Ingenieur-Systemgruppe Zahn GmbH"); map.put(INGENIEURSYSTEMGRUPPE_ZAHN_GMBH, "Ingenieur-Systemgruppe Zahn GmbH");
map.put(GREEN_THROTTLE_GAMES , "Green Throttle Games"); map.put(GREEN_THROTTLE_GAMES, "Green Throttle Games");
map.put(PETER_SYSTEMTECHNIK_GMBH , "Peter Systemtechnik GmbH"); map.put(PETER_SYSTEMTECHNIK_GMBH, "Peter Systemtechnik GmbH");
map.put(OMEGAWAVE_OY , "Omegawave Oy"); map.put(OMEGAWAVE_OY, "Omegawave Oy");
map.put(CINETIX , "Cinetix"); map.put(CINETIX, "Cinetix");
map.put(PASSIF_SEMICONDUCTOR_CORP , "Passif Semiconductor Corp"); map.put(PASSIF_SEMICONDUCTOR_CORP, "Passif Semiconductor Corp");
map.put(SARIS_CYCLING_GROUP_INC , "Saris Cycling Group, Inc"); map.put(SARIS_CYCLING_GROUP_INC, "Saris Cycling Group, Inc");
map.put(BEKEY_A_S , "Bekey A/S"); map.put(BEKEY_A_S, "Bekey A/S");
map.put(CLARINOX_TECHNOLOGIES_PTY_LTD , "Clarinox Technologies Pty. Ltd."); map.put(CLARINOX_TECHNOLOGIES_PTY_LTD, "Clarinox Technologies Pty. Ltd.");
map.put(BDE_TECHNOLOGY_CO_LTD , "BDE Technology Co., Ltd."); map.put(BDE_TECHNOLOGY_CO_LTD, "BDE Technology Co., Ltd.");
map.put(SWIRL_NETWORKS , "Swirl Networks"); map.put(SWIRL_NETWORKS, "Swirl Networks");
map.put(MESO_INTERNATIONAL , "Meso international"); map.put(MESO_INTERNATIONAL, "Meso international");
map.put(TRELAB_LTD , "TreLab Ltd"); map.put(TRELAB_LTD, "TreLab Ltd");
map.put(QUALCOMM_INNOVATION_CENTER_INC_QUIC , "Qualcomm Innovation Center, Inc. (QuIC)"); map.put(QUALCOMM_INNOVATION_CENTER_INC_QUIC, "Qualcomm Innovation Center, Inc. (QuIC)");
map.put(JOHNSON_CONTROLS_INC , "Johnson Controls, Inc."); map.put(JOHNSON_CONTROLS_INC, "Johnson Controls, Inc.");
map.put(STARKEY_LABORATORIES_INC , "Starkey Laboratories Inc."); map.put(STARKEY_LABORATORIES_INC, "Starkey Laboratories Inc.");
map.put(SPOWER_ELECTRONICS_LIMITED , "S-Power Electronics Limited"); map.put(SPOWER_ELECTRONICS_LIMITED, "S-Power Electronics Limited");
map.put(ACE_SENSOR_INC , "Ace Sensor Inc"); map.put(ACE_SENSOR_INC, "Ace Sensor Inc");
map.put(APLIX_CORPORATION , "Aplix Corporation"); map.put(APLIX_CORPORATION, "Aplix Corporation");
map.put(AAMP_OF_AMERICA , "AAMP of America"); map.put(AAMP_OF_AMERICA, "AAMP of America");
map.put(STALMART_TECHNOLOGY_LIMITED , "Stalmart Technology Limited"); map.put(STALMART_TECHNOLOGY_LIMITED, "Stalmart Technology Limited");
map.put(AMICCOM_ELECTRONICS_CORPORATION , "AMICCOM Electronics Corporation"); map.put(AMICCOM_ELECTRONICS_CORPORATION, "AMICCOM Electronics Corporation");
map.put(SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD , "Shenzhen Excelsecu Data Technology Co.,Ltd"); map.put(SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD, "Shenzhen Excelsecu Data Technology Co.,Ltd");
map.put(GENEQ_INC , "Geneq Inc."); map.put(GENEQ_INC, "Geneq Inc.");
map.put(ADIDAS_AG , "adidas AG"); map.put(ADIDAS_AG, "adidas AG");
map.put(LG_ELECTRONICS , "LG Electronics"); map.put(LG_ELECTRONICS, "LG Electronics");
map.put(ONSET_COMPUTER_CORPORATION , "Onset Computer Corporation"); map.put(ONSET_COMPUTER_CORPORATION, "Onset Computer Corporation");
map.put(SELFLY_BV , "Selfly BV"); map.put(SELFLY_BV, "Selfly BV");
map.put(QUUPPA_OY , "Quuppa Oy."); map.put(QUUPPA_OY, "Quuppa Oy.");
map.put(GELO_INC , "GeLo Inc"); map.put(GELO_INC, "GeLo Inc");
map.put(EVLUMA , "Evluma"); map.put(EVLUMA, "Evluma");
map.put(MC10 , "MC10"); map.put(MC10, "MC10");
map.put(BINAURIC_SE , "Binauric SE"); map.put(BINAURIC_SE, "Binauric SE");
map.put(BEATS_ELECTRONICS , "Beats Electronics"); map.put(BEATS_ELECTRONICS, "Beats Electronics");
map.put(MICROCHIP_TECHNOLOGY_INC , "Microchip Technology Inc."); map.put(MICROCHIP_TECHNOLOGY_INC, "Microchip Technology Inc.");
map.put(ELGATO_SYSTEMS_GMBH , "Elgato Systems GmbH"); map.put(ELGATO_SYSTEMS_GMBH, "Elgato Systems GmbH");
map.put(ARCHOS_SA , "ARCHOS SA"); map.put(ARCHOS_SA, "ARCHOS SA");
map.put(DEXCOM_INC , "Dexcom, Inc."); map.put(DEXCOM_INC, "Dexcom, Inc.");
map.put(POLAR_ELECTRO_EUROPE_BV , "Polar Electro Europe B.V."); map.put(POLAR_ELECTRO_EUROPE_BV, "Polar Electro Europe B.V.");
map.put(DIALOG_SEMICONDUCTOR_BV , "Dialog Semiconductor B.V."); map.put(DIALOG_SEMICONDUCTOR_BV, "Dialog Semiconductor B.V.");
map.put(TAIXINGBANG_TECHNOLOGY_HK_CO_LTD , "Taixingbang Technology (HK) Co,. LTD."); map.put(TAIXINGBANG_TECHNOLOGY_HK_CO_LTD, "Taixingbang Technology (HK) Co,. LTD.");
map.put(KAWANTECH , "Kawantech"); map.put(KAWANTECH, "Kawantech");
map.put(AUSTCO_COMMUNICATION_SYSTEMS , "Austco Communication Systems"); map.put(AUSTCO_COMMUNICATION_SYSTEMS, "Austco Communication Systems");
map.put(TIMEX_GROUP_USA_INC , "Timex Group USA, Inc."); map.put(TIMEX_GROUP_USA_INC, "Timex Group USA, Inc.");
map.put(QUALCOMM_TECHNOLOGIES_INC , "Qualcomm Technologies, Inc."); map.put(QUALCOMM_TECHNOLOGIES_INC, "Qualcomm Technologies, Inc.");
map.put(QUALCOMM_CONNECTED_EXPERIENCES_INC , "Qualcomm Connected Experiences, Inc."); map.put(QUALCOMM_CONNECTED_EXPERIENCES_INC, "Qualcomm Connected Experiences, Inc.");
map.put(VOYETRA_TURTLE_BEACH , "Voyetra Turtle Beach"); map.put(VOYETRA_TURTLE_BEACH, "Voyetra Turtle Beach");
map.put(TXTR_GMBH , "txtr GmbH"); map.put(TXTR_GMBH, "txtr GmbH");
map.put(BIOSENTRONICS , "Biosentronics"); map.put(BIOSENTRONICS, "Biosentronics");
map.put(PROCTER_GAMBLE , "Procter & Gamble"); map.put(PROCTER_GAMBLE, "Procter & Gamble");
map.put(HOSIDEN_CORPORATION , "Hosiden Corporation"); map.put(HOSIDEN_CORPORATION, "Hosiden Corporation");
map.put(MUZIK_LLC , "Muzik LLC"); map.put(MUZIK_LLC, "Muzik LLC");
map.put(MISFIT_WEARABLES_CORP , "Misfit Wearables Corp"); map.put(MISFIT_WEARABLES_CORP, "Misfit Wearables Corp");
map.put(GOOGLE , "Google"); map.put(GOOGLE, "Google");
map.put(DANLERS_LTD , "Danlers Ltd"); map.put(DANLERS_LTD, "Danlers Ltd");
map.put(SEMILINK_INC , "Semilink Inc"); map.put(SEMILINK_INC, "Semilink Inc");
map.put(INMUSIC_BRANDS_INC , "inMusic Brands, Inc"); map.put(INMUSIC_BRANDS_INC, "inMusic Brands, Inc");
map.put(LS_RESEARCH_INC , "L.S. Research Inc."); map.put(LS_RESEARCH_INC, "L.S. Research Inc.");
map.put(EDEN_SOFTWARE_CONSULTANTS_LTD , "Eden Software Consultants Ltd."); map.put(EDEN_SOFTWARE_CONSULTANTS_LTD, "Eden Software Consultants Ltd.");
map.put(FRESHTEMP , "Freshtemp"); map.put(FRESHTEMP, "Freshtemp");
map.put(KS_TECHNOLOGIES , "KS Technologies"); map.put(KS_TECHNOLOGIES, "KS Technologies");
map.put(ACTS_TECHNOLOGIES , "ACTS Technologies"); map.put(ACTS_TECHNOLOGIES, "ACTS Technologies");
map.put(VTRACK_SYSTEMS , "Vtrack Systems"); map.put(VTRACK_SYSTEMS, "Vtrack Systems");
map.put(NIELSENKELLERMAN_COMPANY , "Nielsen-Kellerman Company"); map.put(NIELSENKELLERMAN_COMPANY, "Nielsen-Kellerman Company");
map.put(SERVER_TECHNOLOGY_INC , "Server Technology, Inc."); map.put(SERVER_TECHNOLOGY_INC, "Server Technology, Inc.");
map.put(BIORESEARCH_ASSOCIATES , "BioResearch Associates"); map.put(BIORESEARCH_ASSOCIATES, "BioResearch Associates");
map.put(JOLLY_LOGIC_LLC , "Jolly Logic, LLC"); map.put(JOLLY_LOGIC_LLC, "Jolly Logic, LLC");
map.put(ABOVE_AVERAGE_OUTCOMES_INC , "Above Average Outcomes, Inc."); map.put(ABOVE_AVERAGE_OUTCOMES_INC, "Above Average Outcomes, Inc.");
map.put(BITSPLITTERS_GMBH , "Bitsplitters GmbH"); map.put(BITSPLITTERS_GMBH, "Bitsplitters GmbH");
map.put(PAYPAL_INC , "PayPal, Inc."); map.put(PAYPAL_INC, "PayPal, Inc.");
map.put(WITRON_TECHNOLOGY_LIMITED , "Witron Technology Limited"); map.put(WITRON_TECHNOLOGY_LIMITED, "Witron Technology Limited");
map.put(MORSE_PROJECT_INC , "Morse Project Inc."); map.put(MORSE_PROJECT_INC, "Morse Project Inc.");
map.put(KENT_DISPLAYS_INC , "Kent Displays Inc."); map.put(KENT_DISPLAYS_INC, "Kent Displays Inc.");
map.put(NAUTILUS_INC , "Nautilus Inc."); map.put(NAUTILUS_INC, "Nautilus Inc.");
map.put(SMARTIFIER_OY , "Smartifier Oy"); map.put(SMARTIFIER_OY, "Smartifier Oy");
map.put(ELCOMETER_LIMITED , "Elcometer Limited"); map.put(ELCOMETER_LIMITED, "Elcometer Limited");
map.put(VSN_TECHNOLOGIES_INC , "VSN Technologies Inc."); map.put(VSN_TECHNOLOGIES_INC, "VSN Technologies Inc.");
map.put(ACEUNI_CORP_LTD , "AceUni Corp., Ltd."); map.put(ACEUNI_CORP_LTD, "AceUni Corp., Ltd.");
map.put(STICKNFIND , "StickNFind"); map.put(STICKNFIND, "StickNFind");
map.put(CRYSTAL_CODE_AB , "Crystal Code AB"); map.put(CRYSTAL_CODE_AB, "Crystal Code AB");
map.put(KOUKAAM_AS , "KOUKAAM a.s."); map.put(KOUKAAM_AS, "KOUKAAM a.s.");
map.put(DELPHI_CORPORATION , "Delphi Corporation"); map.put(DELPHI_CORPORATION, "Delphi Corporation");
map.put(VALENCETECH_LIMITED , "ValenceTech Limited"); map.put(VALENCETECH_LIMITED, "ValenceTech Limited");
map.put(RESERVED , "Reserved"); map.put(RESERVED, "Reserved");
map.put(TYPO_PRODUCTS_LLC , "Typo Products, LLC"); map.put(TYPO_PRODUCTS_LLC, "Typo Products, LLC");
map.put(TOMTOM_INTERNATIONAL_BV , "TomTom International BV"); map.put(TOMTOM_INTERNATIONAL_BV, "TomTom International BV");
map.put(FUGOO_INC , "Fugoo, Inc"); map.put(FUGOO_INC, "Fugoo, Inc");
map.put(KEISER_CORPORATION , "Keiser Corporation"); map.put(KEISER_CORPORATION, "Keiser Corporation");
map.put(BANG_OLUFSEN_A_S , "Bang & Olufsen A/S"); map.put(BANG_OLUFSEN_A_S, "Bang & Olufsen A/S");
map.put(PLUS_LOCATIONS_SYSTEMS_PTY_LTD , "PLUS Locations Systems Pty Ltd"); map.put(PLUS_LOCATIONS_SYSTEMS_PTY_LTD, "PLUS Locations Systems Pty Ltd");
map.put(UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION , "Ubiquitous Computing Technology Corporation"); map.put(UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION, "Ubiquitous Computing Technology Corporation");
map.put(INNOVATIVE_YACHTTER_SOLUTIONS , "Innovative Yachtter Solutions"); map.put(INNOVATIVE_YACHTTER_SOLUTIONS, "Innovative Yachtter Solutions");
map.put(WILLIAM_DEMANT_HOLDING_A_S , "William Demant Holding A/S"); map.put(WILLIAM_DEMANT_HOLDING_A_S, "William Demant Holding A/S");
map.put(CHICONY_ELECTRONICS_CO_LTD , "Chicony Electronics Co., Ltd."); map.put(CHICONY_ELECTRONICS_CO_LTD, "Chicony Electronics Co., Ltd.");
map.put(ATUS_BV , "Atus BV"); map.put(ATUS_BV, "Atus BV");
map.put(CODEGATE_LTD , "Codegate Ltd."); map.put(CODEGATE_LTD, "Codegate Ltd.");
map.put(ERI_INC , "ERi, Inc."); map.put(ERI_INC, "ERi, Inc.");
map.put(TRANSDUCERS_DIRECT_LLC , "Transducers Direct, LLC"); map.put(TRANSDUCERS_DIRECT_LLC, "Transducers Direct, LLC");
map.put(FUJITSU_TEN_LIMITED , "Fujitsu Ten Limited"); map.put(FUJITSU_TEN_LIMITED, "Fujitsu Ten Limited");
map.put(AUDI_AG , "Audi AG"); map.put(AUDI_AG, "Audi AG");
map.put(HISILICON_TECHNOLOGIES_CO_LTD , "HiSilicon Technologies Co., Ltd."); map.put(HISILICON_TECHNOLOGIES_CO_LTD, "HiSilicon Technologies Co., Ltd.");
map.put(NIPPON_SEIKI_CO_LTD , "Nippon Seiki Co., Ltd."); map.put(NIPPON_SEIKI_CO_LTD, "Nippon Seiki Co., Ltd.");
map.put(STEELSERIES_APS , "Steelseries ApS"); map.put(STEELSERIES_APS, "Steelseries ApS");
map.put(VYZYBL_INC , "vyzybl Inc."); map.put(VYZYBL_INC, "vyzybl Inc.");
map.put(OPENBRAIN_TECHNOLOGIES_CO_LTD , "Openbrain Technologies, Co., Ltd."); map.put(OPENBRAIN_TECHNOLOGIES_CO_LTD, "Openbrain Technologies, Co., Ltd.");
map.put(XENSR , "Xensr"); map.put(XENSR, "Xensr");
map.put(ESOLUTIONS , "e.solutions"); map.put(ESOLUTIONS, "e.solutions");
map.put(ONE_OAK_TECHNOLOGIES , "1OAK Technologies"); map.put(ONE_OAK_TECHNOLOGIES, "1OAK Technologies");
map.put(WIMOTO_TECHNOLOGIES_INC , "Wimoto Technologies Inc"); map.put(WIMOTO_TECHNOLOGIES_INC, "Wimoto Technologies Inc");
map.put(RADIUS_NETWORKS_INC , "Radius Networks, Inc."); map.put(RADIUS_NETWORKS_INC, "Radius Networks, Inc.");
map.put(WIZE_TECHNOLOGY_CO_LTD , "Wize Technology Co., Ltd."); map.put(WIZE_TECHNOLOGY_CO_LTD, "Wize Technology Co., Ltd.");
map.put(QUALCOMM_LABS_INC , "Qualcomm Labs, Inc."); map.put(QUALCOMM_LABS_INC, "Qualcomm Labs, Inc.");
map.put(ARUBA_NETWORKS , "Aruba Networks"); map.put(ARUBA_NETWORKS, "Aruba Networks");
map.put(BAIDU , "Baidu"); map.put(BAIDU, "Baidu");
map.put(ARENDI_AG , "Arendi AG"); map.put(ARENDI_AG, "Arendi AG");
map.put(SKODA_AUTO_AS , "Skoda Auto a.s."); map.put(SKODA_AUTO_AS, "Skoda Auto a.s.");
map.put(VOLKSWAGON_AG , "Volkswagon AG"); map.put(VOLKSWAGON_AG, "Volkswagon AG");
map.put(PORSCHE_AG , "Porsche AG"); map.put(PORSCHE_AG, "Porsche AG");
map.put(SINO_WEALTH_ELECTRONIC_LTD , "Sino Wealth Electronic Ltd."); map.put(SINO_WEALTH_ELECTRONIC_LTD, "Sino Wealth Electronic Ltd.");
map.put(AIRTURN_INC , "AirTurn, Inc."); map.put(AIRTURN_INC, "AirTurn, Inc.");
map.put(KINSA_INC , "Kinsa, Inc."); map.put(KINSA_INC, "Kinsa, Inc.");
map.put(HID_GLOBAL , "HID Global"); map.put(HID_GLOBAL, "HID Global");
map.put(SEAT_ES , "SEAT es"); map.put(SEAT_ES, "SEAT es");
map.put(PROMETHEAN_LTD , "Promethean Ltd."); map.put(PROMETHEAN_LTD, "Promethean Ltd.");
map.put(SALUTICA_ALLIED_SOLUTIONS , "Salutica Allied Solutions"); map.put(SALUTICA_ALLIED_SOLUTIONS, "Salutica Allied Solutions");
map.put(GPSI_GROUP_PTY_LTD , "GPSI Group Pty Ltd"); map.put(GPSI_GROUP_PTY_LTD, "GPSI Group Pty Ltd");
map.put(NIMBLE_DEVICES_OY , "Nimble Devices Oy"); map.put(NIMBLE_DEVICES_OY, "Nimble Devices Oy");
map.put(CHANGZHOU_YONGSE_INFOTECH_CO_LTD , "Changzhou Yongse Infotech Co., Ltd"); map.put(CHANGZHOU_YONGSE_INFOTECH_CO_LTD, "Changzhou Yongse Infotech Co., Ltd");
map.put(SPORTIQ , "SportIQ"); map.put(SPORTIQ, "SportIQ");
map.put(TEMEC_INSTRUMENTS_BV , "TEMEC Instruments B.V."); map.put(TEMEC_INSTRUMENTS_BV, "TEMEC Instruments B.V.");
map.put(SONY_CORPORATION , "Sony Corporation"); map.put(SONY_CORPORATION, "Sony Corporation");
map.put(ASSA_ABLOY , "ASSA ABLOY"); map.put(ASSA_ABLOY, "ASSA ABLOY");
map.put(CLARION_CO_LTD , "Clarion Co., Ltd."); map.put(CLARION_CO_LTD, "Clarion Co., Ltd.");
map.put(WAREHOUSE_INNOVATIONS , "Warehouse Innovations"); map.put(WAREHOUSE_INNOVATIONS, "Warehouse Innovations");
map.put(CYPRESS_SEMICONDUCTOR_CORPORATION , "Cypress Semiconductor Corporation"); map.put(CYPRESS_SEMICONDUCTOR_CORPORATION, "Cypress Semiconductor Corporation");
map.put(MADS_INC , "MADS Inc"); map.put(MADS_INC, "MADS Inc");
map.put(BLUE_MAESTRO_LIMITED , "Blue Maestro Limited"); map.put(BLUE_MAESTRO_LIMITED, "Blue Maestro Limited");
map.put(RESOLUTION_PRODUCTS_INC , "Resolution Products, Inc."); map.put(RESOLUTION_PRODUCTS_INC, "Resolution Products, Inc.");
map.put(AIREWEAR_LLC , "Airewear LLC"); map.put(AIREWEAR_LLC, "Airewear LLC");
map.put(ETC_SP_ZOO , "ETC sp. z.o.o."); map.put(ETC_SP_ZOO, "ETC sp. z.o.o.");
map.put(PRESTIGIO_PLAZA_LTD , "Prestigio Plaza Ltd."); map.put(PRESTIGIO_PLAZA_LTD, "Prestigio Plaza Ltd.");
return map; return map;
} }
@@ -5,14 +5,12 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
/** /**
*
* The UUIDS have been collected from the following sources: * The UUIDS have been collected from the following sources:
* * <p/>
* - http://developer.nokia.com/community/wiki/Bluetooth_Services_for_Windows_Phone * - http://developer.nokia.com/community/wiki/Bluetooth_Services_for_Windows_Phone
* - The Bluez project * - The Bluez project
* *
* @author Alexandros Schillings * @author Alexandros Schillings
*
*/ */
public class GattAttributeResolver { public class GattAttributeResolver {
public static final String BASE_GUID = "00000001-0000-1000-8000-00805f9b34fb"; public static final String BASE_GUID = "00000001-0000-1000-8000-00805f9b34fb";
@@ -192,10 +190,9 @@ public class GattAttributeResolver {
public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d"; public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d";
private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap(); private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap();
public static String getAttributeName(final String uuid, final String fallback){ public static String getAttributeName(final String uuid, final String fallback) {
final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US)); final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US));
return name == null ? fallback : name; return name == null ? fallback : name;
} }
@@ -203,182 +200,181 @@ public class GattAttributeResolver {
private static Map<String, String> populateGattAttributesMap() { private static Map<String, String> populateGattAttributesMap() {
final Map<String, String> map = new HashMap<String, String>(); final Map<String, String> map = new HashMap<String, String>();
map.put(BASE_GUID , "Service Discovery Protocol (SDP)"); map.put(BASE_GUID, "Service Discovery Protocol (SDP)");
map.put(SERVICE_DISCOVERY_PROTOCOL_SDP , "User Datagram Protocol (UDP)"); map.put(SERVICE_DISCOVERY_PROTOCOL_SDP, "User Datagram Protocol (UDP)");
map.put(USER_DATAGRAM_PROTOCOL_UDP , "Radio Frequency Communication Protocol (RFCOMM)"); map.put(USER_DATAGRAM_PROTOCOL_UDP, "Radio Frequency Communication Protocol (RFCOMM)");
map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM , "TCP"); map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM, "TCP");
map.put(TCP , "TCSBIN"); map.put(TCP, "TCSBIN");
map.put(TCSBIN , "TCSAT"); map.put(TCSBIN, "TCSAT");
map.put(TCSAT , "Object Exchange Protocol (OBEX)"); map.put(TCSAT, "Object Exchange Protocol (OBEX)");
map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX , "IP"); map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX, "IP");
map.put(IP , "FTP"); map.put(IP, "FTP");
map.put(FTP , "HTTP"); map.put(FTP, "HTTP");
map.put(HTTP , "WSP"); map.put(HTTP, "WSP");
map.put(WSP , "BNEP_SVC"); map.put(WSP, "BNEP_SVC");
map.put(BNEP_SVC , "UPNP Protocol"); map.put(BNEP_SVC, "UPNP Protocol");
map.put(UPNP_PROTOCOL , "HIDP"); map.put(UPNP_PROTOCOL, "HIDP");
map.put(HIDP , "Hardcopy Control Channel Protocol"); map.put(HIDP, "Hardcopy Control Channel Protocol");
map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL , "Hardcopy Data Channel Protocol"); map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL, "Hardcopy Data Channel Protocol");
map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL , "Hardcopy Notification Protocol"); map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL, "Hardcopy Notification Protocol");
map.put(HARDCOPY_NOTIFICATION_PROTOCOL , "VCTP Protocol"); map.put(HARDCOPY_NOTIFICATION_PROTOCOL, "VCTP Protocol");
map.put(VCTP_PROTOCOL , "VDTP Protocol"); map.put(VCTP_PROTOCOL, "VDTP Protocol");
map.put(VDTP_PROTOCOL , "CMPT Protocol"); map.put(VDTP_PROTOCOL, "CMPT Protocol");
map.put(CMPT_PROTOCOL , "UDI C Plane Protocol"); map.put(CMPT_PROTOCOL, "UDI C Plane Protocol");
map.put(UDI_C_PLANE_PROTOCOL , "MCAP Control Channel"); map.put(UDI_C_PLANE_PROTOCOL, "MCAP Control Channel");
map.put(MCAP_CONTROL_CHANNEL , "MCAP Data Channel"); map.put(MCAP_CONTROL_CHANNEL, "MCAP Data Channel");
map.put(MCAP_DATA_CHANNEL , "L2CAP"); map.put(MCAP_DATA_CHANNEL, "L2CAP");
map.put(L2CAP , "Service Discovery Server"); map.put(L2CAP, "Service Discovery Server");
map.put(SERVICE_DISCOVERY_SERVER , "Browse Group Descriptor"); map.put(SERVICE_DISCOVERY_SERVER, "Browse Group Descriptor");
map.put(BROWSE_GROUP_DESCRIPTOR , "Public Browse Group"); map.put(BROWSE_GROUP_DESCRIPTOR, "Public Browse Group");
map.put(PUBLIC_BROWSE_GROUP , "SPP"); map.put(PUBLIC_BROWSE_GROUP, "SPP");
map.put(SPP , "LAN Access Using PPP"); map.put(SPP, "LAN Access Using PPP");
map.put(LAN_ACCESS_USING_PPP , "DUN_GW"); map.put(LAN_ACCESS_USING_PPP, "DUN_GW");
map.put(DUN_GW , "OBEX_SYNC"); map.put(DUN_GW, "OBEX_SYNC");
map.put(OBEX_SYNC , "OBEX Object Push"); map.put(OBEX_SYNC, "OBEX Object Push");
map.put(OBEX_OBJECT_PUSH , "OBEX File Transfer"); map.put(OBEX_OBJECT_PUSH, "OBEX File Transfer");
map.put(OBEX_FILE_TRANSFER , "IrMC Sync Command"); map.put(OBEX_FILE_TRANSFER, "IrMC Sync Command");
map.put(IRMC_SYNC_COMMAND , "HSP_HS"); map.put(IRMC_SYNC_COMMAND, "HSP_HS");
map.put(HSP_HS , "Cordless Telephony"); map.put(HSP_HS, "Cordless Telephony");
map.put(CORDLESS_TELEPHONY , "Audio Source"); map.put(CORDLESS_TELEPHONY, "Audio Source");
map.put(AUDIO_SOURCE , "Audio Sink"); map.put(AUDIO_SOURCE, "Audio Sink");
map.put(AUDIO_SINK , "AV Remote Control Target"); map.put(AUDIO_SINK, "AV Remote Control Target");
map.put(AV_REMOTE_CONTROL_TARGET , "ADVANCED_AUDIO"); map.put(AV_REMOTE_CONTROL_TARGET, "ADVANCED_AUDIO");
map.put(ADVANCED_AUDIO , "AVRCP_REMOTE"); map.put(ADVANCED_AUDIO, "AVRCP_REMOTE");
map.put(AVRCP_REMOTE , "Video Conferencing"); map.put(AVRCP_REMOTE, "Video Conferencing");
map.put(VIDEO_CONFERENCING , "Intercom"); map.put(VIDEO_CONFERENCING, "Intercom");
map.put(INTERCOM , "FAX"); map.put(INTERCOM, "FAX");
map.put(FAX , "Headset Profile (HSP) - Audio Gateway"); map.put(FAX, "Headset Profile (HSP) - Audio Gateway");
map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY , "WAP"); map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY, "WAP");
map.put(WAP , "WAP Client"); map.put(WAP, "WAP Client");
map.put(WAP_CLIENT , "PANU"); map.put(WAP_CLIENT, "PANU");
map.put(PANU , "NAP"); map.put(PANU, "NAP");
map.put(NAP , "GN"); map.put(NAP, "GN");
map.put(GN , "Direct Printing"); map.put(GN, "Direct Printing");
map.put(DIRECT_PRINTING , "Reference Printing"); map.put(DIRECT_PRINTING, "Reference Printing");
map.put(REFERENCE_PRINTING , "Imaging"); map.put(REFERENCE_PRINTING, "Imaging");
map.put(IMAGING , "Imaging Responder"); map.put(IMAGING, "Imaging Responder");
map.put(IMAGING_RESPONDER , "Imaging Automatic Archive"); map.put(IMAGING_RESPONDER, "Imaging Automatic Archive");
map.put(IMAGING_AUTOMATIC_ARCHIVE , "Imaging Reference Objects"); map.put(IMAGING_AUTOMATIC_ARCHIVE, "Imaging Reference Objects");
map.put(IMAGING_REFERENCE_OBJECTS , "Hands Free Profile (HFP)"); map.put(IMAGING_REFERENCE_OBJECTS, "Hands Free Profile (HFP)");
map.put(HANDS_FREE_PROFILE_HFP , "Hands Free Profile (HFP) – Audio Gateway"); map.put(HANDS_FREE_PROFILE_HFP, "Hands Free Profile (HFP) – Audio Gateway");
map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY , "Direct Printing Reference Objects"); map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY, "Direct Printing Reference Objects");
map.put(DIRECT_PRINTING_REFERENCE_OBJECTS , "Reflected UI"); map.put(DIRECT_PRINTING_REFERENCE_OBJECTS, "Reflected UI");
map.put(REFLECTED_UI , "Basic Printing"); map.put(REFLECTED_UI, "Basic Printing");
map.put(BASIC_PRINTING , "Printing Status"); map.put(BASIC_PRINTING, "Printing Status");
map.put(PRINTING_STATUS , "HID"); map.put(PRINTING_STATUS, "HID");
map.put(HID , "Hardcopy Cable Replacement"); map.put(HID, "Hardcopy Cable Replacement");
map.put(HARDCOPY_CABLE_REPLACEMENT , "HCR Print"); map.put(HARDCOPY_CABLE_REPLACEMENT, "HCR Print");
map.put(HCR_PRINT , "HCR Scan"); map.put(HCR_PRINT, "HCR Scan");
map.put(HCR_SCAN , "Common ISDN Access"); map.put(HCR_SCAN, "Common ISDN Access");
map.put(COMMON_ISDN_ACCESS , "Video Conferencing Gateway"); map.put(COMMON_ISDN_ACCESS, "Video Conferencing Gateway");
map.put(VIDEO_CONFERENCING_GATEWAY , "UDIMT"); map.put(VIDEO_CONFERENCING_GATEWAY, "UDIMT");
map.put(UDIMT , "UDITA"); map.put(UDIMT, "UDITA");
map.put(UDITA , "Audio Video"); map.put(UDITA, "Audio Video");
map.put(AUDIO_VIDEO , "SIM Access"); map.put(AUDIO_VIDEO, "SIM Access");
map.put(SIM_ACCESS , "OBEX PCE"); map.put(SIM_ACCESS, "OBEX PCE");
map.put(OBEX_PCE , "OBEX PSE"); map.put(OBEX_PCE, "OBEX PSE");
map.put(OBEX_PSE , "OBEX PBAP"); map.put(OBEX_PSE, "OBEX PBAP");
map.put(OBEX_PBAP , "OBEX MAS"); map.put(OBEX_PBAP, "OBEX MAS");
map.put(OBEX_MAS , "OBEX MNS"); map.put(OBEX_MAS, "OBEX MNS");
map.put(OBEX_MNS , "OBEX MAP"); map.put(OBEX_MNS, "OBEX MAP");
map.put(OBEX_MAP , "PNP"); map.put(OBEX_MAP, "PNP");
map.put(PNP , "Generic Networking"); map.put(PNP, "Generic Networking");
map.put(GENERIC_NETWORKING , "Generic File Transfer"); map.put(GENERIC_NETWORKING, "Generic File Transfer");
map.put(GENERIC_FILE_TRANSFER , "Generic Audio"); map.put(GENERIC_FILE_TRANSFER, "Generic Audio");
map.put(GENERIC_AUDIO , "Generic Telephony"); map.put(GENERIC_AUDIO, "Generic Telephony");
map.put(GENERIC_TELEPHONY , "UPNP"); map.put(GENERIC_TELEPHONY, "UPNP");
map.put(UPNP , "UPNP IP"); map.put(UPNP, "UPNP IP");
map.put(UPNP_IP , "ESDP UPnP IP PAN"); map.put(UPNP_IP, "ESDP UPnP IP PAN");
map.put(ESDP_UPNP_IP_PAN , "ESDP UPnP IP LAP"); map.put(ESDP_UPNP_IP_PAN, "ESDP UPnP IP LAP");
map.put(ESDP_UPNP_IP_LAP , "ESDP Upnp L2CAP"); map.put(ESDP_UPNP_IP_LAP, "ESDP Upnp L2CAP");
map.put(ESDP_UPNP_L2CAP , "Video Distribution Profile (VDP) - Source"); map.put(ESDP_UPNP_L2CAP, "Video Distribution Profile (VDP) - Source");
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE , "Video Distribution Profile (VDP) - Sink"); map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE, "Video Distribution Profile (VDP) - Sink");
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK , "Video Distribution Profile (VDP)"); map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK, "Video Distribution Profile (VDP)");
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP , "Health Device Profile (HDP)"); map.put(VIDEO_DISTRIBUTION_PROFILE_VDP, "Health Device Profile (HDP)");
map.put(HEALTH_DEVICE_PROFILE_HDP , "Health Device Profile (HDP) - Source"); map.put(HEALTH_DEVICE_PROFILE_HDP, "Health Device Profile (HDP) - Source");
map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE , "Health Device Profile (HDP) - Sink"); map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE, "Health Device Profile (HDP) - Sink");
map.put(HEALTH_DEVICE_PROFILE_HDP_SINK , "GAP"); map.put(HEALTH_DEVICE_PROFILE_HDP_SINK, "GAP");
map.put(GAP , "GATT"); map.put(GAP, "GATT");
map.put(GATT , "IMMEDIATE_ALERT"); map.put(GATT, "IMMEDIATE_ALERT");
map.put(IMMEDIATE_ALERT , "LINK_LOSS"); map.put(IMMEDIATE_ALERT, "LINK_LOSS");
map.put(LINK_LOSS , "TX_POWER"); map.put(LINK_LOSS, "TX_POWER");
map.put(TX_POWER , "Health Thermometer"); map.put(TX_POWER, "Health Thermometer");
map.put(HEALTH_THERMOMETER , "Device Information"); map.put(HEALTH_THERMOMETER, "Device Information");
map.put(DEVICE_INFORMATION , "HEART_RATE"); map.put(DEVICE_INFORMATION, "HEART_RATE");
map.put(HEART_RATE , "CYCLING_SC"); map.put(HEART_RATE, "CYCLING_SC");
map.put(CYCLING_SC , "CLIENT_CHARACTERISTIC_CONFIG"); map.put(CYCLING_SC, "CLIENT_CHARACTERISTIC_CONFIG");
map.put(CLIENT_CHARACTERISTIC_CONFIG , "Device Name"); map.put(CLIENT_CHARACTERISTIC_CONFIG, "Device Name");
map.put(DEVICE_NAME , "Appearance"); map.put(DEVICE_NAME, "Appearance");
map.put(APPEARANCE , "Peripheral Privacy Flag"); map.put(APPEARANCE, "Peripheral Privacy Flag");
map.put(PERIPHERAL_PRIVACY_FLAG , "Reconnection Address"); map.put(PERIPHERAL_PRIVACY_FLAG, "Reconnection Address");
map.put(RECONNECTION_ADDRESS , "Peripheral Preferred Connection Parameters"); map.put(RECONNECTION_ADDRESS, "Peripheral Preferred Connection Parameters");
map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS , "Service Changed"); map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS, "Service Changed");
map.put(SERVICE_CHANGED , "Alert Level"); map.put(SERVICE_CHANGED, "Alert Level");
map.put(ALERT_LEVEL , "Tx Power Level"); map.put(ALERT_LEVEL, "Tx Power Level");
map.put(TX_POWER_LEVEL , "Date Time"); map.put(TX_POWER_LEVEL, "Date Time");
map.put(DATE_TIME , "Day of Week"); map.put(DATE_TIME, "Day of Week");
map.put(DAY_OF_WEEK , "Day Date Time"); map.put(DAY_OF_WEEK, "Day Date Time");
map.put(DAY_DATE_TIME , "Exact Time 256"); map.put(DAY_DATE_TIME, "Exact Time 256");
map.put(EXACT_TIME_256 , "DST Offset"); map.put(EXACT_TIME_256, "DST Offset");
map.put(DST_OFFSET , "Time Zone"); map.put(DST_OFFSET, "Time Zone");
map.put(TIME_ZONE , "Local Time Information"); map.put(TIME_ZONE, "Local Time Information");
map.put(LOCAL_TIME_INFORMATION , "Time with DST"); map.put(LOCAL_TIME_INFORMATION, "Time with DST");
map.put(TIME_WITH_DST , "Time Accuracy"); map.put(TIME_WITH_DST, "Time Accuracy");
map.put(TIME_ACCURACY , "Time Source"); map.put(TIME_ACCURACY, "Time Source");
map.put(TIME_SOURCE , "Reference Time Information"); map.put(TIME_SOURCE, "Reference Time Information");
map.put(REFERENCE_TIME_INFORMATION , "Time Update Control Point"); map.put(REFERENCE_TIME_INFORMATION, "Time Update Control Point");
map.put(TIME_UPDATE_CONTROL_POINT , "Time Update State"); map.put(TIME_UPDATE_CONTROL_POINT, "Time Update State");
map.put(TIME_UPDATE_STATE , "Temperature Measurement"); map.put(TIME_UPDATE_STATE, "Temperature Measurement");
map.put(TEMPERATURE_MEASUREMENT , "Temperature Type"); map.put(TEMPERATURE_MEASUREMENT, "Temperature Type");
map.put(TEMPERATURE_TYPE , "Intermediate Temperature"); map.put(TEMPERATURE_TYPE, "Intermediate Temperature");
map.put(INTERMEDIATE_TEMPERATURE , "Measurement Interval"); map.put(INTERMEDIATE_TEMPERATURE, "Measurement Interval");
map.put(MEASUREMENT_INTERVAL , "System ID"); map.put(MEASUREMENT_INTERVAL, "System ID");
map.put(SYSTEM_ID , "Model Number String"); map.put(SYSTEM_ID, "Model Number String");
map.put(MODEL_NUMBER_STRING , "Serial Number String"); map.put(MODEL_NUMBER_STRING, "Serial Number String");
map.put(SERIAL_NUMBER_STRING , "Firmware Revision String"); map.put(SERIAL_NUMBER_STRING, "Firmware Revision String");
map.put(FIRMWARE_REVISION_STRING , "Hardware Revision String"); map.put(FIRMWARE_REVISION_STRING, "Hardware Revision String");
map.put(HARDWARE_REVISION_STRING , "Software Revision String"); map.put(HARDWARE_REVISION_STRING, "Software Revision String");
map.put(SOFTWARE_REVISION_STRING , "Manufacturer Name String"); map.put(SOFTWARE_REVISION_STRING, "Manufacturer Name String");
map.put(MANUFACTURER_NAME_STRING , "IEEE 11073-20601 Regulatory"); map.put(MANUFACTURER_NAME_STRING, "IEEE 11073-20601 Regulatory");
map.put(IEEE_1107320601_REGULATORY , "Current Time"); map.put(IEEE_1107320601_REGULATORY, "Current Time");
map.put(CURRENT_TIME , "Blood Pressure Measurement"); map.put(CURRENT_TIME, "Blood Pressure Measurement");
map.put(BLOOD_PRESSURE_MEASUREMENT , "Intermediate Cuff Pressure"); map.put(BLOOD_PRESSURE_MEASUREMENT, "Intermediate Cuff Pressure");
map.put(INTERMEDIATE_CUFF_PRESSURE , "Heart Rate Measurement"); map.put(INTERMEDIATE_CUFF_PRESSURE, "Heart Rate Measurement");
map.put(HEART_RATE_MEASUREMENT , "Body Sensor Location"); map.put(HEART_RATE_MEASUREMENT, "Body Sensor Location");
map.put(BODY_SENSOR_LOCATION , "Heart Rate Control Point"); map.put(BODY_SENSOR_LOCATION, "Heart Rate Control Point");
map.put(HEART_RATE_CONTROL_POINT , "Alert Status"); map.put(HEART_RATE_CONTROL_POINT, "Alert Status");
map.put(ALERT_STATUS , "Ringer Control Point"); map.put(ALERT_STATUS, "Ringer Control Point");
map.put(RINGER_CONTROL_POINT , "Ringer Setting"); map.put(RINGER_CONTROL_POINT, "Ringer Setting");
map.put(RINGER_SETTING , "Alert Category ID Bit Mask"); map.put(RINGER_SETTING, "Alert Category ID Bit Mask");
map.put(ALERT_CATEGORY_ID_BIT_MASK , "Alert Category ID"); map.put(ALERT_CATEGORY_ID_BIT_MASK, "Alert Category ID");
map.put(ALERT_CATEGORY_ID , "Alert Notification Control Point"); map.put(ALERT_CATEGORY_ID, "Alert Notification Control Point");
map.put(ALERT_NOTIFICATION_CONTROL_POINT , "Unread Alert Status"); map.put(ALERT_NOTIFICATION_CONTROL_POINT, "Unread Alert Status");
map.put(UNREAD_ALERT_STATUS , "New Alert"); map.put(UNREAD_ALERT_STATUS, "New Alert");
map.put(NEW_ALERT , "Supported New Alert Category"); map.put(NEW_ALERT, "Supported New Alert Category");
map.put(SUPPORTED_NEW_ALERT_CATEGORY , "Supported Unread Alert Category"); map.put(SUPPORTED_NEW_ALERT_CATEGORY, "Supported Unread Alert Category");
map.put(SUPPORTED_UNREAD_ALERT_CATEGORY , "Blood Pressure Feature"); map.put(SUPPORTED_UNREAD_ALERT_CATEGORY, "Blood Pressure Feature");
map.put(BLOOD_PRESSURE_FEATURE , "PNPID"); map.put(BLOOD_PRESSURE_FEATURE, "PNPID");
map.put(PNPID , "SC_CONTROL_POINT"); map.put(PNPID, "SC_CONTROL_POINT");
map.put(SC_CONTROL_POINT , "CSC_MEASUREMENT"); map.put(SC_CONTROL_POINT, "CSC_MEASUREMENT");
map.put(CSC_MEASUREMENT , "CSC_FEATURE"); map.put(CSC_MEASUREMENT, "CSC_FEATURE");
map.put(CSC_FEATURE , "SENSOR_LOCATION"); map.put(CSC_FEATURE, "SENSOR_LOCATION");
map.put(SENSOR_LOCATION , "ActiveSync"); map.put(SENSOR_LOCATION, "ActiveSync");
map.put(ACTIVESYNC , "ActiveSync"); map.put(ACTIVESYNC, "ActiveSync");
map.put(ESTIMOTE_SERVICE , "Estimote Service"); map.put(ESTIMOTE_SERVICE, "Estimote Service");
map.put(ESTIMOTE_UUID , "Estimote UUID"); map.put(ESTIMOTE_UUID, "Estimote UUID");
map.put(ESTIMOTE_MAJOR , "Estimote Major"); map.put(ESTIMOTE_MAJOR, "Estimote Major");
map.put(ESTIMOTE_MINOR , "Estimote Minor"); map.put(ESTIMOTE_MINOR, "Estimote Minor");
map.put(ESTIMOTE_BATTERY , "Estimote Battery"); map.put(ESTIMOTE_BATTERY, "Estimote Battery");
map.put(ESTIMOTE_TEMPERATURE , "Estimote Temperature"); map.put(ESTIMOTE_TEMPERATURE, "Estimote Temperature");
map.put(ESTIMOTE_POWER , "Estimote Power"); map.put(ESTIMOTE_POWER, "Estimote Power");
map.put(ESTIMOTE_ADVERTISING_INTERVAL , "Estimote Advertising Interval"); map.put(ESTIMOTE_ADVERTISING_INTERVAL, "Estimote Advertising Interval");
map.put(ESTIMOTE_VERSION_SERVICE , "Estimote Version Service"); map.put(ESTIMOTE_VERSION_SERVICE, "Estimote Version Service");
map.put(ESTIMOTE_SOFTWARE_VERSION , "Estimote Software Version"); map.put(ESTIMOTE_SOFTWARE_VERSION, "Estimote Software Version");
map.put(ESTIMOTE_HARDWARE_VERSION , "Estimote Hardware Version"); map.put(ESTIMOTE_HARDWARE_VERSION, "Estimote Hardware Version");
map.put(ESTIMOTE_AUTHENTICATION_SERVICE , "Estimote Authentication Service"); map.put(ESTIMOTE_AUTHENTICATION_SERVICE, "Estimote Authentication Service");
map.put(ESTIMOTE_ADVERTISING_SEED , "Estimote Advertising Seed"); map.put(ESTIMOTE_ADVERTISING_SEED, "Estimote Advertising Seed");
map.put(ESTIMOTE_ADVERTISING_VECTOR , "Estimote Advertising Vector"); map.put(ESTIMOTE_ADVERTISING_VECTOR, "Estimote Advertising Vector");
return map; return map;
@@ -1,5 +1,8 @@
package uk.co.alt236.bluetoothlelib.util; package uk.co.alt236.bluetoothlelib.util;
import android.annotation.SuppressLint;
import android.util.SparseArray;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@@ -8,18 +11,20 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord; import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
import android.annotation.SuppressLint;
import android.util.SparseArray;
public class AdRecordUtils { public class AdRecordUtils {
public static String getRecordDataAsString(final AdRecord nameRecord) { public static String getRecordDataAsString(final AdRecord nameRecord) {
if(nameRecord == null){return "";} if (nameRecord == null) {
return "";
}
return new String(nameRecord.getData()); return new String(nameRecord.getData());
} }
public static byte[] getServiceData(final AdRecord serviceData) { public static byte[] getServiceData(final AdRecord serviceData) {
if (serviceData == null) {return null;} if (serviceData == null) {
return null;
}
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return null; if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return null;
final byte[] raw = serviceData.getData(); final byte[] raw = serviceData.getData();
@@ -28,7 +33,9 @@ public class AdRecordUtils {
} }
public static int getServiceDataUuid(final AdRecord serviceData) { public static int getServiceDataUuid(final AdRecord serviceData) {
if (serviceData == null) {return -1;} if (serviceData == null) {
return -1;
}
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return -1; if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return -1;
final byte[] raw = serviceData.getData(); final byte[] raw = serviceData.getData();
@@ -56,7 +63,7 @@ public class AdRecordUtils {
//Done if our record isn't a valid type //Done if our record isn't a valid type
if (type == 0) break; if (type == 0) break;
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length); final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
records.add(new AdRecord(length, type, data)); records.add(new AdRecord(length, type, data));
@@ -82,7 +89,7 @@ public class AdRecordUtils {
//Done if our record isn't a valid type //Done if our record isn't a valid type
if (type == 0) break; if (type == 0) break;
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length); final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
records.put(type, new AdRecord(length, type, data)); records.put(type, new AdRecord(length, type, data));
@@ -107,7 +114,7 @@ public class AdRecordUtils {
//Done if our record isn't a valid type //Done if our record isn't a valid type
if (type == 0) break; if (type == 0) break;
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length); final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
records.put(type, new AdRecord(length, type, data)); records.put(type, new AdRecord(length, type, data));
@@ -4,24 +4,26 @@ import java.nio.ByteBuffer;
public class ByteUtils { public class ByteUtils {
/** The Constant HEXES. */ /**
* The Constant HEXES.
*/
private static final String HEXES = "0123456789ABCDEF"; private static final String HEXES = "0123456789ABCDEF";
/** /**
* Gets a pretty representation of a Byte Array as a HEX String. * Gets a pretty representation of a Byte Array as a HEX String.
* * <p/>
* Sample output: [01, 30, FF, AA] * Sample output: [01, 30, FF, AA]
* *
* @param array the array * @param array the array
* @return the string * @return the string
*/ */
public static String byteArrayToHexString(final byte[] array){ public static String byteArrayToHexString(final byte[] array) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
boolean firstEntry = true; boolean firstEntry = true;
sb.append('['); sb.append('[');
for ( final byte b : array ) { for (final byte b : array) {
if(!firstEntry){ if (!firstEntry) {
sb.append(", "); sb.append(", ");
} }
sb.append(HEXES.charAt((b & 0xF0) >> 4)); sb.append(HEXES.charAt((b & 0xF0) >> 4));
@@ -40,11 +42,13 @@ public class ByteUtils {
* @param prefix the prefix * @param prefix the prefix
* @return true, if successful * @return true, if successful
*/ */
public static boolean doesArrayBeginWith(final byte[] array, final byte[] prefix){ public static boolean doesArrayBeginWith(final byte[] array, final byte[] prefix) {
if(array.length < prefix.length){return false;} if (array.length < prefix.length) {
return false;
}
for(int i = 0; i < prefix.length; i++){ for (int i = 0; i < prefix.length; i++) {
if(array[i] != prefix[i]){ if (array[i] != prefix[i]) {
return false; return false;
} }
} }
@@ -58,7 +62,7 @@ public class ByteUtils {
* @param input the input * @param input the input
* @return the int from the array * @return the int from the array
*/ */
public static int getIntFrom2ByteArray(final byte[] input){ public static int getIntFrom2ByteArray(final byte[] input) {
final byte[] result = new byte[4]; final byte[] result = new byte[4];
result[0] = 0; result[0] = 0;
@@ -71,13 +75,13 @@ public class ByteUtils {
/** /**
* Converts a byte to an int, preserving the sign. * Converts a byte to an int, preserving the sign.
* * <p/>
* For example, FF will be converted to 255 and not -1. * For example, FF will be converted to 255 and not -1.
* *
* @param bite the bite * @param bite the bite
* @return the int from byte * @return the int from byte
*/ */
public static int getIntFromByte(final byte bite){ public static int getIntFromByte(final byte bite) {
return Integer.valueOf(bite & 0xFF); return Integer.valueOf(bite & 0xFF);
} }
@@ -108,15 +112,14 @@ public class ByteUtils {
* @param array the array * @param array the array
* @return the byte[] * @return the byte[]
*/ */
public static byte[] invertArray(final byte[] array){ public static byte[] invertArray(final byte[] array) {
final int size = array.length; final int size = array.length;
byte temp; byte temp;
for (int i = 0; i < size/2; i++) for (int i = 0; i < size / 2; i++) {
{
temp = array[i]; temp = array[i];
array[i] = array[size-1 - i]; array[i] = array[size - 1 - i];
array[size-1 - i] = temp; array[size - 1 - i] = temp;
} }
return array; return array;
@@ -0,0 +1,8 @@
package uk.co.alt236.bluetoothlelib.util;
public enum IBeaconDistanceDescriptor {
IMMEDIATE,
NEAR,
FAR,
UNKNOWN,
}
@@ -10,25 +10,9 @@ public class IBeaconUtils {
private static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = new byte[]{0x4C, 0x00, 0x02, 0x15}; private static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = new byte[]{0x4C, 0x00, 0x02, 0x15};
public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy){
if(accuracy < DISTANCE_THRESHOLD_WTF){
return IBeaconDistanceDescriptor.UNKNOWN;
}
if(accuracy < DISTANCE_THRESHOLD_IMMEDIATE){
return IBeaconDistanceDescriptor.IMMEDIATE;
}
if(accuracy < DISTANCE_THRESHOLD_NEAR){
return IBeaconDistanceDescriptor.NEAR;
}
return IBeaconDistanceDescriptor.FAR;
}
/** /**
* Calculates the accuracy of an RSSI reading. * Calculates the accuracy of an RSSI reading.
* * <p/>
* The code was taken from {@linktourl http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing} * The code was taken from {@linktourl http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing}
* *
* @param txPower the calibrated TX power of an iBeacon * @param txPower the calibrated TX power of an iBeacon
@@ -40,23 +24,38 @@ public class IBeaconUtils {
return -1.0; // if we cannot determine accuracy, return -1. return -1.0; // if we cannot determine accuracy, return -1.
} }
final double ratio = rssi*1.0/txPower; final double ratio = rssi * 1.0 / txPower;
if (ratio < 1.0) { if (ratio < 1.0) {
return Math.pow(ratio,10); return Math.pow(ratio, 10);
} } else {
else { final double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
final double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
return accuracy; return accuracy;
} }
} }
public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy) {
if (accuracy < DISTANCE_THRESHOLD_WTF) {
return IBeaconDistanceDescriptor.UNKNOWN;
}
if (accuracy < DISTANCE_THRESHOLD_IMMEDIATE) {
return IBeaconDistanceDescriptor.IMMEDIATE;
}
if (accuracy < DISTANCE_THRESHOLD_NEAR) {
return IBeaconDistanceDescriptor.NEAR;
}
return IBeaconDistanceDescriptor.FAR;
}
/** /**
* Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon; * Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon;
* *
* @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device. * @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device.
* @return true if the device is an iBeacon, false otherwise * @return true if the device is an iBeacon, false otherwise
*/ */
public static boolean isThisAnIBeacon(final BluetoothLeDevice device){ public static boolean isThisAnIBeacon(final BluetoothLeDevice device) {
return isThisAnIBeacon( return isThisAnIBeacon(
device.getAdRecordStore().getRecordDataAsString(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getBytes()); device.getAdRecordStore().getRecordDataAsString(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getBytes());
} }
@@ -67,23 +66,21 @@ public class IBeaconUtils {
* @param manufacturerData a Bluetooth LE device's raw manufacturerData. * @param manufacturerData a Bluetooth LE device's raw manufacturerData.
* @return true if the manufacturer data belong to an iBeacon * @return true if the manufacturer data belong to an iBeacon
*/ */
public static boolean isThisAnIBeacon(final byte[] manufacturerData){ public static boolean isThisAnIBeacon(final byte[] manufacturerData) {
if(manufacturerData == null){return false;} if (manufacturerData == null) {
return false;
}
// An iBeacon record must be at least 25 chars long // An iBeacon record must be at least 25 chars long
if(!(manufacturerData.length >= 25)){return false;} if (!(manufacturerData.length >= 25)) {
return false;
}
if(ByteUtils.doesArrayBeginWith(manufacturerData, MANUFACTURER_DATA_IBEACON_PREFIX)){ if (ByteUtils.doesArrayBeginWith(manufacturerData, MANUFACTURER_DATA_IBEACON_PREFIX)) {
return true; return true;
} }
return false; return false;
} }
public enum IBeaconDistanceDescriptor{
IMMEDIATE,
NEAR,
FAR,
UNKNOWN,
}
} }
@@ -3,12 +3,12 @@ package uk.co.alt236.bluetoothlelib.util;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
public class LimitedLinkHashMap<K, V> extends LinkedHashMap<K, V>{ public class LimitedLinkHashMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = -5375660288461724925L; private static final long serialVersionUID = -5375660288461724925L;
private final int mMaxSize; private final int mMaxSize;
public LimitedLinkHashMap(final int maxSize){ public LimitedLinkHashMap(final int maxSize) {
super(maxSize + 1, 1, false); super(maxSize + 1, 1, false);
mMaxSize = maxSize; mMaxSize = maxSize;
} }
+14 -13
View File
@@ -1,43 +1,44 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest
package="uk.co.alt236.btlescan" package="uk.co.alt236.btlescan"
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="3" android:versionCode="3"
android:versionName="0.0.3" > android:versionName="0.0.3">
<uses-sdk <uses-sdk
android:minSdkVersion="18" android:minSdkVersion="18"
android:targetSdkVersion="18" /> android:targetSdkVersion="18"/>
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature <uses-feature
android:name="android.hardware.bluetooth_le" android:name="android.hardware.bluetooth_le"
android:required="false" /> android:required="false"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme">
<activity <activity
android:name="uk.co.alt236.btlescan.activities.MainActivity" android:name="uk.co.alt236.btlescan.activities.MainActivity"
android:label="@string/app_name" > android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name="uk.co.alt236.btlescan.activities.DeviceDetailsActivity" android:name="uk.co.alt236.btlescan.activities.DeviceDetailsActivity"
android:label="@string/app_name" > android:label="@string/app_name">
</activity> </activity>
<activity android:name="uk.co.alt236.btlescan.activities.DeviceControlActivity" /> <activity android:name="uk.co.alt236.btlescan.activities.DeviceControlActivity"/>
<service <service
android:name="uk.co.alt236.btlescan.services.BluetoothLeService" android:name="uk.co.alt236.btlescan.services.BluetoothLeService"
android:enabled="true" /> android:enabled="true"/>
</application> </application>
</manifest> </manifest>
@@ -16,16 +16,6 @@
package uk.co.alt236.btlescan.activities; package uk.co.alt236.btlescan.activities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver;
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.services.BluetoothLeService;
import android.app.Activity; import android.app.Activity;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothGattService;
@@ -44,8 +34,19 @@ import android.view.View;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter; import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView; import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.InjectView; import butterknife.InjectView;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver;
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.services.BluetoothLeService;
/** /**
* For a given BLE device, this Activity provides the user interface to connect, display data, * For a given BLE device, this Activity provides the user interface to connect, display data,
@@ -54,29 +55,54 @@ import butterknife.InjectView;
* Bluetooth LE API. * Bluetooth LE API.
*/ */
public class DeviceControlActivity extends Activity { public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class.getSimpleName();
public static final String EXTRA_DEVICE = "extra_device"; public static final String EXTRA_DEVICE = "extra_device";
private final static String TAG = DeviceControlActivity.class.getSimpleName();
private static final String LIST_NAME = "NAME"; private static final String LIST_NAME = "NAME";
private static final String LIST_UUID = "UUID"; private static final String LIST_UUID = "UUID";
@InjectView(R.id.gatt_services_list)
ExpandableListView mGattServicesList;
@InjectView(R.id.connection_state)
TextView mConnectionState;
@InjectView(R.id.uuid)
TextView mGattUUID;
@InjectView(R.id.description)
TextView mGattUUIDDesc;
@InjectView(R.id.data_as_string)
TextView mDataAsString;
@InjectView(R.id.data_as_array)
TextView mDataAsArray;
private BluetoothGattCharacteristic mNotifyCharacteristic; private BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothLeService mBluetoothLeService; private BluetoothLeService mBluetoothLeService;
private List<List<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<List<BluetoothGattCharacteristic>>(); private List<List<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<List<BluetoothGattCharacteristic>>();
// If a given GATT characteristic is selected, check for supported features. This sample
// demonstrates 'Read' and 'Notify' features. See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(final ExpandableListView parent, final View v, final int groupPosition, final int childPosition, final long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
// If there is an active notification on a characteristic, clear
// it first so it doesn't update the data field on the user interface.
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(characteristic, true);
}
return true;
}
return false;
}
};
private String mDeviceAddress; private String mDeviceAddress;
private String mDeviceName;
@InjectView(R.id.gatt_services_list) ExpandableListView mGattServicesList;
@InjectView(R.id.connection_state) TextView mConnectionState;
@InjectView(R.id.uuid) TextView mGattUUID;
@InjectView(R.id.description) TextView mGattUUIDDesc;
@InjectView(R.id.data_as_string) TextView mDataAsString;
@InjectView(R.id.data_as_array) TextView mDataAsArray;
private boolean mConnected = false;
private String mExportString;
// Code to manage Service lifecycle. // Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() { private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override @Override
@@ -95,7 +121,9 @@ public class DeviceControlActivity extends Activity {
mBluetoothLeService = null; mBluetoothLeService = null;
} }
}; };
private String mDeviceName;
private boolean mConnected = false;
private String mExportString;
// Handles various events fired by the Service. // Handles various events fired by the Service.
// ACTION_GATT_CONNECTED: connected to a GATT server. // ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server. // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
@@ -131,35 +159,6 @@ public class DeviceControlActivity extends Activity {
} }
}; };
// If a given GATT characteristic is selected, check for supported features. This sample
// demonstrates 'Read' and 'Notify' features. See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(final ExpandableListView parent, final View v, final int groupPosition, final int childPosition, final long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
// If there is an active notification on a characteristic, clear
// it first so it doesn't update the data field on the user interface.
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(characteristic, true);
}
return true;
}
return false;
}
};
private void clearUI() { private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null); mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
mGattUUID.setText(R.string.no_data); mGattUUID.setText(R.string.no_data);
@@ -168,7 +167,63 @@ public class DeviceControlActivity extends Activity {
mDataAsString.setText(R.string.no_data); mDataAsString.setText(R.string.no_data);
} }
private void generateExportString(final List<BluetoothGattService> gattServices){ // Demonstrates how to iterate through the supported GATT Services/Characteristics.
// In this sample, we populate the data structure that is bound to the ExpandableListView
// on the UI.
private void displayGattServices(final List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
generateExportString(gattServices);
String uuid = null;
final String unknownServiceString = getResources().getString(R.string.unknown_service);
final String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
final List<Map<String, String>> gattServiceData = new ArrayList<Map<String, String>>();
final List<List<Map<String, String>>> gattCharacteristicData = new ArrayList<List<Map<String, String>>>();
mGattCharacteristics = new ArrayList<List<BluetoothGattCharacteristic>>();
// Loops through available GATT Services.
for (final BluetoothGattService gattService : gattServices) {
final Map<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
final List<Map<String, String>> gattCharacteristicGroupData = new ArrayList<Map<String, String>>();
final List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
final List<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();
// Loops through available Characteristics.
for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
final Map<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
final SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,
android.R.layout.simple_expandable_list_item_2,
new String[]{LIST_NAME, LIST_UUID},
new int[]{android.R.id.text1, android.R.id.text2},
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[]{LIST_NAME, LIST_UUID},
new int[]{android.R.id.text1, android.R.id.text2}
);
mGattServicesList.setAdapter(gattServiceAdapter);
invalidateOptionsMenu();
}
private void generateExportString(final List<BluetoothGattService> gattServices) {
final String unknownServiceString = getResources().getString(R.string.unknown_service); final String unknownServiceString = getResources().getString(R.string.unknown_service);
final String unknownCharaString = getResources().getString(R.string.unknown_characteristic); final String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
final StringBuilder exportBuilder = new StringBuilder(); final StringBuilder exportBuilder = new StringBuilder();
@@ -217,62 +272,6 @@ public class DeviceControlActivity extends Activity {
mExportString = exportBuilder.toString(); mExportString = exportBuilder.toString();
} }
// Demonstrates how to iterate through the supported GATT Services/Characteristics.
// In this sample, we populate the data structure that is bound to the ExpandableListView
// on the UI.
private void displayGattServices(final List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
generateExportString(gattServices);
String uuid = null;
final String unknownServiceString = getResources().getString(R.string.unknown_service);
final String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
final List<Map<String, String>> gattServiceData = new ArrayList<Map<String, String>>();
final List<List<Map<String, String>>> gattCharacteristicData = new ArrayList<List<Map<String, String>>>();
mGattCharacteristics = new ArrayList<List<BluetoothGattCharacteristic>>();
// Loops through available GATT Services.
for (final BluetoothGattService gattService : gattServices) {
final Map<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
final List<Map<String, String>> gattCharacteristicGroupData = new ArrayList<Map<String, String>>();
final List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
final List<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();
// Loops through available Characteristics.
for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
final Map<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
final SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 },
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 }
);
mGattServicesList.setAdapter(gattServiceAdapter);
invalidateOptionsMenu();
}
@Override @Override
public void onCreate(final Bundle savedInstanceState) { public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -307,7 +306,7 @@ public class DeviceControlActivity extends Activity {
menu.findItem(R.id.menu_disconnect).setVisible(false); menu.findItem(R.id.menu_disconnect).setVisible(false);
} }
if(mExportString == null){ if (mExportString == null) {
menu.findItem(R.id.menu_share).setVisible(false); menu.findItem(R.id.menu_share).setVisible(false);
} else { } else {
menu.findItem(R.id.menu_share).setVisible(true); menu.findItem(R.id.menu_share).setVisible(true);
@@ -325,7 +324,7 @@ public class DeviceControlActivity extends Activity {
@Override @Override
public boolean onOptionsItemSelected(final MenuItem item) { public boolean onOptionsItemSelected(final MenuItem item) {
switch(item.getItemId()) { switch (item.getItemId()) {
case R.id.menu_connect: case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress); mBluetoothLeService.connect(mDeviceAddress);
return true; return true;
@@ -374,7 +373,7 @@ public class DeviceControlActivity extends Activity {
public void run() { public void run() {
final int colourId; final int colourId;
switch(resourceId){ switch (resourceId) {
case R.string.connected: case R.string.connected:
colourId = android.R.color.holo_green_dark; colourId = android.R.color.holo_green_dark;
break; break;
@@ -401,10 +400,10 @@ public class DeviceControlActivity extends Activity {
return intentFilter; return intentFilter;
} }
private static String tryString(final String string, final String fallback){ private static String tryString(final String string, final String fallback) {
if(string == null){ if (string == null) {
return fallback; return fallback;
} else{ } else {
return string; return string;
} }
} }
@@ -1,8 +1,19 @@
package uk.co.alt236.btlescan.activities; package uk.co.alt236.btlescan.activities;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.commonsware.cwac.merge.MergeAdapter;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
import butterknife.ButterKnife;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord; import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData; import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData;
@@ -12,36 +23,26 @@ import uk.co.alt236.bluetoothlelib.util.ByteUtils;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils; import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
import uk.co.alt236.btlescan.R; import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.util.TimeFormatter; import uk.co.alt236.btlescan.util.TimeFormatter;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.TextView;
import butterknife.ButterKnife;
import com.commonsware.cwac.merge.MergeAdapter; public class DeviceDetailsActivity extends ListActivity {
public class DeviceDetailsActivity extends ListActivity{
public static final String EXTRA_DEVICE = "extra_device"; public static final String EXTRA_DEVICE = "extra_device";
private BluetoothLeDevice mDevice; private BluetoothLeDevice mDevice;
private void appendAdRecordView(final MergeAdapter adapter, final String title, final AdRecord record){ private void appendAdRecordView(final MergeAdapter adapter, final String title, final AdRecord record) {
final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_adrecord, null); final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_adrecord, null);
final TextView tvString = (TextView) lt.findViewById(R.id.data_as_string); final TextView tvString = (TextView) lt.findViewById(R.id.data_as_string);
final TextView tvArray = (TextView) lt.findViewById(R.id.data_as_array); final TextView tvArray = (TextView) lt.findViewById(R.id.data_as_array);
final TextView tvTitle = (TextView) lt.findViewById(R.id.title); final TextView tvTitle = (TextView) lt.findViewById(R.id.title);
tvTitle.setText(title ); tvTitle.setText(title);
tvString.setText("'" + AdRecordUtils.getRecordDataAsString(record) + "'"); tvString.setText("'" + AdRecordUtils.getRecordDataAsString(record) + "'");
tvArray.setText("'" + ByteUtils.byteArrayToHexString(record.getData()) + "'"); tvArray.setText("'" + ByteUtils.byteArrayToHexString(record.getData()) + "'");
adapter.addView(lt); adapter.addView(lt);
} }
private void appendDeviceInfo(final MergeAdapter adapter, final BluetoothLeDevice device){ private void appendDeviceInfo(final MergeAdapter adapter, final BluetoothLeDevice device) {
final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_device_info, null); final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_device_info, null);
final TextView tvName = (TextView) lt.findViewById(R.id.deviceName); final TextView tvName = (TextView) lt.findViewById(R.id.deviceName);
final TextView tvAddress = (TextView) lt.findViewById(R.id.deviceAddress); final TextView tvAddress = (TextView) lt.findViewById(R.id.deviceAddress);
@@ -56,7 +57,7 @@ public class DeviceDetailsActivity extends ListActivity{
adapter.addView(lt); adapter.addView(lt);
} }
private void appendHeader(final MergeAdapter adapter, final String title){ private void appendHeader(final MergeAdapter adapter, final String title) {
final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_header, null); final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_header, null);
final TextView tvTitle = (TextView) lt.findViewById(R.id.title); final TextView tvTitle = (TextView) lt.findViewById(R.id.title);
tvTitle.setText(title); tvTitle.setText(title);
@@ -64,7 +65,7 @@ public class DeviceDetailsActivity extends ListActivity{
adapter.addView(lt); adapter.addView(lt);
} }
private void appendIBeaconInfo(final MergeAdapter adapter, final IBeaconManufacturerData iBeaconData){ private void appendIBeaconInfo(final MergeAdapter adapter, final IBeaconManufacturerData iBeaconData) {
final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_ibeacon_details, null); final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_ibeacon_details, null);
final TextView tvCompanyId = (TextView) lt.findViewById(R.id.companyId); final TextView tvCompanyId = (TextView) lt.findViewById(R.id.companyId);
final TextView tvAdvert = (TextView) lt.findViewById(R.id.advertisement); final TextView tvAdvert = (TextView) lt.findViewById(R.id.advertisement);
@@ -76,16 +77,16 @@ public class DeviceDetailsActivity extends ListActivity{
tvCompanyId.setText( tvCompanyId.setText(
CompanyIdentifierResolver.getCompanyName(iBeaconData.getCompanyIdentifier(), getString(R.string.unknown)) CompanyIdentifierResolver.getCompanyName(iBeaconData.getCompanyIdentifier(), getString(R.string.unknown))
+ " (" + hexEncode(iBeaconData.getCompanyIdentifier()) + ")"); + " (" + hexEncode(iBeaconData.getCompanyIdentifier()) + ")");
tvAdvert.setText(iBeaconData.getIBeaconAdvertisement() + " (" + hexEncode( iBeaconData.getIBeaconAdvertisement() ) + ")"); tvAdvert.setText(iBeaconData.getIBeaconAdvertisement() + " (" + hexEncode(iBeaconData.getIBeaconAdvertisement()) + ")");
tvUUID.setText(iBeaconData.getUUID()); tvUUID.setText(iBeaconData.getUUID());
tvMajor.setText(iBeaconData.getMajor() + " (" + hexEncode( iBeaconData.getMajor() ) + ")"); tvMajor.setText(iBeaconData.getMajor() + " (" + hexEncode(iBeaconData.getMajor()) + ")");
tvMinor.setText(iBeaconData.getMinor() + " (" + hexEncode( iBeaconData.getMinor() ) + ")"); tvMinor.setText(iBeaconData.getMinor() + " (" + hexEncode(iBeaconData.getMinor()) + ")");
tvTxPower.setText(iBeaconData.getCalibratedTxPower() + " (" + hexEncode( iBeaconData.getCalibratedTxPower() ) + ")"); tvTxPower.setText(iBeaconData.getCalibratedTxPower() + " (" + hexEncode(iBeaconData.getCalibratedTxPower()) + ")");
adapter.addView(lt); adapter.addView(lt);
} }
private void appendRssiInfo(final MergeAdapter adapter, final BluetoothLeDevice device){ private void appendRssiInfo(final MergeAdapter adapter, final BluetoothLeDevice device) {
final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_rssi_info, null); final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_rssi_info, null);
final TextView tvFirstTimestamp = (TextView) lt.findViewById(R.id.firstTimestamp); final TextView tvFirstTimestamp = (TextView) lt.findViewById(R.id.firstTimestamp);
final TextView tvFirstRssi = (TextView) lt.findViewById(R.id.firstRssi); final TextView tvFirstRssi = (TextView) lt.findViewById(R.id.firstRssi);
@@ -102,11 +103,11 @@ public class DeviceDetailsActivity extends ListActivity{
adapter.addView(lt); adapter.addView(lt);
} }
private void appendSimpleText(final MergeAdapter adapter, final byte[] data){ private void appendSimpleText(final MergeAdapter adapter, final byte[] data) {
appendSimpleText(adapter, ByteUtils.byteArrayToHexString(data)); appendSimpleText(adapter, ByteUtils.byteArrayToHexString(data));
} }
private void appendSimpleText(final MergeAdapter adapter, final String data){ private void appendSimpleText(final MergeAdapter adapter, final String data) {
final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_textview, null); final LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.list_item_view_textview, null);
final TextView tvData = (TextView) lt.findViewById(R.id.data); final TextView tvData = (TextView) lt.findViewById(R.id.data);
@@ -116,11 +117,11 @@ public class DeviceDetailsActivity extends ListActivity{
} }
private String formatRssi(final double rssi){ private String formatRssi(final double rssi) {
return getString(R.string.formatter_db, String.valueOf(rssi)); return getString(R.string.formatter_db, String.valueOf(rssi));
} }
private String formatRssi(final int rssi){ private String formatRssi(final int rssi) {
return getString(R.string.formatter_db, String.valueOf(rssi)); return getString(R.string.formatter_db, String.valueOf(rssi));
} }
@@ -159,7 +160,7 @@ public class DeviceDetailsActivity extends ListActivity{
private void pupulateDetails(final BluetoothLeDevice device) { private void pupulateDetails(final BluetoothLeDevice device) {
final MergeAdapter adapter = new MergeAdapter(); final MergeAdapter adapter = new MergeAdapter();
if(device == null){ if (device == null) {
appendHeader(adapter, getString(R.string.header_device_info)); appendHeader(adapter, getString(R.string.header_device_info));
appendSimpleText(adapter, getString(R.string.invalid_device_data)); appendSimpleText(adapter, getString(R.string.invalid_device_data));
} else { } else {
@@ -173,10 +174,10 @@ public class DeviceDetailsActivity extends ListActivity{
appendSimpleText(adapter, device.getScanRecord()); appendSimpleText(adapter, device.getScanRecord());
final Collection<AdRecord> adRecords = device.getAdRecordStore().getRecordsAsCollection(); final Collection<AdRecord> adRecords = device.getAdRecordStore().getRecordsAsCollection();
if(adRecords.size() > 0){ if (adRecords.size() > 0) {
appendHeader(adapter, getString(R.string.header_raw_ad_records)); appendHeader(adapter, getString(R.string.header_raw_ad_records));
for(final AdRecord record : adRecords){ for (final AdRecord record : adRecords) {
appendAdRecordView( appendAdRecordView(
adapter, adapter,
@@ -186,7 +187,7 @@ public class DeviceDetailsActivity extends ListActivity{
} }
final boolean isIBeacon = IBeaconUtils.isThisAnIBeacon(device); final boolean isIBeacon = IBeaconUtils.isThisAnIBeacon(device);
if(isIBeacon){ if (isIBeacon) {
final IBeaconManufacturerData iBeaconData = new IBeaconManufacturerData(device); final IBeaconManufacturerData iBeaconData = new IBeaconManufacturerData(device);
appendHeader(adapter, getString(R.string.header_ibeacon_data)); appendHeader(adapter, getString(R.string.header_ibeacon_data));
appendIBeaconInfo(adapter, iBeaconData); appendIBeaconInfo(adapter, iBeaconData);
@@ -196,11 +197,11 @@ public class DeviceDetailsActivity extends ListActivity{
getListView().setAdapter(adapter); getListView().setAdapter(adapter);
} }
private static String formatTime(final long time){ private static String formatTime(final long time) {
return TimeFormatter.getIsoDateTime(time); return TimeFormatter.getIsoDateTime(time);
} }
private static String hexEncode(final int integer){ private static String hexEncode(final int integer) {
return "0x" + Integer.toHexString(integer).toUpperCase(Locale.US); return "0x" + Integer.toHexString(integer).toUpperCase(Locale.US);
} }
} }
@@ -1,12 +1,5 @@
package uk.co.alt236.btlescan.activities; package uk.co.alt236.btlescan.activities;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.adapters.LeDeviceListAdapter;
import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore;
import uk.co.alt236.btlescan.util.BluetoothLeScanner;
import uk.co.alt236.btlescan.util.BluetoothUtils;
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ListActivity; import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
@@ -22,13 +15,24 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.InjectView; import butterknife.InjectView;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.adapters.LeDeviceListAdapter;
import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore;
import uk.co.alt236.btlescan.util.BluetoothLeScanner;
import uk.co.alt236.btlescan.util.BluetoothUtils;
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
public class MainActivity extends ListActivity { public class MainActivity extends ListActivity {
@InjectView(R.id.tvBluetoothLe) TextView mTvBluetoothLeStatus; @InjectView(R.id.tvBluetoothLe)
@InjectView(R.id.tvBluetoothStatus) TextView mTvBluetoothStatus; TextView mTvBluetoothLeStatus;
@InjectView(R.id.tvItemCount) TextView mTvItemCount; @InjectView(R.id.tvBluetoothStatus)
TextView mTvBluetoothStatus;
@InjectView(R.id.tvItemCount)
TextView mTvItemCount;
private BluetoothUtils mBluetoothUtils; private BluetoothUtils mBluetoothUtils;
private BluetoothLeScanner mScanner; private BluetoothLeScanner mScanner;
@@ -53,20 +57,13 @@ public class MainActivity extends ListActivity {
} }
}; };
private void updateItemCount(final int count){ private void displayAboutDialog() {
mTvItemCount.setText(
getString(
R.string.formatter_item_count,
String.valueOf(count)));
}
private void displayAboutDialog(){
// REALLY REALLY LAZY LINKIFIED DIALOG // REALLY REALLY LAZY LINKIFIED DIALOG
final int paddingSizeDp = 5; final int paddingSizeDp = 5;
final float scale = getResources().getDisplayMetrics().density; final float scale = getResources().getDisplayMetrics().density;
final int dpAsPixels = (int) (paddingSizeDp * scale + 0.5f); final int dpAsPixels = (int) (paddingSizeDp * scale + 0.5f);
final TextView textView=new TextView(this); final TextView textView = new TextView(this);
final SpannableString text = new SpannableString(getString(R.string.about_dialog_text)); final SpannableString text = new SpannableString(getString(R.string.about_dialog_text));
textView.setText(text); textView.setText(text);
@@ -79,7 +76,8 @@ public class MainActivity extends ListActivity {
.setTitle(R.string.menu_about) .setTitle(R.string.menu_about)
.setCancelable(false) .setCancelable(false)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {} public void onClick(final DialogInterface dialog, final int id) {
}
}) })
.setView(textView) .setView(textView)
.show(); .show();
@@ -110,7 +108,7 @@ public class MainActivity extends ListActivity {
menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate); menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate);
} }
if(getListView().getCount() > 0){ if (getListView().getCount() > 0) {
menu.findItem(R.id.menu_share).setVisible(true); menu.findItem(R.id.menu_share).setVisible(true);
} else { } else {
menu.findItem(R.id.menu_share).setVisible(false); menu.findItem(R.id.menu_share).setVisible(false);
@@ -156,18 +154,18 @@ public class MainActivity extends ListActivity {
} }
@Override @Override
public void onResume(){ public void onResume() {
super.onResume(); super.onResume();
final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn(); final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn();
final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported(); final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported();
if(mIsBluetoothOn){ if (mIsBluetoothOn) {
mTvBluetoothStatus.setText(R.string.on); mTvBluetoothStatus.setText(R.string.on);
} else { } else {
mTvBluetoothStatus.setText(R.string.off); mTvBluetoothStatus.setText(R.string.off);
} }
if(mIsBluetoothLePresent){ if (mIsBluetoothLePresent) {
mTvBluetoothLeStatus.setText(R.string.supported); mTvBluetoothLeStatus.setText(R.string.supported);
} else { } else {
mTvBluetoothLeStatus.setText(R.string.not_supported); mTvBluetoothLeStatus.setText(R.string.not_supported);
@@ -176,7 +174,7 @@ public class MainActivity extends ListActivity {
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
private void startScan(){ private void startScan() {
final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn(); final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn();
final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported(); final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported();
mDeviceStore.clear(); mDeviceStore.clear();
@@ -186,10 +184,17 @@ public class MainActivity extends ListActivity {
setListAdapter(mLeDeviceListAdapter); setListAdapter(mLeDeviceListAdapter);
mBluetoothUtils.askUserToEnableBluetoothIfNeeded(); mBluetoothUtils.askUserToEnableBluetoothIfNeeded();
if(mIsBluetoothOn && mIsBluetoothLePresent){ if (mIsBluetoothOn && mIsBluetoothLePresent) {
mScanner.scanLeDevice(-1, true); mScanner.scanLeDevice(-1, true);
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
} }
private void updateItemCount(final int count) {
mTvItemCount.setText(
getString(
R.string.formatter_item_count,
String.valueOf(count)));
}
} }
@@ -1,11 +1,5 @@
package uk.co.alt236.btlescan.adapters; package uk.co.alt236.btlescan.adapters;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.IBeaconDevice;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.util.Constants;
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
import android.app.Activity; import android.app.Activity;
import android.support.v4.widget.SimpleCursorAdapter; import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -13,6 +7,14 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.IBeaconDevice;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.util.Constants;
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
// Adapter for holding devices found through scanning. // Adapter for holding devices found through scanning.
public class LeDeviceListAdapter extends SimpleCursorAdapter { public class LeDeviceListAdapter extends SimpleCursorAdapter {
private final LayoutInflater mInflator; private final LayoutInflater mInflator;
@@ -26,12 +28,12 @@ public class LeDeviceListAdapter extends SimpleCursorAdapter {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public EasyObjectCursor<BluetoothLeDevice> getCursor(){ public EasyObjectCursor<BluetoothLeDevice> getCursor() {
return ((EasyObjectCursor<BluetoothLeDevice>) super.getCursor()); return ((EasyObjectCursor<BluetoothLeDevice>) super.getCursor());
} }
@Override @Override
public BluetoothLeDevice getItem(final int i){ public BluetoothLeDevice getItem(final int i) {
return getCursor().getItem(i); return getCursor().getItem(i);
} }
@@ -68,13 +70,13 @@ public class LeDeviceListAdapter extends SimpleCursorAdapter {
final String deviceName = device.getName(); final String deviceName = device.getName();
final double rssi = device.getRssi(); final double rssi = device.getRssi();
if (deviceName != null && deviceName.length() > 0){ if (deviceName != null && deviceName.length() > 0) {
viewHolder.deviceName.setText(deviceName); viewHolder.deviceName.setText(deviceName);
} else{ } else {
viewHolder.deviceName.setText(R.string.unknown_device); viewHolder.deviceName.setText(R.string.unknown_device);
} }
if (IBeaconUtils.isThisAnIBeacon(device)){ if (IBeaconUtils.isThisAnIBeacon(device)) {
final IBeaconDevice iBeacon = new IBeaconDevice(device); final IBeaconDevice iBeacon = new IBeaconDevice(device);
final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(iBeacon.getAccuracy()); final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(iBeacon.getAccuracy());
@@ -1,5 +1,9 @@
package uk.co.alt236.btlescan.containers; package uk.co.alt236.btlescan.containers;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
@@ -19,58 +23,35 @@ import uk.co.alt236.btlescan.R;
import uk.co.alt236.btlescan.util.CsvWriterHelper; import uk.co.alt236.btlescan.util.CsvWriterHelper;
import uk.co.alt236.btlescan.util.TimeFormatter; import uk.co.alt236.btlescan.util.TimeFormatter;
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor; import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
public class BluetoothLeDeviceStore { public class BluetoothLeDeviceStore {
private final Map<String, BluetoothLeDevice> mDeviceMap; private final Map<String, BluetoothLeDevice> mDeviceMap;
public BluetoothLeDeviceStore(){ public BluetoothLeDeviceStore() {
mDeviceMap = new HashMap<String, BluetoothLeDevice>(); mDeviceMap = new HashMap<String, BluetoothLeDevice>();
} }
public void addDevice(final BluetoothLeDevice device){ public void addDevice(final BluetoothLeDevice device) {
if(mDeviceMap.containsKey(device.getAddress())){ if (mDeviceMap.containsKey(device.getAddress())) {
mDeviceMap.get(device.getAddress()).updateRssiReading(device.getTimestamp(), device.getRssi()); mDeviceMap.get(device.getAddress()).updateRssiReading(device.getTimestamp(), device.getRssi());
} else { } else {
mDeviceMap.put(device.getAddress(), device); mDeviceMap.put(device.getAddress(), device);
} }
} }
public void clear(){ public void clear() {
mDeviceMap.clear(); mDeviceMap.clear();
} }
public EasyObjectCursor<BluetoothLeDevice> getDeviceCursor() {
private static FileWriter generateFile(final File file, final String contents){
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.append(contents);
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}finally{
try {
writer.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
return writer;
}
public EasyObjectCursor<BluetoothLeDevice> getDeviceCursor(){
return new EasyObjectCursor<BluetoothLeDevice>( return new EasyObjectCursor<BluetoothLeDevice>(
BluetoothLeDevice.class, BluetoothLeDevice.class,
getDeviceList(), getDeviceList(),
"address"); "address");
} }
public List<BluetoothLeDevice> getDeviceList(){ public List<BluetoothLeDevice> getDeviceList() {
final List<BluetoothLeDevice> methodResult = new ArrayList<BluetoothLeDevice>(mDeviceMap.values()); final List<BluetoothLeDevice> methodResult = new ArrayList<BluetoothLeDevice>(mDeviceMap.values());
Collections.sort(methodResult, new Comparator<BluetoothLeDevice>() { Collections.sort(methodResult, new Comparator<BluetoothLeDevice>() {
@@ -84,8 +65,7 @@ public class BluetoothLeDeviceStore {
return methodResult; return methodResult;
} }
private String getListAsCsv() {
private String getListAsCsv(){
final List<BluetoothLeDevice> list = getDeviceList(); final List<BluetoothLeDevice> list = getDeviceList();
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append(CsvWriterHelper.addStuff("mac")); sb.append(CsvWriterHelper.addStuff("mac"));
@@ -104,7 +84,7 @@ public class BluetoothLeDeviceStore {
sb.append(CsvWriterHelper.addStuff("accuracy")); sb.append(CsvWriterHelper.addStuff("accuracy"));
sb.append('\n'); sb.append('\n');
for(final BluetoothLeDevice device : list){ for (final BluetoothLeDevice device : list) {
sb.append(CsvWriterHelper.addStuff(device.getAddress())); sb.append(CsvWriterHelper.addStuff(device.getAddress()));
sb.append(CsvWriterHelper.addStuff(device.getName())); sb.append(CsvWriterHelper.addStuff(device.getName()));
sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getFirstTimestamp()))); sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getFirstTimestamp())));
@@ -120,7 +100,7 @@ public class BluetoothLeDeviceStore {
final String distance; final String distance;
final String accuracy; final String accuracy;
if(isIBeacon){ if (isIBeacon) {
final IBeaconDevice beacon = new IBeaconDevice(device); final IBeaconDevice beacon = new IBeaconDevice(device);
uuid = String.valueOf(beacon.getUUID()); uuid = String.valueOf(beacon.getUUID());
minor = String.valueOf(beacon.getMinor()); minor = String.valueOf(beacon.getMinor());
@@ -151,8 +131,7 @@ public class BluetoothLeDeviceStore {
return sb.toString(); return sb.toString();
} }
public void shareDataAsEmail(final Context context) {
public void shareDataAsEmail(final Context context){
final long timeInMillis = System.currentTimeMillis(); final long timeInMillis = System.currentTimeMillis();
final String to = null; final String to = null;
@@ -170,7 +149,7 @@ public class BluetoothLeDeviceStore {
outputFile.setReadable(true, false); outputFile.setReadable(true, false);
generateFile(outputFile, getListAsCsv()); generateFile(outputFile, getListAsCsv());
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(outputFile)); i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(outputFile));
i.putExtra(Intent.EXTRA_EMAIL, new String[] { to }); i.putExtra(Intent.EXTRA_EMAIL, new String[]{to});
i.putExtra(Intent.EXTRA_SUBJECT, subject); i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_TEXT, message); i.putExtra(Intent.EXTRA_TEXT, message);
context.startActivity(Intent.createChooser(i, context.getString(R.string.exporter_email_device_list_picker_text))); context.startActivity(Intent.createChooser(i, context.getString(R.string.exporter_email_device_list_picker_text)));
@@ -179,4 +158,23 @@ public class BluetoothLeDeviceStore {
e.printStackTrace(); e.printStackTrace();
} }
} }
private static FileWriter generateFile(final File file, final String contents) {
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.append(contents);
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
return writer;
}
} }
@@ -16,8 +16,6 @@
package uk.co.alt236.btlescan.services; package uk.co.alt236.btlescan.services;
import java.util.List;
import android.app.Service; import android.app.Service;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
@@ -33,33 +31,44 @@ import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log; import android.util.Log;
import java.util.List;
/** /**
* Service for managing connection and data communication with a GATT server hosted on a * Service for managing connection and data communication with a GATT server hosted on a
* given Bluetooth LE device. * given Bluetooth LE device.
*/ */
public class BluetoothLeService extends Service { public class BluetoothLeService extends Service {
private final static String TAG = BluetoothLeService.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED"; public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"; public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED"; public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE"; public final static String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA_RAW = "com.example.bluetooth.le.EXTRA_DATA_RAW"; public final static String EXTRA_DATA_RAW = "com.example.bluetooth.le.EXTRA_DATA_RAW";
public final static String EXTRA_UUID_CHAR = "com.example.bluetooth.le.EXTRA_UUID_CHAR"; public final static String EXTRA_UUID_CHAR = "com.example.bluetooth.le.EXTRA_UUID_CHAR";
private final static String TAG = BluetoothLeService.class.getSimpleName();
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
private final IBinder mBinder = new LocalBinder();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
// Implements callback methods for GATT events that the app cares about. For example, // Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered. // connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
@Override
public void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override @Override
public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) { public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
final String intentAction; final String intentAction;
@@ -87,18 +96,6 @@ public class BluetoothLeService extends Service {
Log.w(TAG, "onServicesDiscovered received: " + status); Log.w(TAG, "onServicesDiscovered received: " + status);
} }
} }
@Override
public void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}; };
private void broadcastUpdate(final String action) { private void broadcastUpdate(final String action) {
@@ -119,58 +116,22 @@ public class BluetoothLeService extends Service {
sendBroadcast(intent); sendBroadcast(intent);
} }
public class LocalBinder extends Binder {
public BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
@Override
public IBinder onBind(final Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(final Intent intent) {
// After using a given device, you should make sure that BluetoothGatt.close() is called
// such that resources are cleaned up properly. In this particular example, close() is
// invoked when the UI is disconnected from the Service.
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
/** /**
* Initializes a reference to the local Bluetooth adapter. * After using a given BLE device, the app must call this method to ensure resources are
* * released properly.
* @return Return true if the initialization is successful.
*/ */
public boolean initialize() { public void close() {
// For API level 18 and above, get a reference to BluetoothAdapter through if (mBluetoothGatt == null) {
// BluetoothManager. return;
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
} }
} mBluetoothGatt.close();
mBluetoothGatt = null;
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
} }
/** /**
* Connects to the GATT server hosted on the Bluetooth LE device. * Connects to the GATT server hosted on the Bluetooth LE device.
* *
* @param address The device address of the destination device. * @param address The device address of the destination device.
*
* @return Return true if the connection is initiated successfully. The connection result * @return Return true if the connection is initiated successfully. The connection result
* is reported asynchronously through the * is reported asynchronously through the
* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
@@ -225,15 +186,54 @@ public class BluetoothLeService extends Service {
} }
/** /**
* After using a given BLE device, the app must call this method to ensure resources are * Retrieves a list of supported GATT services on the connected device. This should be
* released properly. * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
*
* @return A {@code List} of supported services.
*/ */
public void close() { public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null) { if (mBluetoothGatt == null) return null;
return;
return mBluetoothGatt.getServices();
} }
mBluetoothGatt.close();
mBluetoothGatt = null; /**
* Initializes a reference to the local Bluetooth adapter.
*
* @return Return true if the initialization is successful.
*/
public boolean initialize() {
// For API level 18 and above, get a reference to BluetoothAdapter through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
@Override
public IBinder onBind(final Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(final Intent intent) {
// After using a given device, you should make sure that BluetoothGatt.close() is called
// such that resources are cleaned up properly. In this particular example, close() is
// invoked when the UI is disconnected from the Service.
close();
return super.onUnbind(intent);
} }
/** /**
@@ -265,15 +265,9 @@ public class BluetoothLeService extends Service {
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
} }
/** public class LocalBinder extends Binder {
* Retrieves a list of supported GATT services on the connected device. This should be public BluetoothLeService getService() {
* invoked only after {@code BluetoothGatt#discoverServices()} completes successfully. return BluetoothLeService.this;
* }
* @return A {@code List} of supported services.
*/
public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null) return null;
return mBluetoothGatt.getServices();
} }
} }
@@ -10,7 +10,7 @@ public class BluetoothLeScanner {
private final BluetoothUtils mBluetoothUtils; private final BluetoothUtils mBluetoothUtils;
private boolean mScanning; private boolean mScanning;
public BluetoothLeScanner(final BluetoothAdapter.LeScanCallback leScanCallback, final BluetoothUtils bluetoothUtils){ public BluetoothLeScanner(final BluetoothAdapter.LeScanCallback leScanCallback, final BluetoothUtils bluetoothUtils) {
mHandler = new Handler(); mHandler = new Handler();
mLeScanCallback = leScanCallback; mLeScanCallback = leScanCallback;
mBluetoothUtils = bluetoothUtils; mBluetoothUtils = bluetoothUtils;
@@ -22,10 +22,12 @@ public class BluetoothLeScanner {
public void scanLeDevice(final int duration, final boolean enable) { public void scanLeDevice(final int duration, final boolean enable) {
if (enable) { if (enable) {
if(mScanning){return;} if (mScanning) {
return;
}
Log.d("TAG", "~ Starting Scan"); Log.d("TAG", "~ Starting Scan");
// Stops scanning after a pre-defined scan period. // Stops scanning after a pre-defined scan period.
if(duration > 0){ if (duration > 0) {
mHandler.postDelayed(new Runnable() { mHandler.postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -8,33 +8,32 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
public final class BluetoothUtils { public final class BluetoothUtils {
public final static int REQUEST_ENABLE_BT = 2001;
private final Activity mActivity; private final Activity mActivity;
private final BluetoothAdapter mBluetoothAdapter; private final BluetoothAdapter mBluetoothAdapter;
public final static int REQUEST_ENABLE_BT = 2001; public BluetoothUtils(final Activity activity) {
public BluetoothUtils(final Activity activity){
mActivity = activity; mActivity = activity;
final BluetoothManager btManager = (BluetoothManager) mActivity.getSystemService(Context.BLUETOOTH_SERVICE); final BluetoothManager btManager = (BluetoothManager) mActivity.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = btManager.getAdapter(); mBluetoothAdapter = btManager.getAdapter();
} }
public void askUserToEnableBluetoothIfNeeded(){ public void askUserToEnableBluetoothIfNeeded() {
if (isBluetoothLeSupported() && (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())) { if (isBluetoothLeSupported() && (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())) {
final Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); final Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
mActivity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); mActivity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} }
} }
public BluetoothAdapter getBluetoothAdapter(){ public BluetoothAdapter getBluetoothAdapter() {
return mBluetoothAdapter; return mBluetoothAdapter;
} }
public boolean isBluetoothLeSupported(){ public boolean isBluetoothLeSupported() {
return mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); return mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
} }
public boolean isBluetoothOn(){ public boolean isBluetoothOn() {
if (mBluetoothAdapter == null) { if (mBluetoothAdapter == null) {
return false; return false;
} else { } else {
@@ -2,20 +2,23 @@ package uk.co.alt236.btlescan.util;
public class CsvWriterHelper { public class CsvWriterHelper {
private static final String QUOTE = "\""; private static final String QUOTE = "\"";
public static String addStuff(final Integer text){
public static String addStuff(final Integer text) {
return QUOTE + text + QUOTE + ","; return QUOTE + text + QUOTE + ",";
} }
public static String addStuff(final Long text){ public static String addStuff(final Long text) {
return QUOTE + text + QUOTE + ","; return QUOTE + text + QUOTE + ",";
} }
public static String addStuff(final boolean value){ public static String addStuff(final boolean value) {
return QUOTE + value + QUOTE + ","; return QUOTE + value + QUOTE + ",";
} }
public static String addStuff(String text){ public static String addStuff(String text) {
if(text == null){text = "<blank>";} if (text == null) {
text = "<blank>";
}
text = text.replace(QUOTE, "'"); text = text.replace(QUOTE, "'");
return QUOTE + text.trim() + QUOTE + ","; return QUOTE + text.trim() + QUOTE + ",";
@@ -8,11 +8,11 @@ public class TimeFormatter {
private final static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz"; private final static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
private final static SimpleDateFormat ISO_FORMATTER = new UtcDateFormatter(ISO_FORMAT, Locale.US); private final static SimpleDateFormat ISO_FORMATTER = new UtcDateFormatter(ISO_FORMAT, Locale.US);
public static String getIsoDateTime(final Date date){ public static String getIsoDateTime(final Date date) {
return ISO_FORMATTER.format(date); return ISO_FORMATTER.format(date);
} }
public static String getIsoDateTime(final long millis){ public static String getIsoDateTime(final long millis) {
return getIsoDateTime(new Date(millis)); return getIsoDateTime(new Date(millis));
} }
} }
@@ -1,9 +1,10 @@
/******************************************************************************* /**
* ****************************************************************************
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
* * <p/>
* GenieConnect Ltd. ("COMPANY") CONFIDENTIAL * GenieConnect Ltd. ("COMPANY") CONFIDENTIAL
* Unpublished Copyright (c) 2010-2013 GenieConnect Ltd., All Rights Reserved. * Unpublished Copyright (c) 2010-2013 GenieConnect Ltd., All Rights Reserved.
* * <p/>
* NOTICE: * NOTICE:
* All information contained herein is, and remains the property of COMPANY. * All information contained herein is, and remains the property of COMPANY.
* The intellectual and technical concepts contained herein are proprietary to * The intellectual and technical concepts contained herein are proprietary to
@@ -14,11 +15,11 @@
* contained herein is hereby forbidden to anyone except current COMPANY employees, * contained herein is hereby forbidden to anyone except current COMPANY employees,
* managers or contractors who have executed Confidentiality and Non-disclosure * managers or contractors who have executed Confidentiality and Non-disclosure
* agreements explicitly covering such access. * agreements explicitly covering such access.
* * <p/>
* The copyright notice above does not evidence any actual or intended publication * The copyright notice above does not evidence any actual or intended publication
* or disclosure of this source code, which includes information that is * or disclosure of this source code, which includes information that is
* confidential and/or proprietary, and is a trade secret, of COMPANY. * confidential and/or proprietary, and is a trade secret, of COMPANY.
* * <p/>
* ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, OR PUBLIC * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, OR PUBLIC
* DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN * DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN
* CONSENT OF COMPANY IS STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS * CONSENT OF COMPANY IS STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS
@@ -26,34 +27,35 @@
* AND/OR RELATED INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, * AND/OR RELATED INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE,
* DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING * DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING
* THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. * THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
******************************************************************************/ * ****************************************************************************
*/
package uk.co.alt236.btlescan.util; package uk.co.alt236.btlescan.util;
import android.annotation.SuppressLint;
import java.text.DateFormatSymbols; import java.text.DateFormatSymbols;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import android.annotation.SuppressLint; public class UtcDateFormatter extends java.text.SimpleDateFormat {
public class UtcDateFormatter extends java.text.SimpleDateFormat{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String TIME_ZONE_STRING = "UTC"; private static final String TIME_ZONE_STRING = "UTC";
private static final TimeZone TIME_ZONE_UTC = TimeZone.getTimeZone(TIME_ZONE_STRING); private static final TimeZone TIME_ZONE_UTC = TimeZone.getTimeZone(TIME_ZONE_STRING);
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
public UtcDateFormatter(final String template){ public UtcDateFormatter(final String template) {
super(template); super(template);
super.setTimeZone(TIME_ZONE_UTC); super.setTimeZone(TIME_ZONE_UTC);
} }
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
public UtcDateFormatter(final String template, final DateFormatSymbols symbols){ public UtcDateFormatter(final String template, final DateFormatSymbols symbols) {
super(template, symbols); super(template, symbols);
super.setTimeZone(TIME_ZONE_UTC); super.setTimeZone(TIME_ZONE_UTC);
} }
public UtcDateFormatter(final String template, final Locale locale){ public UtcDateFormatter(final String template, final Locale locale) {
super(template, locale); super(template, locale);
super.setTimeZone(TIME_ZONE_UTC); super.setTimeZone(TIME_ZONE_UTC);
} }
@@ -66,7 +68,7 @@ public class UtcDateFormatter extends java.text.SimpleDateFormat{
* @see java.text.DateFormat#setTimeZone(java.util.TimeZone) * @see java.text.DateFormat#setTimeZone(java.util.TimeZone)
*/ */
@Override @Override
public void setTimeZone(final TimeZone timezone){ public void setTimeZone(final TimeZone timezone) {
throw new UnsupportedOperationException("This SimpleDateFormat can only be in " + TIME_ZONE_STRING); throw new UnsupportedOperationException("This SimpleDateFormat can only be in " + TIME_ZONE_STRING);
} }
} }
@@ -1,11 +1,11 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minWidth="56dp" > android:minWidth="56dp">
<ProgressBar <ProgressBar
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="32dp" android:layout_height="32dp"
android:layout_gravity="center" /> android:layout_gravity="center"/>
</FrameLayout> </FrameLayout>
@@ -1,15 +1,14 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" > android:paddingTop="@dimen/activity_vertical_margin">
<ListView <ListView
android:id="@android:id/list" android:id="@android:id/list"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" > android:layout_height="wrap_content">
</ListView> </ListView>
</RelativeLayout> </RelativeLayout>
@@ -21,7 +21,7 @@
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" > android:paddingTop="@dimen/activity_vertical_margin">
<GridLayout <GridLayout
android:id="@+id/deviceInformation" android:id="@+id/deviceInformation"
@@ -29,27 +29,27 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:columnCount="2" android:columnCount="2"
android:useDefaultMargins="true" > android:useDefaultMargins="true">
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_device_address" /> android:text="@string/label_device_address"/>
<TextView <TextView
android:id="@+id/device_address" android:id="@+id/device_address"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_state" /> android:text="@string/label_state"/>
<TextView <TextView
android:id="@+id/connection_state" android:id="@+id/connection_state"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
</GridLayout> </GridLayout>
<View <View
@@ -57,7 +57,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_below="@id/deviceInformation" android:layout_below="@id/deviceInformation"
android:background="@android:color/holo_blue_dark" /> android:background="@android:color/holo_blue_dark"/>
<GridLayout <GridLayout
android:id="@+id/gattInformation" android:id="@+id/gattInformation"
@@ -65,47 +65,47 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:columnCount="2" android:columnCount="2"
android:useDefaultMargins="true" > android:useDefaultMargins="true">
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_uuid" /> android:text="@string/label_uuid"/>
<TextView <TextView
android:id="@+id/uuid" android:id="@+id/uuid"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_desc" /> android:text="@string/label_desc"/>
<TextView <TextView
android:id="@+id/description" android:id="@+id/description"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_as_string" /> android:text="@string/label_as_string"/>
<TextView <TextView
android:id="@+id/data_as_string" android:id="@+id/data_as_string"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_as_array" /> android:text="@string/label_as_array"/>
<TextView <TextView
android:id="@+id/data_as_array" android:id="@+id/data_as_array"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
</GridLayout> </GridLayout>
<View <View
@@ -113,13 +113,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_above="@id/gattInformation" android:layout_above="@id/gattInformation"
android:background="@android:color/holo_blue_dark" /> android:background="@android:color/holo_blue_dark"/>
<ExpandableListView <ExpandableListView
android:id="@+id/gatt_services_list" android:id="@+id/gatt_services_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_above="@id/lowerSepparator" android:layout_above="@id/lowerSepparator"
android:layout_below="@id/upperSepparator" /> android:layout_below="@id/upperSepparator"/>
</RelativeLayout> </RelativeLayout>
@@ -7,14 +7,14 @@
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > tools:context=".MainActivity">
<GridLayout <GridLayout
android:id="@+id/gridLayout1" android:id="@+id/gridLayout1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:columnCount="2" android:columnCount="2"
android:paddingBottom="@dimen/activity_vertical_margin" > android:paddingBottom="@dimen/activity_vertical_margin">
<TextView <TextView
android:layout_column="0" android:layout_column="0"
@@ -22,7 +22,7 @@
android:layout_row="0" android:layout_row="0"
android:text="@string/label_bluetooth_le_status" android:text="@string/label_bluetooth_le_status"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/tvBluetoothLe" android:id="@+id/tvBluetoothLe"
@@ -33,7 +33,7 @@
android:layout_row="0" android:layout_row="0"
android:gravity="right" android:gravity="right"
android:text="@string/not_supported" android:text="@string/not_supported"
android:textSize="12sp" /> android:textSize="12sp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -43,7 +43,7 @@
android:layout_row="1" android:layout_row="1"
android:text="@string/label_bluetooth_status" android:text="@string/label_bluetooth_status"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/tvBluetoothStatus" android:id="@+id/tvBluetoothStatus"
@@ -54,59 +54,59 @@
android:layout_row="1" android:layout_row="1"
android:gravity="right" android:gravity="right"
android:text="@string/off" android:text="@string/off"
android:textSize="12sp" /> android:textSize="12sp"/>
</GridLayout> </GridLayout>
<View <View
android:id="@+id/upperSepparator" android:id="@+id/upperSepparator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:background="@android:color/holo_blue_dark" /> android:background="@android:color/holo_blue_dark"/>
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" > android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/infoContainer" android:id="@+id/infoContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:orientation="vertical" > android:orientation="vertical">
<View <View
android:id="@+id/lowerSepparator" android:id="@+id/lowerSepparator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:background="@android:color/holo_blue_dark" /> android:background="@android:color/holo_blue_dark"/>
<TextView <TextView
android:id="@+id/tvItemCount" android:id="@+id/tvItemCount"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/formatter_item_count" /> android:text="@string/formatter_item_count"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/listContainer" android:id="@+id/listContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_above="@id/infoContainer" android:layout_above="@id/infoContainer"
android:orientation="vertical" > android:layout_alignParentTop="true"
android:orientation="vertical">
<ListView <ListView
android:id="@android:id/list" android:id="@android:id/list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"/>
<TextView <TextView
android:id="@android:id/empty" android:id="@android:id/empty"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal" android:gravity="center_vertical|center_horizontal"
android:text="@string/no_data" /> android:text="@string/no_data"/>
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
@@ -18,31 +18,31 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="horizontal" > android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/device_icon" android:id="@+id/device_icon"
android:paddingTop="5dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:src="@drawable/ic_bluetooth" /> android:paddingTop="5dp"
android:src="@drawable/ic_bluetooth"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" > android:orientation="vertical">
<TextView <TextView
android:id="@+id/device_name" android:id="@+id/device_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="24sp" /> android:textSize="24sp"/>
<GridLayout <GridLayout
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:columnCount="2" > android:columnCount="2">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -50,14 +50,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_mac" android:text="@string/label_mac"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/device_address" android:id="@+id/device_address"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="12sp" android:textSize="12sp"
android:typeface="monospace" /> android:typeface="monospace"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -65,14 +65,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="Updated:" android:text="Updated:"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/device_last_update" android:id="@+id/device_last_update"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -80,14 +80,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_rssi" android:text="@string/label_rssi"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/device_rssi" android:id="@+id/device_rssi"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
</GridLayout> </GridLayout>
<GridLayout <GridLayout
@@ -95,7 +95,7 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/light_gray" android:background="@color/light_gray"
android:columnCount="4" > android:columnCount="4">
<!-- ROW 1 --> <!-- ROW 1 -->
@@ -105,7 +105,7 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_uuid" android:text="@string/label_uuid"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/ibeacon_uuid" android:id="@+id/ibeacon_uuid"
@@ -113,7 +113,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_columnSpan="3" android:layout_columnSpan="3"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
<!-- ROW 2 --> <!-- ROW 2 -->
@@ -123,14 +123,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_major" android:text="@string/label_major"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/ibeacon_major" android:id="@+id/ibeacon_major"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -139,14 +139,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_minor" android:text="@string/label_minor"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/ibeacon_minor" android:id="@+id/ibeacon_minor"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
<!-- ROW 3 --> <!-- ROW 3 -->
@@ -156,14 +156,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_tx_power" android:text="@string/label_tx_power"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/ibeacon_tx_power" android:id="@+id/ibeacon_tx_power"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -172,14 +172,14 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_distance" android:text="@string/label_distance"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/ibeacon_distance" android:id="@+id/ibeacon_distance"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
<!-- ROW 4 --> <!-- ROW 4 -->
@@ -189,7 +189,7 @@
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="Descriptor:" android:text="Descriptor:"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/ibeacon_distance_descriptor" android:id="@+id/ibeacon_distance_descriptor"
@@ -197,7 +197,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_columnSpan="3" android:layout_columnSpan="3"
android:paddingRight="5dp" android:paddingRight="5dp"
android:textSize="12sp" /> android:textSize="12sp"/>
</GridLayout> </GridLayout>
</LinearLayout> </LinearLayout>
@@ -4,40 +4,40 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="5dp" > android:paddingBottom="5dp">
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<GridLayout <GridLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:columnCount="2" android:columnCount="2"
android:useDefaultMargins="true" > android:useDefaultMargins="true">
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_as_string" /> android:text="@string/label_as_string"/>
<TextView <TextView
android:id="@+id/data_as_string" android:id="@+id/data_as_string"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_as_array" /> android:text="@string/label_as_array"/>
<TextView <TextView
android:id="@+id/data_as_array" android:id="@+id/data_as_array"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
</GridLayout> </GridLayout>
</LinearLayout> </LinearLayout>
@@ -4,53 +4,53 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="5dp" > android:paddingBottom="5dp">
<GridLayout <GridLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:columnCount="2" android:columnCount="2"
android:useDefaultMargins="true" > android:useDefaultMargins="true">
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_device_name" /> android:text="@string/label_device_name"/>
<TextView <TextView
android:id="@+id/deviceName" android:id="@+id/deviceName"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_device_address" /> android:text="@string/label_device_address"/>
<TextView <TextView
android:id="@+id/deviceAddress" android:id="@+id/deviceAddress"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_device_class" /> android:text="@string/label_device_class"/>
<TextView <TextView
android:id="@+id/deviceClass" android:id="@+id/deviceClass"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_bonding_state" /> android:text="@string/label_bonding_state"/>
<TextView <TextView
android:id="@+id/deviceBondingState" android:id="@+id/deviceBondingState"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
</GridLayout> </GridLayout>
</LinearLayout> </LinearLayout>
@@ -4,7 +4,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="5dp" > android:paddingBottom="5dp">
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
@@ -13,11 +13,11 @@
android:textAllCaps="true" android:textAllCaps="true"
android:textColor="@android:color/holo_blue_dark" android:textColor="@android:color/holo_blue_dark"
android:textSize="14sp" android:textSize="14sp"
android:textStyle="bold" /> android:textStyle="bold"/>
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:background="@android:color/holo_blue_dark" /> android:background="@android:color/holo_blue_dark"/>
</LinearLayout> </LinearLayout>
@@ -4,73 +4,73 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="5dp" > android:paddingBottom="5dp">
<GridLayout <GridLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:columnCount="2" android:columnCount="2"
android:useDefaultMargins="true" > android:useDefaultMargins="true">
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_company_id" /> android:text="@string/label_company_id"/>
<TextView <TextView
android:id="@+id/companyId" android:id="@+id/companyId"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_advertisement" /> android:text="@string/label_advertisement"/>
<TextView <TextView
android:id="@+id/advertisement" android:id="@+id/advertisement"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_uuid" /> android:text="@string/label_uuid"/>
<TextView <TextView
android:id="@+id/uuid" android:id="@+id/uuid"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_major" /> android:text="@string/label_major"/>
<TextView <TextView
android:id="@+id/major" android:id="@+id/major"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_minor" /> android:text="@string/label_minor"/>
<TextView <TextView
android:id="@+id/minor" android:id="@+id/minor"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_tx_power" /> android:text="@string/label_tx_power"/>
<TextView <TextView
android:id="@+id/txpower" android:id="@+id/txpower"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
</GridLayout> </GridLayout>
</LinearLayout> </LinearLayout>
@@ -4,63 +4,63 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="5dp" > android:paddingBottom="5dp">
<GridLayout <GridLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:columnCount="2" android:columnCount="2"
android:useDefaultMargins="true" > android:useDefaultMargins="true">
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_first_timestamp" /> android:text="@string/label_first_timestamp"/>
<TextView <TextView
android:id="@+id/firstTimestamp" android:id="@+id/firstTimestamp"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_first_rssi" /> android:text="@string/label_first_rssi"/>
<TextView <TextView
android:id="@+id/firstRssi" android:id="@+id/firstRssi"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_last_timestamp" /> android:text="@string/label_last_timestamp"/>
<TextView <TextView
android:id="@+id/lastTimestamp" android:id="@+id/lastTimestamp"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_last_rssi" /> android:text="@string/label_last_rssi"/>
<TextView <TextView
android:id="@+id/lastRssi" android:id="@+id/lastRssi"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
<TextView <TextView
style="@style/GridLayoutTitleTextView" style="@style/GridLayoutTitleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_running_average_rssi" /> android:text="@string/label_running_average_rssi"/>
<TextView <TextView
android:id="@+id/runningAverageRssi" android:id="@+id/runningAverageRssi"
style="@style/GridLayoutDataTextView" /> style="@style/GridLayoutDataTextView"/>
</GridLayout> </GridLayout>
</LinearLayout> </LinearLayout>
@@ -4,10 +4,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:gravity="top"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="5dp" > android:paddingBottom="5dp">
<TextView <TextView
android:id="@+id/data" android:id="@+id/data"
style="@style/GridLayoutDataTextViewMonospace" /> style="@style/GridLayoutDataTextViewMonospace"/>
</LinearLayout> </LinearLayout>
+1 -1
View File
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/menu_refresh" android:id="@+id/menu_refresh"
+2 -2
View File
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/menu_refresh" android:id="@+id/menu_refresh"
@@ -33,9 +33,9 @@
android:title="@string/menu_stop"/> android:title="@string/menu_stop"/>
<item <item
android:id="@+id/menu_share" android:id="@+id/menu_share"
android:icon="@drawable/ic_action_share"
android:orderInCategory="102" android:orderInCategory="102"
android:showAsAction="ifRoom" android:showAsAction="ifRoom"
android:icon="@drawable/ic_action_share"
android:title="@string/menu_share"/> android:title="@string/menu_share"/>
<item <item
android:id="@+id/menu_about" android:id="@+id/menu_about"