GATT sunucusuna bağlanma

Bir BDE cihazıyla etkileşimde bulunmanın ilk adımı bu cihaza bağlanmaktır. Daha fazla özellikle de cihazdaki GATT sunucusuna bağlanmayı gerektirir. GATT'ye bağlanmak için sunucu kullanıyorsanız connectGatt() yöntemidir. Bu yöntem üç parametre alır: Context nesnesi, autoConnect (bir boole değeri BDE cihazına otomatik olarak bağlanıp bağlanmayacağını kullanılabilir hale gelir) ve bir BluetoothGattCallback:

Kotlin

var bluetoothGatt: BluetoothGatt? = null
...

bluetoothGatt = device.connectGatt(this, false, gattCallback)

Java

bluetoothGatt = device.connectGatt(this, false, gattCallback);

Bu bağlantı, BLE cihazı tarafından barındırılan GATT sunucusuna bağlanır ve bir BluetoothGatt örneği GATT istemci işlemlerini yürütmek için kullanabilirsiniz. Arayan (Android uygulaması) GATT müşterisidir. İlgili içeriği oluşturmak için kullanılan BluetoothGattCallback, sonuçları müşteriye teslim etmek için kullanılır. Örneğin: bağlantı durumunu ve diğer GATT istemci işlemlerini görebilirsiniz.

Bağlı hizmet kurulumu

Aşağıdaki örnekte BDE uygulaması, (DeviceControlActivity) Bluetooth cihazlara bağlanmak, cihaz verilerini görüntülemek için ve cihazın desteklediği GATT hizmetlerini ve özelliklerini gösterebilirsiniz. Merkezli Bu etkinlik, kullanıcı girişinde bir kullanıcı adı ile BluetoothLeService adlı Service, BLE API aracılığıyla BDE cihazıyla etkileşime girer. İletişim, izin veren bir bağlı hizmet kullanılarak gerçekleştirilen BluetoothLeService öğesine bağlanacak etkinliği ve işlevleri ve cihazlara bağlanabiliyor. BluetoothLeService için bir Erişim sağlayan Binder uygulaması söz konusu etkinlik için bir hizmet olarak kabul edilir.

Kotlin

class BluetoothLeService : Service() {

    private val binder = LocalBinder()

    override fun onBind(intent: Intent): IBinder? {
        return binder
    }

    inner class LocalBinder : Binder() {
        fun getService() : BluetoothLeService {
            return this@BluetoothLeService
        }
    }
}

Java

class BluetoothLeService extends Service {

    private Binder binder = new LocalBinder();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    class LocalBinder extends Binder {
        public BluetoothLeService getService() {
            return BluetoothLeService.this;
        }
    }
}

Etkinlik, hizmeti şunu kullanarak başlatabilir: bindService() bir Intent bir ServiceConnection bağlantı ve bağlantı kesme etkinliklerini dinlemek için uygulama ve bir işaret tıklayın.

Kotlin

class DeviceControlActivity : AppCompatActivity() {

    private var bluetoothService : BluetoothLeService? = null

    // Code to manage Service lifecycle.
    private val serviceConnection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(
            componentName: ComponentName,
            service: IBinder
        ) {
            bluetoothService = (service as LocalBinder).getService()
            bluetoothService?.let { bluetooth ->
                // call functions on service to check connection and connect to devices
            }
        }

        override fun onServiceDisconnected(componentName: ComponentName) {
            bluetoothService = null
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.gatt_services_characteristics)

        val gattServiceIntent = Intent(this, BluetoothLeService::class.java)
        bindService(gattServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
    }
}

Java

class DeviceControlActivity extends AppCompatActivity {

    private BluetoothLeService bluetoothService;

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            bluetoothService = ((LocalBinder) service).getService();
            if (bluetoothService != null) {
                // call functions on service to check connection and connect to devices
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bluetoothService = null;
        }
    };

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

        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }
}

BluetoothAdapter'ı kur

Hizmet bağlandıktan sonra BluetoothAdapter. Uygulama adaptörün cihazda bulunduğundan emin olun. Kurulum Bluetooth BluetoothAdapter. Aşağıdaki örnekte, bu kurulum kodu Başarılı olduğunu gösteren Boolean değeri döndüren initialize() işlevi.

Kotlin

private const val TAG = "BluetoothLeService"

