zhuguifei
2025-12-30 61eee1173c00a7ba9d9c748d28fe3acdb33b9441
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.blakequ.bluetooth_manager_lib.device.ibeacon;
 
 
import com.blakequ.bluetooth_manager_lib.util.ByteUtils;
 
final class IBeaconUtils {
    private static final double DISTANCE_THRESHOLD_WTF = 0.0;
    private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
    private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
 
    private IBeaconUtils(){
        // TO AVOID INSTANTIATION
    }
 
    /**
     * Calculates the accuracy of an RSSI reading.
     * <p/>
     * The code was taken from <a href="http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing" /a>
     *
     * @param txPower the calibrated TX power of an iBeacon
     * @param rssi    the RSSI value of the iBeacon
     * @return the calculated Accuracy
     */
    public static double calculateAccuracy(final int txPower, final double rssi) {
        if (rssi == 0) {
            return -1.0; // if we cannot determine accuracy, return -1.
        }
 
        final double ratio = rssi * 1.0 / txPower;
        if (ratio < 1.0) {
            return Math.pow(ratio, 10);
        } else {
            return (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
        }
    }
 
    public static String calculateUuidString(final byte[] uuid) {
        final StringBuilder sb = new StringBuilder();
 
        for (int i = 0; i < uuid.length; i++) {
            if (i == 4) {
                sb.append('-');
            }
            if (i == 6) {
                sb.append('-');
            }
            if (i == 8) {
                sb.append('-');
            }
            if (i == 10) {
                sb.append('-');
            }
 
            final int intFromByte = ByteUtils.getIntFromByte(uuid[i]);
            if(intFromByte <= 0xF){
                sb.append('0');
            }
            sb.append(Integer.toHexString(intFromByte));
        }
 
 
        return sb.toString();
    }
 
    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;
    }
}