iBeacon,摇一摇

判断手机是否支持蓝牙,是否开启蓝牙

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (bluetoothAdapter == null) {
//                            Intent intent = new Intent(getActivity(), ShackActivity.class);
//                            startActivity(intent);
            Toast.makeText(getActivity(), "您的手机不支持寻宝活动",Toast.LENGTH_SHORT).show();
        } else if (!bluetoothAdapter.isEnabled()){
            final AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).create();
            alertDialog.show();
            alertDialog.getWindow().setContentView(R.layout.bluetooth_enable_dialog);
            TextView buttonOpenBlueTooth = (TextView) alertDialog.getWindow().findViewById(R.id.openbluetooth);
            buttonOpenBlueTooth.requestFocus();
            buttonOpenBlueTooth.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startActivityForResult(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS), BLUETOOTH_SETTING);
                    alertDialog.dismiss();
                }
            });
            TextView buttonIgnorebluetooth =  (TextView)alertDialog.getWindow().findViewById(R.id.ignorebluetooth);
            buttonIgnorebluetooth.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    alertDialog.dismiss();
                }
            });


        }else {
            Intent intent2 = new Intent(getActivity(), ShackActivity.class);
            startActivity(intent2);
        }

ShackActivity 摇一摇界面

public class ShackActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager sensorManager;
    private Vibrator vibrator;
    private int shackCount = 0;

    private long lastScanTime = 0;
    private long lastShowTime = 0;

    //iBeacon参数
    private int major=6101;
    private String UUID = "fda50693-a4e2-4fb1-afcf-c6eb07647825";


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.shake_activity);
        //获取到系统服务
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);


    }



    @Override
    protected void onResume() {
        super.onResume();

        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
        handler.removeMessages(0);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        int sensorType = event.sensor.getType();
        //values[0]:X轴,values[1]:Y轴,values[2]:Z轴
        float[] values = event.values;
        if (sensorType == Sensor.TYPE_ACCELEROMETER) {
            if ((Math.abs(values[0]) > 17 || Math.abs(values[1]) > 17 || Math
                    .abs(values[2]) > 17)) {
                shackCount++;


                //记录大于17的次数
                if (shackCount == 2) {
                    shackCount = 0;
                    //震动的毫秒数
                    vibrator.vibrate(500);
                    //记录最后一次摇动的时间
                    lastScanTime = System.currentTimeMillis();
                    //扫描蓝牙
                    scanBeacon();
                } else if (shackCount == 0) {
                }

            }
        }

    }


    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    private int REQUEST_OPEN_BT_CODE = 1;
    private boolean mScanning = false;
    private BleDevicesScanner mScanner = null;
    private Map<String, Integer> ibeaconMap = new HashMap<>();
    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            mScanner.stop();
            mScanning = false;
            dealWithBeacons();
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_OPEN_BT_CODE && resultCode == RESULT_OK) {
            scanBeacon();
        } else if (requestCode == REQUEST_OPEN_BT_CODE && resultCode != RESULT_OK) {
            Toast.makeText(this, "Failed to open the BlueTooth!", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 扫描蓝牙信息
     */
    private void scanBeacon() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            return;
        }
        if (mScanning) {
            return;
        }
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!bluetoothAdapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_OPEN_BT_CODE);
            return;
        }
        ibeaconMap.clear();
        mScanner = new BleDevicesScanner(bluetoothAdapter,
                new BluetoothAdapter.LeScanCallback() {

                    @Override
                    public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {

                        final iBeaconClass.iBeacon ibeacon = iBeaconClass.fromScanData(device, rssi, scanRecord);

                        //对扫描到的蓝牙进行赛选
                        if (ibeacon != null && ibeacon.proximityUuid.equals(UUID)&&major==ibeacon.major) {
                            String bleName = ibeacon.proximityUuid + "-" + ibeacon.major + "-" + ibeacon.minor;

                            //将符合条件的蓝牙进行加入map中进行后续处理
                            ibeaconMap.put(bleName, ibeacon.rssi);

                        }
                    }
                });
        //设置扫描时长,单位毫秒,默认 10 秒
        mScanner.setScanPeriod(500);
        mScanner.start();

        //扫描一秒后将扫描到的蓝牙信息进行处理
        handler.sendEmptyMessageDelayed(0, 1000);
        mScanning = true;
    }

    /**
     * 对符合条件的蓝牙信息进行处理
     */
    private void dealWithBeacons() {
        long currentTime = System.currentTimeMillis();

        //符合条件的蓝牙信息为0时
        if (ibeaconMap.size() == 0) {
            if (currentTime - lastScanTime < 3000) {
                scanBeacon();
            } else {



            }
        } else {
            //扫描间隔时间小于3秒
            if (currentTime - lastShowTime < 3000) {
                return;
            }
            int maxrssi = -100;
            String maxbeacon = "";
            //选出信号最好的一个进行处理
            for (String key : ibeaconMap.keySet()) {
                if (ibeaconMap.get(key) > maxrssi) {
                    maxbeacon = key;
                    maxrssi = ibeaconMap.get(key);
                }
            }
//获取到信号最好的一个传到服务器
//            matchBeacon(maxbeacon);
        }
    }




    @Override
    protected void onDestroy() {
        super.onDestroy();
    }


}

