Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何与BLE沟通_Java_Android_Bluetooth_Bluetooth Lowenergy - Fatal编程技术网

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);
   }
}