onServicesDiscovered问题?

时间:2016-03-25 17:42:27

标签: android bluetooth connection gatt

我有一个基本的Android应用程序。这几乎与我已编写和测试的内容重复。

servicesDiscovered未触发,并且在我手动搜索时找不到任何服务。

我无法弄清楚出了什么问题,请注意它不是BLE设备本身,因为使用预制的BLE应用程序(用于调试它显示所有特征,服务等)

有人可以帮忙吗?我认为这很简单,但我似乎无法找到它!

package airconditioner.com.airconditioncontrol;

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.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


public class MainActivity extends Activity {
    /**************CUSTOM CLASS TO HANDLE DEVICE LIST*******************/
    private class LeDeviceListAdapter{
        private ArrayList<BluetoothDevice> mLeDevices;
        private ArrayList<String> adapter;
        private Context context;

        public LeDeviceListAdapter(){
            mLeDevices = new ArrayList<BluetoothDevice>();
            adapter = new ArrayList<String>();
        }
    public void addDevice(BluetoothDevice device){  //add device name and address
        if(!mLeDevices.contains(device)){
            mLeDevices.add(device);

            String name;
            if(device.getName() != null)
                name = device.getName();
            else
                name = "unknown - null";

            String address;
            if(device.getAddress() != null)
                address = device.getAddress();
            else
                address = "unknown - null";

            adapter.add(name + "\n" + address); //push BLE info to list of strings
        }
    }

    public void clear(){mLeDevices.clear();}
    public BluetoothDevice getDevice(int i){return mLeDevices.get(i);}

    public void update(){
        handle.post(new Runnable() {
            @Override
            public void run() {
                ListView list = (ListView)findViewById(R.id.ble_list);
                list.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.textlayout, adapter));
            }
        });
    }
}

/*************DECLARE GLOBAL VARIABLES FOR BLE****************/
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothScan;
private BluetoothGatt gatt;

private LeDeviceListAdapter mLeDeviceListAdapter;  //implemented in code - custom

private boolean mScanning;

private UUID AIR_SETTING_SERVICE = UUID.fromString("762fd44e-1610-4730-a364-c9af0c07628c");
private UUID AIR_SETTING_ATTRIBUTE = UUID.fromString("e5eb1257-1892-4353-89d6-eba2f89562bd");

private final Handler handle = new Handler(Looper.getMainLooper());

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Get List View and create method for OnClick
    ListView ble_list = (ListView)findViewById(R.id.ble_list);
    ble_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
            if (device != null){
                if(mScanning){
                    scanForDevice(false);
                    connectTo(device);
                }else{
                    Toast toast = Toast.makeText(getApplicationContext(), "Error: onItemClick()", Toast.LENGTH_LONG);
                    toast.show();
                }
            }
        }
    });

    //START BLUETOOTH
    final BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    mBluetoothScan = mBluetoothAdapter.getBluetoothLeScanner();

    if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()){
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, 1); //Usually 1 is a global variable
    }

    //Initialize list view adapter
    mLeDeviceListAdapter = new LeDeviceListAdapter();

    //start scan
    scanForDevice(true);
}