iBeaconClass

public class iBeaconClass {

    static public class iBeacon {
        public String name;
        public int major;
        public int minor;
        public String proximityUuid;
        public String bluetoothAddress;
        public int txPower;
        public int rssi;
    }

    public static iBeacon fromScanData(BluetoothDevice device, int rssi,
                                       byte[] scanData) {

        int startByte = 2;
        boolean patternFound = false;
        while (startByte <= 5) {
            if (((int) scanData[startByte + 2] & 0xff) == 0x02
                    && ((int) scanData[startByte + 3] & 0xff) == 0x15) {
                // yes! This is an iBeacon
                patternFound = true;
                break;
            } else if (((int) scanData[startByte] & 0xff) == 0x2d
                    && ((int) scanData[startByte + 1] & 0xff) == 0x24
                    && ((int) scanData[startByte + 2] & 0xff) == 0xbf
                    && ((int) scanData[startByte + 3] & 0xff) == 0x16) {
                iBeacon iBeacon = new iBeacon();
                iBeacon.major = 0;
                iBeacon.minor = 0;
                iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000";
                iBeacon.txPower = -55;
                return iBeacon;
            } else if (((int) scanData[startByte] & 0xff) == 0xad
                    && ((int) scanData[startByte + 1] & 0xff) == 0x77
                    && ((int) scanData[startByte + 2] & 0xff) == 0x00
                    && ((int) scanData[startByte + 3] & 0xff) == 0xc6) {

                iBeacon iBeacon = new iBeacon();
                iBeacon.major = 0;
                iBeacon.minor = 0;
                iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000";
                iBeacon.txPower = -55;
                return iBeacon;
            }
            startByte++;
        }

        if (patternFound == false) {
            // This is not an iBeacon
            return null;
        }

        iBeacon iBeacon = new iBeacon();

        iBeacon.major = (scanData[startByte + 20] & 0xff) * 0x100
                + (scanData[startByte + 21] & 0xff);
        iBeacon.minor = (scanData[startByte + 22] & 0xff) * 0x100
                + (scanData[startByte + 23] & 0xff);
        iBeacon.txPower = (int) scanData[startByte + 24]; // this one is signed
        iBeacon.rssi = rssi;

        // AirLocate:
        // 02 01 1a 1a ff 4c 00 02 15 # Apple's fixed iBeacon advertising prefix
        // e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile
        // uuid
        // 00 00 # major
        // 00 00 # minor
        // c5 # The 2's complement of the calibrated Tx Power

        // Estimote:
        // 02 01 1a 11 07 2d 24 bf 16
        // 394b31ba3f486415ab376e5c0f09457374696d6f7465426561636f6e00000000000000000000000000000000000000000000000000

        byte[] proximityUuidBytes = new byte[16];
        System.arraycopy(scanData, startByte + 4, proximityUuidBytes, 0, 16);
        String hexString = bytesToHexString(proximityUuidBytes);
        StringBuilder sb = new StringBuilder();
        sb.append(hexString.substring(0, 8));
        sb.append("-");
        sb.append(hexString.substring(8, 12));
        sb.append("-");
        sb.append(hexString.substring(12, 16));
        sb.append("-");
        sb.append(hexString.substring(16, 20));
        sb.append("-");
        sb.append(hexString.substring(20, 32));
        iBeacon.proximityUuid = sb.toString();

        if (device != null) {
            iBeacon.bluetoothAddress = device.getAddress();
            iBeacon.name = device.getName();
        }

        return iBeacon;
    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
}

BleDevicesScanner

@SuppressLint("NewApi")
public class BleDevicesScanner implements Runnable, BluetoothAdapter.LeScanCallback {