class BluetoothLeService : Service() {

    private var bluetoothAdapter: BluetoothAdapter? = null

    fun initialize(): Boolean {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        if (bluetoothAdapter == null) {
            Log.e(TAG, "Unable to obtain a BluetoothAdapter.")
            return false
        }
        return true
    }

    ...
}

Java

class BluetoothLeService extends Service {

    public static final String TAG = "BluetoothLeService";

    private BluetoothAdapter bluetoothAdapter;

    public boolean initialize() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
            return false;
        }
        return true;
    }

    ...
}

Etkinlik, ServiceConnection uygulamasında bu işlevi çağırır. initialize() işlevinden yanlış döndürülen bir değerin nasıl işleneceği bir uygulamadır. Kullanıcıya geçerli cihaz Bluetooth işlemini desteklemiyor veya herhangi bir özelliği devre dışı bırakmıyor Bluetooth'un çalışmasını gerektiren cihazlar. Aşağıdaki örnekte, Etkinlikte finish() çağrıldı seçeneğini tıklayın.

Kotlin

class DeviceControlActivity : AppCompatActivity() {

    // Code to manage Service lifecycle.
    private val serviceConnection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(
            componentName: ComponentName,
            service: IBinder
        ) {
            bluetoothService = (service as LocalBinder).getService()
            bluetoothService?.let { bluetooth ->
                if (!bluetooth.initialize()) {
                    Log.e(TAG, "Unable to initialize Bluetooth")
                    finish()
                }
                // perform device connection
            }
        }

        override fun onServiceDisconnected(componentName: ComponentName) {
            bluetoothService = null
        }
    }

    ...
}

Java

class DeviceControlsActivity extends AppCompatActivity {

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            bluetoothService = ((LocalBinder) service).getService();
            if (bluetoothService != null) {
                if (!bluetoothService.initialize()) {
                    Log.e(TAG, "Unable to initialize Bluetooth");
                    finish();
                }
                // perform device connection
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bluetoothService = null;
        }
    };

    ...
}

Bir cihaza bağlan

BluetoothLeService örneği başlatıldıktan sonra BDE'ye bağlanabilir olanak tanır. Etkinliğin yapılabilmesi için cihaz adresini hizmete göndermesi gerekir bağlantıyı başlatın. Hizmet ilk olarak getRemoteDevice() BluetoothAdapter adresinde (cihaza erişmek için) tıklayın. Adaptör, getRemoteDevice(), bu adrese sahip bir cihaza IllegalArgumentException

Kotlin

fun connect(address: String): Boolean {
    bluetoothAdapter?.let { adapter ->
        try {
            val device = adapter.getRemoteDevice(address)
        } catch (exception: IllegalArgumentException) {
            Log.w(TAG, "Device not found with provided address.")
            return false
        }
    // connect to the GATT server on the device
    } ?: run {
        Log.w(TAG, "BluetoothAdapter not initialized")
        return false
    }
}

Java

public boolean connect(final String address) {
    if (bluetoothAdapter == null || address == null) {
        Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }

    try {
        final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
    } catch (IllegalArgumentException exception) {
        Log.w(TAG, "Device not found with provided address.");
        return false;
    }
    // connect to the GATT server on the device
}

Hizmet şu koşulları karşıladığında DeviceControlActivity, bu connect() işlevini çağırır: başlatıldı. Etkinliğin, BDE cihazının adresini iletmesi gerekir. İçinde Aşağıdaki örnekte, cihaz adresi etkinliğe intent olarak aktarılır ekstra

Kotlin

// Code to manage Service lifecycle.
private val serviceConnection: ServiceConnection = object : ServiceConnection {
    override fun onServiceConnected(
    componentName: ComponentName,
    service: IBinder
    ) {
        bluetoothService = (service as LocalBinder).getService()
        bluetoothService?.let { bluetooth ->
            if (!bluetooth.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth")
                finish()
            }
            // perform device connection
            bluetooth.connect(deviceAddress)
        }
    }

    override fun onServiceDisconnected(componentName: ComponentName) {
        bluetoothService = null
    }
}

Java

private ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        bluetoothService = ((LocalBinder) service).getService();
        if (bluetoothService != null) {
            if (!bluetoothService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            // perform device connection
            bluetoothService.connect(deviceAddress);
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        bluetoothService = null;
    }
};

GATT geri çağırmasını bildir