@Override
protected void onDestroy(){
    if(gatt != null)
        gatt.close();
    gatt = null;        //FIX THIS IMPLEMENTATION
    super.onDestroy();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/*************HANDLE START OF SCANNING FOR DEVICES**************/
private void scanForDevice(final boolean enable){
    if(enable){
        ListView list = (ListView)findViewById(R.id.ble_list);
        list.setAdapter(null);

        mScanning = true;
        mBluetoothScan.startScan(mLeScanCallback);
        Log.d("SCAN", "SCAN START");
    }else{
        mScanning = false;
        mBluetoothScan.stopScan(mLeScanCallback);
        Log.d("SCAN", "SCAN STOP");
    }
}

//Callback for received BLE Devices
private ScanCallback mLeScanCallback =
    new ScanCallback(){
        @Override
        public void onScanResult(int CallBackType, final ScanResult result){
                runOnUiThread(new Runnable(){
                    @Override
                    public void run(){
                        Log.d("BLE DEVICE:", result.getDevice().getAddress().toString());     //Log Address
                        mLeDeviceListAdapter.addDevice(result.getDevice());        //Add info to custom class
                        mLeDeviceListAdapter.update();             //Update UI
                   }
                });
            }
        };

//Connect to a passed device
private void connectTo(BluetoothDevice device){
    if(gatt == null){
        gatt = device.connectGatt(getApplicationContext(), false, gattCallBack);
    }else{
        Log.d("ERROR", "gatt != null");
        Toast t = Toast.makeText(getApplicationContext(), "ERROR: gatt != null", Toast.LENGTH_LONG);
    }
}

//Gatt callback for connection changes
private final BluetoothGattCallback gattCallBack = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {     //handle connecting BLE
        Log.d("CONNECTION STATUS", "Status: " + status + " newState: " + newState);
        switch(newState){
            case BluetoothProfile.STATE_CONNECTED:

                Log.d("STATE", "CONNECTED");
                handle.post(new Runnable(){
                    @Override
                    public void run(){
                        TextView text = (TextView)findViewById(R.id.connection_status);
                        text.setText("Status: Connected");
                        text.setTextColor(Color.BLUE);
                    }
                });
                break;

            case BluetoothProfile.STATE_DISCONNECTED:

                Log.d("STATE", "CONNECTED");
                handle.post(new Runnable(){
                    @Override
                    public void run(){
                        TextView text = (TextView)findViewById(R.id.connection_status);
                        text.setText("Status: Disconnected");
                        text.setTextColor(Color.BLACK);
                    }
                });
                break;
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status){

        //Log services
        List<BluetoothGattService> services = gatt.getServices();
        for(BluetoothGattService a : services)
            Log.d("SERVICES", a.getUuid().toString());

        //get service
        BluetoothGattService service = gatt.getService(AIR_SETTING_SERVICE);

        if(service != null){
            BluetoothGattCharacteristic characteristic = service.getCharacteristic(AIR_SETTING_ATTRIBUTE);

            //Log characteristics in service
            List<BluetoothGattCharacteristic> charac = service.getCharacteristics();
            for(BluetoothGattCharacteristic c : charac)
                Log.d("CHARACTERISTIC", c.getUuid().toString());

            if(characteristic !=null){
                gatt.readCharacteristic(characteristic);    //go to callback for reading
                Log.d("CHARACTERISTIC", "WORKING");
            }else{
                Log.d("ERROR", "CHARACTERISTIC NULL");
            }
        }else{
            Log.d("ERROR", "SERVICE NULL");
        }
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt g, BluetoothGattCharacteristic c, int status){  //handle characteristic write
        if(status != 0){
            Log.d("ERROR", "WRITE FAILED: " + status);
        }else{
            Log.d("GATT", "WRITTEN");   //Check status codes
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt g, BluetoothGattCharacteristic c, int status){
        if(status != 0){
            Log.d("ERROR", "READ FAIL: " + status);
        }else{
            //Handle getting storing current value read
            Log.d("GATT", "READ");
            //Don't need to store value locally - c.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8,0);
        }
    }
};

/***********HANDLE BUTTON PRESSES******************/
public void sendStatus(View view){
    EditText textBox = (EditText)findViewById(R.id.edit_message);
    int status = -1;

    try{
        status = Integer.parseInt(textBox.getText().toString());
    }catch(Exception e){
        Log.d("EXCEPTION", "Parsing String -> Int");
        Toast.makeText(getApplicationContext(), "Please enter a valid number", Toast.LENGTH_LONG).show();
        return;
    }

    if(gatt != null){
        List<BluetoothGattService> services = gatt.getServices();
        for(BluetoothGattService a : services)
            Log.d("SERVICES", a.getUuid().toString());
        BluetoothGattService service = gatt.getService(AIR_SETTING_SERVICE);
        BluetoothGattCharacteristic characteristic;
        if(service != null)
            characteristic = service.getCharacteristic(AIR_SETTING_ATTRIBUTE);
        else
            Log.d("ERROR", "SERVICE NULL");

        /*
        if(service == null || characteristic == null){          //catch errors
            Log.d("ERROR", "SERVICE OR CHARACTERISTIC NULL");
            Toast.makeText(getApplicationContext(), "Service or characteristic is null!", Toast.LENGTH_LONG).show();
        }else{
            characteristic.setValue(status, BluetoothGattCharacteristic.FORMAT_UINT8, 0);       //change local characteristic
            gatt.writeCharacteristic(characteristic);           //write characteristic

            //Update UI
            TextView text = (TextView)findViewById(R.id.fan_status);
            switch(status){
                case 0:
                    text.setText("Status: OFF");
                    break;
                case 1:
                    text.setText("Status: LOW");
                    break;
                case 2:
                    text.setText("Status: MED");
                    break;
                case 3:
                    text.setText("Status: HIGH");
                    break;
                default:
                    Log.d("ERROR", "Status: " + status);
            }
        }
    }else{
        Toast.makeText(getApplicationContext(), "You need to connect to a device first", Toast.LENGTH_SHORT).show();*/
    }
}

public void disconnectBLE(View view){
    Toast.makeText(getApplicationContext(), "Disconnecting Bluetooth...", Toast.LENGTH_SHORT).show();

    //close BLE
    if(gatt != null)
        gatt.close();
    gatt = null;

    //reset and restart scan
    scanForDevice(true);
}

}

1 个答案:

答案 0 :(得分:0)

注意:

如果您忘记了discoverService(),它就不会发现,发现服务!