2017-02-07 12 views
1

問題ビーコン+ Bluetooth通信は、私は、特定のIDでビーコンを発している周辺機器をした

微細[BLE]を動作していません。私のスマートフォン(それは中心的役割を担っています)は、周辺機器のビーコンを探しています。正しいビーコンが見つかると、GATTプロファイルを介してBluetooth通信を開始します。 デバイスが初めて接続されたとき、データが正しく送信されますが、2回目(2つのデバイスを20秒ごとに接続しようとするタイマーがあります)、接続が失敗します。わかりませんなぜ...私はアプリのプロセスを終了し、再びそれを動作させるためにそれを開く必要があります。私はビーコンについて

をやった

、私はaltbeaconを使用しているので、中央装置におけるビーコン検出のためのコードはこれです:

@Override public void onBeaconServiceConnect() { beaconManager.setRangeNotifier(new RangeNotifier() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { Log.i(TAG, "Beacon detected!"); if (beacons.size() > 0 && Utils.getUserData(getApplicationContext(), "id").compareTo("-1") != 0) { if(region.getId1().compareTo(Identifier.parse(identifier))==0) { Beacon beacon = beacons.iterator().next(); Log.i(TAG, "The first beacon I see is about " + beacon.getDistance() + " meters away. " + region.getId1()); String mac = beacon.getBluetoothAddress(); Log.i("MAC", "MAC: "+mac); CustomBluetoothManager customBluetoothManager = CustomBluetoothManager.getInstance(getApplicationContext()); if(!customBluetoothManager.isScanning()) { customBluetoothManager.scanLeDevice(true, mac); } } } } }); try { beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", Identifier.parse(identifier), null, null)); } catch (RemoteException e) { } } 

ビーコンが発見された

、その後、scanLeDeviceが呼び出されます。

public void scanLeDevice(final boolean enable, String mac) { 
    target_mac = mac; 
    mHandler = new Handler(); 

    if (enable) { 
     // Stops scanning after a pre-defined scan period. 
     mHandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       mScanning = false; 
       mBluetoothAdapter.stopLeScan(mLeScanCallback); 
      } 
     }, SCAN_PERIOD); 

     mScanning = true; 
     mBluetoothAdapter.startLeScan(mLeScanCallback); 
    } else { 
     mScanning = false; 
     mBluetoothAdapter.stopLeScan(mLeScanCallback); 
    } 
} 

、ここではmLeScanCallbackコードです:

private BluetoothAdapter.LeScanCallback mLeScanCallback = 
     new BluetoothAdapter.LeScanCallback() { 
      @Override 
      public void onLeScan(final BluetoothDevice device, int rssi, 
           byte[] scanRecord) { 
       long epoch = System.currentTimeMillis()/1000; 
       SharedPreferences prefs = context.getSharedPreferences(
         "epoch", Context.MODE_PRIVATE); 
       long epochStored = prefs.getLong("epoch", 0); 

       if (device.getAddress().compareTo(MAC) == 0 && after20Seconds) { 
        prefs.edit().putLong("epoch", epoch).apply(); 
        Log.d("epoch", Long.toString(epoch)); 
        mDeviceAddress = device.getAddress(); 
        final Intent gattServiceIntent = new Intent(context, BluetoothLeService.class); 
        context.bindService(gattServiceIntent, mServiceConnection, context.BIND_AUTO_CREATE); 
       } 
      } 
     }; 

ビーコンがパケットに含まれているMACアドレスが実際のデバイスMACと同じではないため、MACアドレスをハードコードする必要がありました(これはBLE定義のものですが、できます)。

データが送信されたときに最後に、私は閉じて、ブルートゥースチャネルを切断し、私はあまりにもサービスのバインドを解除しようとしましたが、何も動作:

@Override 
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { 
     super.onCharacteristicWrite(gatt, characteristic, status); 
     disconnect(); 
     close(); 
     unbindService(mServiceConnection); 
    } 

ので、このコードで、初めてデバイスが接続されているデータが正しく送信されますが、20秒後、2回目の試行では、決して通信を確立しません。

質問

  1. 問題は何ができるかの任意のアイデア?
  2. BLEのしくみビーコンパケットでは、MACはセキュリティ上の理由から偽装されています。しかし、私がビーコンスキャンアプリからそれを取得し、それをアプリにハードコードすると、コミュニケーションは機能します...私はそれがうまくいかないと思います。
  3. ビーコンパケットから正しいデバイスMACを取得するにはどうすればよいですか?
  4. Bluetooth通信でビーコンを使用するサンプルがありますか?
  5. 私は「mBluetoothAdapter.stopLeScan(mLeScanCallback)」メソッドを介してスキャンを停止すると、スキャンが実際に停止していないこと...それは普通のことだと思われますか?ログはに常時 "BluetoothLeScannerを:startRegisteration:mLeScanClients = {org.altbeacon.beacon.service.scanner.CycledLeScannerForLollipop $ @ 4 5445b45 = android.bluetooth.le.BluetoothLeScanner ......" と表示され
+0

なぜaltbeaconが必要ですか?私が理解しているところから。あなたの要件はgattの中央と周辺の役割に基づいており、デバイスのMAC IDの周りを回っています。 (その間、私はなぜその問題が2回目に似ているか覚えています) – user2450263

+0

あなたの返事をありがとう!ユーザーが周辺機器の近くにいることを知るためにはビーコンが必要です。この方法で、アプリがユーザーの周りにあるBluetoothデバイスを連続してスキャンすることを避けることができます。 – adri1992

+0

'scanLeDevice'とそのコールバックはとにかく、proximityのrssi値を計算する必要があります - ユーザーがデバイスの近くにいるかどうかを計算する – user2450263

答えて

1

あなたはAndroid BLE APIを使用してMACアドレスを読み取ることができません。ご存じのように、OSによって実際のMACにマッピングされている偽のMACで偽装されます。だから、この行は信頼できません。

device.getAddress().compareTo(MAC) == 0

これは、接続が第二の歯を失敗する原因となっているかもしれません。最初の起動時に動作するということは驚くべきことです。おそらく、AndroidのMACスプーフィングローテーションアルゴリズムの決定的な実装のためだけです。 2番目の接続が機能しないという事実

接続する正しいデバイスを、おそらくビーコン識別子で見つける別の方法が必要です。

これは典型的な使用例ではないため、ビーコンに接続するためのサンプルコードを見つけるのは難しいです。典型的には、それらは設計されているように送信専用デバイスとして扱われる。これは、Android Beacon LibraryがBLEサービスに接続するツールを提供しない理由です。すべてのビーコンメーカーに標準実装はありません。つまり、あなたのカスタムアプローチは合理的です。

Androidビーコンライブラリがビーコンを検出するために独自のBluetoothスキャンを行っていることを理解してください。このため、スキャンを停止しても、ログにスキャン結果が表示されます。これは図書館からのものです。

完全な開示:私は、Android Beacon Libraryのオープンソースプロジェクトの開発者です。

+0

この返信と前に受け取ったあなたの助けに感謝したいと思います。私はRadiusNetworks android ibeaconライブラリをAppleの著作権/商標の取り締まりの後に使用しています。 Altbeaconとeddystoneの実装はそれ以来ずっと進んでいます。 私はこの特定の質問の実装は、[BluetoothGatt](https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html)および関連するクラスに関連すると言います。 – user2450263

関連する問題