    private static final String TAG = BleDevicesScanner.class.getSimpleName();

    private static final long DEFAULT_SCAN_PERIOD = 500L;
    public static final long PERIOD_SCAN_ONCE = -1;

    private final BluetoothAdapter bluetoothAdapter;
    private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
    private final LeScansPoster leScansPoster;

    private long scanPeriod = DEFAULT_SCAN_PERIOD;
    private Thread scanThread;
    private volatile boolean isScanning = false;

    public BleDevicesScanner(BluetoothAdapter adapter, BluetoothAdapter.LeScanCallback callback) {
        bluetoothAdapter = adapter;
        leScansPoster = new LeScansPoster(callback);
    }

    public synchronized void setScanPeriod(long scanPeriod) {
        this.scanPeriod = scanPeriod < 0 ? PERIOD_SCAN_ONCE : scanPeriod;
    }

    public boolean isScanning() {
        return scanThread != null && scanThread.isAlive();
    }

    public synchronized void start() {
        if (isScanning())
            return;

        if (scanThread != null) {
            scanThread.interrupt();
        }
        scanThread = new Thread(this);
        scanThread.setName(TAG);
        scanThread.start();
    }

    public synchronized void stop() {
        isScanning = false;
        if (scanThread != null) {
            scanThread.interrupt();
            scanThread = null;
        }
        bluetoothAdapter.stopLeScan(this);
    }

    public void run() {
        // TODO Auto-generated method stub
        try {
            isScanning = true;
            do {
                synchronized (this) {
                    bluetoothAdapter.startLeScan(this);
                }
                if (scanPeriod > 0)
                    Thread.sleep(scanPeriod);
                synchronized (this) {
                    bluetoothAdapter.stopLeScan(this);
                }
            } while (isScanning && scanPeriod > 0);
        } catch (InterruptedException ignore) {

        } finally {
            synchronized (this) {
                bluetoothAdapter.stopLeScan(this);
            }
        }

    }

    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
        // TODO Auto-generated method stub
        synchronized (leScansPoster) {
            leScansPoster.set(device, rssi, scanRecord);
            mainThreadHandler.post(leScansPoster);
        }
    }

    private static class LeScansPoster implements Runnable {
        private final BluetoothAdapter.LeScanCallback leScanCallback;

        private BluetoothDevice device;
        private int rssi;
        private byte[] scanRecord;

        private LeScansPoster(BluetoothAdapter.LeScanCallback leScanCallback) {
            this.leScanCallback = leScanCallback;
        }

        public void set(BluetoothDevice device, int rssi, byte[] scanRecord) {
            this.device = device;
            this.rssi = rssi;
            this.scanRecord = scanRecord;
        }


        public void run() {
            // TODO Auto-generated method stub
            leScanCallback.onLeScan(device, rssi, scanRecord);
        }

    }

}

需要的权限

 <!-- bluetooth -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    <uses-permission android:name="android.permission.VIBRATE"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值