Java 如何与BLE沟通
我有以下工作代码,可以扫描并连接到可编程设备:Java 如何与BLE沟通,java,android,bluetooth,bluetooth-lowenergy,Java,Android,Bluetooth,Bluetooth Lowenergy,我有以下工作代码,可以扫描并连接到可编程设备: import android.Manifest; import android.app.AlertDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallba
import android.Manifest;
import android.app.AlertDialog;
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.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity2 extends AppCompatActivity {
private final static String TAG = MainActivity2.class.getSimpleName();
BluetoothManager btManager;
BluetoothAdapter btAdapter;
BluetoothLeScanner btScanner;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
Boolean btScanning = false;
int deviceIndex = 0;
ArrayList<BluetoothDevice> devicesDiscovered = new ArrayList<BluetoothDevice>();
BluetoothGatt bluetoothGatt;
public final static String ACTION_GATT_CONNECTED =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"com.example.bluetooth.le.EXTRA_DATA";
public Map<String, String> uuids = new HashMap<String, String>();
// Stops scanning after 5 seconds.
private Handler mHandler = new Handler();
private static final long SCAN_PERIOD = 5000;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
btScanner = btAdapter.getBluetoothLeScanner();
if (btAdapter != null && !btAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
// Make sure we have access coarse location enabled, if not, prompt the user to enable it
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
// Device scan callback.
private ScanCallback leScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
devicesDiscovered.add(result.getDevice());
deviceIndex++;
}
};
// Device connect call back
private final BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
}
@Override
public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
}
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
displayGattServices(bluetoothGatt.getServices());
}
@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// >> DUNNO WHAT TO DO HERE <<
}
};
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
System.out.println(characteristic.getUuid());
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
public void startScanning() {
System.out.println("start scanning");
btScanning = true;
deviceIndex = 0;
devicesDiscovered.clear();
AsyncTask.execute(new Runnable() {
@Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
stopScanning();
}
}, SCAN_PERIOD);
}
public void stopScanning() {
System.out.println("stopping scanning");
btScanning = false;
AsyncTask.execute(new Runnable() {
@Override
public void run() {
btScanner.stopScan(leScanCallback);
}
});
}
public void connectToDeviceSelected() {
int deviceSelected = Integer.parseInt("0" /* MY DEVICE INDEX TAKEN FROM AN EDITTEXT*/);
bluetoothGatt = devicesDiscovered.get(deviceSelected).connectGatt(this, false, btleGattCallback);
}
public void disconnectDeviceSelected() {
bluetoothGatt.disconnect();
}
private void displayGattServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics =
gattService.getCharacteristics();
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic :
gattCharacteristics) {
// SHOWS AVAILABLES
}
}
}
@Override
public void onStart() {
super.onStart();
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.example.joelwasserman.androidbleconnectexample/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
@Override
public void onStop() {
super.onStop();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.example.joelwasserman.androidbleconnectexample/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
}
导入android.Manifest;
导入android.app.AlertDialog;
导入android.bluetooth.BluetoothAdapter;
导入android.bluetooth.bluetooth设备;
导入android.bluetooth.BluetoothGatt;
导入android.bluetooth.BluetoothGattCallback;
导入android.bluetooth.BluetoothGattCharacteristic;
导入android.bluetooth.BluetoothGattService;
导入android.bluetooth.BluetoothManager;
导入android.bluetooth.le.BluetoothLeScanner;
导入android.bluetooth.le.ScanCallback;
导入android.bluetooth.le.ScanResult;
导入android.content.Context;
导入android.content.DialogInterface;
导入android.content.Intent;
导入android.content.pm.PackageManager;
导入android.net.Uri;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.os.Handler;
导入android.support.v7.app.AppActivity;
导入com.google.android.gms.appindexing.Action;
导入com.google.android.gms.AppIndex.AppIndex;
导入com.google.android.gms.common.api.GoogleAppClient;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类MainActivity2扩展了AppCompatActivity{
private final static String TAG=MainActivity2.class.getSimpleName();
蓝牙经理;
蓝牙适配器;
蓝牙扫描仪;
私有最终静态整数请求\启用\ BT=1;
私有静态最终整数权限\请求\粗略\位置=1;
布尔扫描=假;
int deviceIndex=0;
ArrayList DevicesDiscoveryd=新的ArrayList();
蓝牙关贸总协定蓝牙关贸总协定;
公共最终静态字符串动作\u GATT\u已连接=
“com.example.bluetooth.le.ACTION\u GATT\u CONNECTED”;
公共最终静态字符串操作\u GATT\u断开连接=
“com.example.bluetooth.le.ACTION\u GATT\u DISCONNECTED”;
公共最终静态字符串操作\u GATT\u服务\u发现=
“com.example.bluetooth.le.ACTION\u GATT\u SERVICES\u DISCOVERED”;
公共最终静态字符串操作\u数据\u可用=
“com.example.bluetooth.le.ACTION\u数据可用”;
公共最终静态字符串额外_数据=
“com.example.bluetooth.le.EXTRA_DATA”;
publicmap uuids=newhashmap();
//5秒后停止扫描。
私有处理程序mHandler=新处理程序();
专用静态最终长扫描周期=5000;
/**
*注意:这是自动生成的,用于实现应用程序索引API。
*看https://g.co/AppIndexing/AndroidStudio 了解更多信息。
*/
私人谷歌客户;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btManager=(BluetoothManager)getSystemService(Context.BLUETOOTH\u服务);
btAdapter=btManager.getAdapter();
btScanner=btAdapter.getBluetoothLeScanner();
if(btAdapter!=null&&!btAdapter.isEnabled()){
Intent enableentent=新意图(BluetoothAdapter.ACTION\u REQUEST\u ENABLE);
startActivityForResult(启用意图、请求和启用);
}
//确保已启用访问粗略位置,如果未启用,则提示用户启用它
if(this.checkSelfPermission(Manifest.permission.ACCESS\u\u LOCATION)!=PackageManager.permission\u已授予){
final AlertDialog.Builder=新建AlertDialog.Builder(此);
builder.setTitle(“此应用程序需要位置访问”);
setMessage(“请授予位置访问权限,以便此应用程序可以检测外围设备。”);
setPositiveButton(android.R.string.ok,null);
builder.setOnDismissListener(新的DialogInterface.OnDismissListener(){
@凌驾
公共void onDismiss(对话框接口对话框){
requestPermissions(新字符串[]{Manifest.permission.ACCESS\u rough\u LOCATION},permission\u REQUEST\u rough\u LOCATION);
}
});
builder.show();
}
client=new GoogleApiClient.Builder(this.addApi(AppIndex.API).build();
}
//设备扫描回调。
private ScanCallback leScanCallback=新建ScanCallback(){
@凌驾
公共void onScanResult(int callbackType、ScanResult){
discovered.add(result.getDevice());
deviceIndex++;
}
};
//设备连接回拨
私有最终BluetoothGattCallback btleGattCallback=新BluetoothGattCallback(){
@凌驾
特征变更后的公共无效(蓝牙gatt,最终蓝牙gatt特征特征){
}
@凌驾
连接状态更改的公共无效(最终蓝牙gatt gatt、最终int状态、最终int新闻状态){
}
@凌驾
发现服务上的公共无效(最终蓝牙gatt、最终int状态){
displayGattServices(bluetoothGatt.getServices());
}
@凌驾
//特征读取操作的结果
公共性质无效阅读(蓝牙gatt,
蓝牙特征,
int状态){
如果(状态==蓝牙GATT.GATT\U成功){
广播更新(动作数据可用,特征);
}
}
@凌驾
特征写入的公共无效(蓝牙gatt、蓝牙gatt特征特征、int状态){
//>>不知道该怎么做查看在characteristic中写入新值的示例:
public static final byte NO_ALERT = 0x00; //your byte data
public final static UUID IMMEDIATE_ALERT_UUID =
UUID.fromString("00001802-0000-1000-8000-00805f9b34fb"); //UUID of gatt service
public final static UUID IMMEDIATE_ALERT_LEVEL_UUID =
UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb"); //UUID of characteristic
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
byte[] data;
byte b = NO_ALERT;
data = new byte[]{b};
BluetoothGattService service = gatt.getService(IMMEDIATE_ALERT_UUID);
if (service != null) {
BluetoothGattCharacteristic characteristic = service.getCharacteristic(IMMEDIATE_ALERT_LEVEL_UUID);
characteristic.setValue(data);
gatt.writeCharacteristic(characteristic);
}
}