iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
Android 4.3からBluetooth LEに対応したということで、Nexus 7 (2012)を使って、iBeaconの検出に挑戦してみた。
今回の記事は、各種ブログから得られた情報を参考にしているのだが、その大半は内容が似ている。つまり、元となる情報があるようだ。しかし、どれが元の情報なのか分からず、関連情報としてあげてみたが、それに元の情報が含まれているのか自身がない。含まれていない場合は、申し訳ない。
AndroidManifest.xmlファイルに特権を追加する。
<manifest ...>
...
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
...
</manifest>
BLUETOOTHでBLE機器との通信を。BLUETOOTH_ADMINでBLE機器の検出を。最後のは、BLE対応端末でのみ動作という意味だ。
MainActivity.javaに必要なクラスをインポートする。
import android.content.Context;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import android.content.pm.PackageManager;
import android.widget.Toast;
import android.util.Log;
インスタンス変数を宣言しておく。
private final String TAG = "Wibree-Main";
private BluetoothAdapter mBluetoothAdapter;
今回は、簡単なお試しなので、onCreate()メソッドに必要なコードを記述。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* BLE対応の確認 */
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "not support", Toast.LENGTH_SHORT).show();
finish();
}
/* Bluetooth Adapter */
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
/* Bluetooth LEデバイスの検索 */
mBluetoothAdapter.startLeScan(mLeScanCallback);
}
コールバックの実装。この部分は、参考にしたサイトのコードを丸写し。
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device,
int rssi,
byte[] scanRecord) {
if (scanRecord.length > 30) {
if ((scanRecord[5] == (byte)0x4c)
&& (scanRecord[6] == (byte)0x00)
&& (scanRecord[7] == (byte)0x02)
&& (scanRecord[8] == (byte)0x15)) {
String uuid = IntToHex2(scanRecord[9] & 0xff)
+ IntToHex2(scanRecord[10] & 0xff)
+ IntToHex2(scanRecord[11] & 0xff)
+ IntToHex2(scanRecord[12] & 0xff)
+ "-"
+ IntToHex2(scanRecord[13] & 0xff)
+ IntToHex2(scanRecord[14] & 0xff)
+ "-"
+ IntToHex2(scanRecord[15] & 0xff)
+ IntToHex2(scanRecord[16] & 0xff)
+ "-"
+ IntToHex2(scanRecord[17] & 0xff)
+ IntToHex2(scanRecord[18] & 0xff)
+ "-"
+ IntToHex2(scanRecord[19] & 0xff)
+ IntToHex2(scanRecord[20] & 0xff)
+ IntToHex2(scanRecord[21] & 0xff)
+ IntToHex2(scanRecord[22] & 0xff)
+ IntToHex2(scanRecord[23] & 0xff)
+ IntToHex2(scanRecord[24] & 0xff);
String major = IntToHex2(scanRecord[25] & 0xff) + IntToHex2(scanRecord[26] & 0xff);
String minor = IntToHex2(scanRecord[27] & 0xff) + IntToHex2(scanRecord[28] & 0xff);
Log.d(TAG, "uuid:" + uuid);
Log.d(TAG, "major:" + major);
Log.d(TAG, "minor:" + minor);
}
}
}
};
private String IntToHex2(int i) {
char hex_2[] = {Character.forDigit((i >> 4) & 0x0f,16),Character.forDigit(i&0x0f, 16)};
String hex_2_str = new String(hex_2);
return hex_2_str.toUpperCase();
}
iBeaconは、BLEのアドバタイズメントに情報を埋め込んでいるので、スキャンしたデータから識別子やメジャー/マイナー番号がとれる。
さあ、これを実機で実行だ!あれ?動かない。BLE対応の確認で引っかかる!
Nexus 7 (2012)は、ハード的にはBLE対応は可能みたいだが、OSで未対応としているみたい。試せなくで残念!