Etkinlik, hizmete hangi cihaza bağlanacağını ve hizmeti bildirdiğinde bağlantısı kurulduğunda, hizmetin BDE cihazı. Bu bağlantıyı almak için bir BluetoothGattCallback gerekir bağlantı durumu, hizmet keşfi, özellikleri hakkında bildirimler okumalar ve karakteristik bildirimler içerir.

Bu konu, bağlantı durumu bildirimlerine odaklanmaktadır. Aktarım BDE'sini inceleyin verileri görebilirsiniz. hizmet keşfi, özellik okumaları ve istek özellikleri bildirimleri etkinleştirebilirsiniz.

İlgili içeriği oluşturmak için kullanılan onConnectionStateChange() işlevi, cihazın GATT sunucusuyla olan bağlantı değiştiğinde tetiklenir. Aşağıdaki örnekte, geri çağırma Service sınıfında tanımlanmıştır. Dolayısıyla şununla birlikte kullanılabilir: Bir kez BluetoothDevice ona bağlandığından emin olur.

Kotlin

private val bluetoothGattCallback = object : BluetoothGattCallback() {
    override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            // successfully connected to the GATT Server
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            // disconnected from the GATT Server
        }
    }
}

Java

private final BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            // successfully connected to the GATT Server
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            // disconnected from the GATT Server
        }
    }
};

GATT hizmetine bağlan

BluetoothGattCallback bildirildikten sonra hizmet, GATT'ye bağlanmak için connect() işlevinden BluetoothDevice nesnesi ekleyebilirsiniz.

İlgili içeriği oluşturmak için kullanılan connectGatt() işlevini kullanın. Bu işlem için Context nesnesi, autoConnect boole değeri gerekir işareti ve BluetoothGattCallback. Bu örnekte, uygulama doğrudan BDE cihazına bağlanılıyor. Bu nedenle autoConnect için false iletildi.

BluetoothGatt özelliği de eklenir. Bu, hizmetin bağlantı kurulduğunda, gerek yoktur.

Kotlin

class BluetoothLeService : Service() {

...

    private var bluetoothGatt: BluetoothGatt? = null

    ...

    fun connect(address: String): Boolean {
        bluetoothAdapter?.let { adapter ->
            try {
                val device = adapter.getRemoteDevice(address)
                // connect to the GATT server on the device
                bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback)
                return true
            } catch (exception: IllegalArgumentException) {
                Log.w(TAG, "Device not found with provided address.  Unable to connect.")
                return false
            }
        } ?: run {
            Log.w(TAG, "BluetoothAdapter not initialized")
            return false
        }
    }
}

Java

class BluetoothLeService extends Service {

...

    private BluetoothGatt bluetoothGatt;

    ...

    public boolean connect(final String address) {
        if (bluetoothAdapter == null || address == null) {
            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }
        try {
            final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
            // connect to the GATT server on the device
            bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback);
            return true;
        } catch (IllegalArgumentException exception) {
            Log.w(TAG, "Device not found with provided address.  Unable to connect.");
            return false;
        }
    }
}

Yayın güncellemeleri

Sunucu GATT sunucusuna bağlandığında veya bağlantısı kesildiğinde, sunucu tarafından yeni durumun etkinliği. Bunu yapmanın birkaç yolu vardır. İlgili içeriği oluşturmak için kullanılan aşağıdaki örnekte bir yayın bilgi sağlar.

Hizmet, yeni durumu yayınlamak için bir işlev bildirir. Bu işlev, yayınlanmadan önce Intent nesnesine iletilen bir işlem dizesinde geri dönüyor.

Kotlin

private fun broadcastUpdate(action: String) {
    val intent = Intent(action)
    sendBroadcast(intent)
}

Java

private void broadcastUpdate(final String action) {
    final Intent intent = new Intent(action);
    sendBroadcast(intent);
}

Yayın işlevi oluşturulduktan sonra BluetoothGattCallback ile bağlantı durumu hakkında bilgi GATT sunucusu. Sabitler ve hizmetin mevcut bağlantı durumu bildirilir Intent işlemlerini temsil eden hizmette.

Kotlin

class BluetoothLeService : Service() {

    private var connectionState = STATE_DISCONNECTED

