在这里,我有Github Repo https://github.com/youten/BLERW/,其中包含一些有关如何扫描读取BLE设备RSSI并将其连接的代码Android程序。 在扫描菜单中,它使应用程序可以扫描附近的每个BLE设备。
在这种情况下,我只想按名称或地址扫描读取特定/标识的BLE设备,但是我不知道如何将其放入程序中。希望你们能帮助我。
Device Adapter.java
package youten.redo.ble.readwrite;
import java.util.List;
import youten.redo.ble.util.ScannedDevice;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**
* スキャンされたBLEデバイスリストのAdapter
*/
public class DeviceAdapter extends ArrayAdapter<ScannedDevice> {
private static final String PREFIX_RSSI = "RSSI:";
private List<ScannedDevice> mList;
private LayoutInflater mInflater;
private int mResId;
public DeviceAdapter(Context context, int resId, List<ScannedDevice> objects) {
super(context, resId, objects);
mResId = resId;
mList = objects;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ScannedDevice item = (ScannedDevice) getItem(position);
if (convertView == null) {
convertView = mInflater.inflate(mResId, null);
}
TextView name = (TextView) convertView.findViewById(R.id.device_name);
name.setText(item.getDisplayName());
TextView address = (TextView) convertView.findViewById(R.id.device_address);
address.setText(item.getDevice().getAddress());
TextView rssi = (TextView) convertView.findViewById(R.id.device_rssi);
rssi.setText(PREFIX_RSSI + Integer.toString(item.getRssi()));
return convertView;
}
/** add or update BluetoothDevice */
public void update(BluetoothDevice newDevice, int rssi, byte[] scanRecord) {
if ((newDevice == null) || (newDevice.getAddress() == null)) {
return;
}
boolean contains = false;
for (ScannedDevice device : mList) {
if (newDevice.getAddress().equals(device.getDevice().getAddress())) {
contains = true;
device.setRssi(rssi); // update
break;
}
}
if (!contains) {
// add new BluetoothDevice
mList.add(new ScannedDevice(newDevice, rssi));
}
notifyDataSetChanged();
}
}
DeviceActivity.java
package youten.redo.ble.readwrite;
import java.util.UUID;
import youten.redo.ble.util.BleUtil;
import youten.redo.ble.util.BleUuid;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
/**
* BLEデバイスへのconnect・Service
* Discoveryを実施し、Characteristicsのread/writeをハンドリングするActivity
*/
public class DeviceActivity extends Activity implements View.OnClickListener {
private static final String TAG = "BLEDevice";
public static final String EXTRA_BLUETOOTH_DEVICE = "BT_DEVICE";
private BluetoothAdapter mBTAdapter;
private BluetoothDevice mDevice;
private BluetoothGatt mConnGatt;
private int mStatus;
private Button mReadManufacturerNameButton;
private Button mReadSerialNumberButton;
private Button mWriteAlertLevelButton;
private final BluetoothGattCallback mGattcallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mStatus = newState;
mConnGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mStatus = newState;
runOnUiThread(new Runnable() {
public void run() {
mReadManufacturerNameButton.setEnabled(false);
mReadSerialNumberButton.setEnabled(false);
mWriteAlertLevelButton.setEnabled(false);
};
});
}
};
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
for (BluetoothGattService service : gatt.getServices()) {
if ((service == null) || (service.getUuid() == null)) {
continue;
}
if (BleUuid.SERVICE_DEVICE_INFORMATION.equalsIgnoreCase(service
.getUuid().toString())) {
mReadManufacturerNameButton
.setTag(service.getCharacteristic(UUID
.fromString(BleUuid.CHAR_MANUFACTURER_NAME_STRING)));
mReadSerialNumberButton
.setTag(service.getCharacteristic(UUID
.fromString(BleUuid.CHAR_SERIAL_NUMBEAR_STRING)));
runOnUiThread(new Runnable() {
public void run() {
mReadManufacturerNameButton.setEnabled(true);
mReadSerialNumberButton.setEnabled(true);
};
});
}
if (BleUuid.SERVICE_IMMEDIATE_ALERT.equalsIgnoreCase(service
.getUuid().toString())) {
runOnUiThread(new Runnable() {
public void run() {
mWriteAlertLevelButton.setEnabled(true);
};
});
mWriteAlertLevelButton.setTag(service
.getCharacteristic(UUID
.fromString(BleUuid.CHAR_ALERT_LEVEL)));
}
}
runOnUiThread(new Runnable() {
public void run() {
setProgressBarIndeterminateVisibility(false);
};
});
};
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (BleUuid.CHAR_MANUFACTURER_NAME_STRING
.equalsIgnoreCase(characteristic.getUuid().toString())) {
final String name = characteristic.getStringValue(0);
runOnUiThread(new Runnable() {
public void run() {
mReadManufacturerNameButton.setText(name);
setProgressBarIndeterminateVisibility(false);
};
});
} else if (BleUuid.CHAR_SERIAL_NUMBEAR_STRING
.equalsIgnoreCase(characteristic.getUuid().toString())) {
final String name = characteristic.getStringValue(0);
runOnUiThread(new Runnable() {
public void run() {
mReadSerialNumberButton.setText(name);
setProgressBarIndeterminateVisibility(false);
};
});
}
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
runOnUiThread(new Runnable() {
public void run() {
setProgressBarIndeterminateVisibility(false);
};
});
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_device);
// state
mStatus = BluetoothProfile.STATE_DISCONNECTED;
mReadManufacturerNameButton = (Button) findViewById(R.id.read_manufacturer_name_button);
mReadManufacturerNameButton.setOnClickListener(this);
mReadSerialNumberButton = (Button) findViewById(R.id.read_serial_number_button);
mReadSerialNumberButton.setOnClickListener(this);
mWriteAlertLevelButton = (Button) findViewById(R.id.write_alert_level_button);
mWriteAlertLevelButton.setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
init();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mConnGatt != null) {
if ((mStatus != BluetoothProfile.STATE_DISCONNECTING)
&& (mStatus != BluetoothProfile.STATE_DISCONNECTED)) {
mConnGatt.disconnect();
}
mConnGatt.close();
mConnGatt = null;
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.read_manufacturer_name_button) {
if ((v.getTag() != null)
&& (v.getTag() instanceof BluetoothGattCharacteristic)) {
BluetoothGattCharacteristic ch = (BluetoothGattCharacteristic) v
.getTag();
if (mConnGatt.readCharacteristic(ch)) {
setProgressBarIndeterminateVisibility(true);
}
}
} else if (v.getId() == R.id.read_serial_number_button) {
if ((v.getTag() != null)
&& (v.getTag() instanceof BluetoothGattCharacteristic)) {
BluetoothGattCharacteristic ch = (BluetoothGattCharacteristic) v
.getTag();
if (mConnGatt.readCharacteristic(ch)) {
setProgressBarIndeterminateVisibility(true);
}
}
} else if (v.getId() == R.id.write_alert_level_button) {
if ((v.getTag() != null)
&& (v.getTag() instanceof BluetoothGattCharacteristic)) {
BluetoothGattCharacteristic ch = (BluetoothGattCharacteristic) v
.getTag();
ch.setValue(new byte[] { (byte) 0x03 });
if (mConnGatt.writeCharacteristic(ch)) {
setProgressBarIndeterminateVisibility(true);
}
}
}
}
private void init() {
// BLE check
if (!BleUtil.isBLESupported(this)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT)
.show();
finish();
return;
}
// BT check
BluetoothManager manager = BleUtil.getManager(this);
if (manager != null) {
mBTAdapter = manager.getAdapter();
}
if (mBTAdapter == null) {
Toast.makeText(this, R.string.bt_unavailable, Toast.LENGTH_SHORT)
.show();
finish();
return;
}
// check BluetoothDevice
if (mDevice == null) {
mDevice = getBTDeviceExtra();
if (mDevice == null) {
finish();
return;
}
}
// button disable
mReadManufacturerNameButton.setEnabled(false);
mReadSerialNumberButton.setEnabled(false);
mWriteAlertLevelButton.setEnabled(false);
// connect to Gatt
if ((mConnGatt == null)
&& (mStatus == BluetoothProfile.STATE_DISCONNECTED)) {
// try to connect
mConnGatt = mDevice.connectGatt(this, false, mGattcallback);
mStatus = BluetoothProfile.STATE_CONNECTING;
} else {
if (mConnGatt != null) {
// re-connect and re-discover Services
mConnGatt.connect();
mConnGatt.discoverServices();
} else {
Log.e(TAG, "state error");
finish();
return;
}
}
setProgressBarIndeterminateVisibility(true);
}
private BluetoothDevice getBTDeviceExtra() {
Intent intent = getIntent();
if (intent == null) {
return null;
}
Bundle extras = intent.getExtras();
if (extras == null) {
return null;
}
return extras.getParcelable(EXTRA_BLUETOOTH_DEVICE);
}
}
ScanActivity.java
package youten.redo.ble.readwrite;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.RuntimePermissions;
import youten.redo.ble.util.BleUtil;
import youten.redo.ble.util.ScannedDevice;
/**
* BLEデバイスをスキャンし、一覧に表示するActivity。
*/
@RuntimePermissions
public class ScanActivity extends Activity implements BluetoothAdapter.LeScanCallback {
private BluetoothAdapter mBTAdapter;
private DeviceAdapter mDeviceAdapter;
private boolean mIsScanning;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_scan);
init();
}
@Override
protected void onDestroy() {
super.onDestroy();
stopScan();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mIsScanning) {
menu.findItem(R.id.action_scan).setVisible(false);
menu.findItem(R.id.action_stop).setVisible(true);
} else {
menu.findItem(R.id.action_scan).setVisible(true);
menu.findItem(R.id.action_stop).setVisible(false);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
// ignore
return true;
} else if (itemId == R.id.action_scan) {
ScanActivityPermissionsDispatcher.startScanWithPermissionCheck(this);
return true;
} else if (itemId == R.id.action_stop) {
stopScan();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onLeScan(final BluetoothDevice newDeivce, final int newRssi,
final byte[] newScanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mDeviceAdapter.update(newDeivce, newRssi, newScanRecord);
}
});
}
private void init() {
// BLE check
if (!BleUtil.isBLESupported(this)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
// BT check
BluetoothManager manager = BleUtil.getManager(this);
if (manager != null) {
mBTAdapter = manager.getAdapter();
}
if (mBTAdapter == null) {
Toast.makeText(this, R.string.bt_unavailable, Toast.LENGTH_SHORT).show();
finish();
return;
}
if (!mBTAdapter.isEnabled()) {
Toast.makeText(this, R.string.bt_disabled, Toast.LENGTH_SHORT).show();
finish();
return;
}
// init listview
ListView deviceListView = (ListView) findViewById(R.id.list);
mDeviceAdapter = new DeviceAdapter(this, R.layout.listitem_device,
new ArrayList<ScannedDevice>());
deviceListView.setAdapter(mDeviceAdapter);
deviceListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterview, View view, int position, long id) {
ScannedDevice item = mDeviceAdapter.getItem(position);
if (item != null) {
Intent intent = new Intent(view.getContext(), DeviceActivity.class);
BluetoothDevice selectedDevice = item.getDevice();
intent.putExtra(DeviceActivity.EXTRA_BLUETOOTH_DEVICE, selectedDevice);
startActivity(intent);
// stop before change Activity
stopScan();
}
}
});
stopScan();
}
@NeedsPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
void startScan() {
if ((mBTAdapter != null) && (!mIsScanning)) {
mBTAdapter.startLeScan(this);
mIsScanning = true;
setProgressBarIndeterminateVisibility(true);
invalidateOptionsMenu();
}
}
private void stopScan() {
if (mBTAdapter != null) {
mBTAdapter.stopLeScan(this);
}
mIsScanning = false;
setProgressBarIndeterminateVisibility(false);
invalidateOptionsMenu();
}
}