    private val bluetoothGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
        override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                // successfully connected to the GATT Server
                connectionState = STATE_CONNECTED
                broadcastUpdate(ACTION_GATT_CONNECTED)
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                // disconnected from the GATT Server
                connectionState = STATE_DISCONNECTED
                broadcastUpdate(ACTION_GATT_DISCONNECTED)
            }
        }
    }

    ...

    companion object {
        const val ACTION_GATT_CONNECTED =
            "com.example.bluetooth.le.ACTION_GATT_CONNECTED"
        const val ACTION_GATT_DISCONNECTED =
            "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"

        private const val STATE_DISCONNECTED = 0
        private const val STATE_CONNECTED = 2

    }
}

Java

class BluetoothLeService extends Service {

    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";

    private static final int STATE_DISCONNECTED = 0;
    private static final int STATE_CONNECTED = 2;

    private int connectionState;
    ...

    private final BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                // successfully connected to the GATT Server
                connectionState = STATE_CONNECTED;
                broadcastUpdate(ACTION_GATT_CONNECTED);
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                // disconnected from the GATT Server
                connectionState = STATE_DISCONNECTED;
                broadcastUpdate(ACTION_GATT_DISCONNECTED);
            }
        }
    };

    …
}

Etkinlikteki güncellemeleri dinle

Hizmet bağlantı güncellemelerini yayınladığında etkinliğin BroadcastReceiver uygulayabilirsiniz. Etkinliği oluştururken bu alıcının kaydını yapın ve ekrandan ayrılıyor. Hizmetten etkinlikleri dinleyerek kullanıcı arayüzünün güncel özelliklerine bağlı olarak BDE cihazıyla bağlantı durumu.

Kotlin

class DeviceControlActivity : AppCompatActivity() {

...

    private val gattUpdateReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothLeService.ACTION_GATT_CONNECTED -> {
                    connected = true
                    updateConnectionState(R.string.connected)
                }
                BluetoothLeService.ACTION_GATT_DISCONNECTED -> {
                    connected = false
                    updateConnectionState(R.string.disconnected)
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        registerReceiver(gattUpdateReceiver, makeGattUpdateIntentFilter())
        if (bluetoothService != null) {
            val result = bluetoothService!!.connect(deviceAddress)
            Log.d(DeviceControlsActivity.TAG, "Connect request result=$result")
        }
    }

    override fun onPause() {
        super.onPause()
        unregisterReceiver(gattUpdateReceiver)
    }

    private fun makeGattUpdateIntentFilter(): IntentFilter? {
        return IntentFilter().apply {
            addAction(BluetoothLeService.ACTION_GATT_CONNECTED)
            addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED)
        }
    }
}

Java

class DeviceControlsActivity extends AppCompatActivity {

...

    private final BroadcastReceiver gattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                connected = true;
                updateConnectionState(R.string.connected);
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                connected = false;
                updateConnectionState(R.string.disconnected);
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();

        registerReceiver(gattUpdateReceiver, makeGattUpdateIntentFilter());
        if (bluetoothService != null) {
            final boolean result = bluetoothService.connect(deviceAddress);
            Log.d(TAG, "Connect request result=" + result);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(gattUpdateReceiver);
    }

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        return intentFilter;
    }
}

BDE verilerini aktar bölümünde, BroadcastReceiver ayrıca hizmet keşfini cihazın tipik verileri.

GATT bağlantısını kapat

Bluetooth bağlantılarıyla çalışırken önemli bir adım bağlantısını kurun. Bunu yapmak için close() numarasını arayın işlevini BluetoothGatt nesnesine aktarmalısınız. Aşağıdaki örnekte hizmet, BluetoothGatt referansını barındırır. Etkinlik hizmetinde, cihazın pilinin boşalmasını önlemek için bağlantı kapatılır.

Kotlin

class BluetoothLeService : Service() {

...

    override fun onUnbind(intent: Intent?): Boolean {
        close()
        return super.onUnbind(intent)
    }

    private fun close() {
        bluetoothGatt?.let { gatt ->
            gatt.close()
            bluetoothGatt = null
        }
    }
}

Java

class BluetoothLeService extends Service {

...

      @Override
      public boolean onUnbind(Intent intent) {
          close();
          return super.onUnbind(intent);
      }

      private void close() {
          if (bluetoothGatt == null) {
              Return;
          }
          bluetoothGatt.close();
          bluetoothGatt = null;
      }
}