Bluetooth cihazları bulma

BluetoothAdapter simgesini kullanarak uzak Bluetooth cihazlarını cihaz keşfi aracılığıyla veya eşlenen cihazların listesini sorgula yoluyla bulabilirsiniz.

Bluetooth cihazları bulmaya çalışmadan önce gerekli Bluetooth izinlerine sahip olduğunuzdan ve uygulamanızı Bluetooth için ayarladığınızdan emin olun.

Cihaz bulma, yerel alanda Bluetooth özellikli cihazlar arayan ve her biri hakkında bazı bilgiler isteyen bir tarama işlemidir. Bu işlem bazen keşfetme, sorgu veya tarama olarak da adlandırılır. Yakındaki bir Bluetooth cihazı, yalnızca şu anda bilgi isteklerini kabul ediyorsa ve bulunabilir durumdaysa keşif isteğine yanıt verir. Bir cihaz bulunabilir durumdaysa cihazın adı, sınıfı ve benzersiz MAC adresi gibi bazı bilgileri paylaşarak keşif isteğine yanıt verir. Keşif işlemini gerçekleştiren cihaz, bu bilgileri kullanarak keşfedilen cihazla bağlantı başlatmayı seçebilir.

Bulanık cihazlar kullanıcının konumuyla ilgili bilgileri gösterebileceğinden cihaz bulma işlemi için konum erişimi gerekir. Uygulamanız Android 8.0 (API seviyesi 26) veya sonraki bir sürümü çalıştıran bir cihazda kullanılıyorsa bunun yerine Companion Device Manager API'yi kullanabilirsiniz. Bu API, uygulamanız adına cihaz keşfi gerçekleştirir. Bu nedenle, uygulamanızın konum izinleri istemesi gerekmez.

Uzaktan bir cihazla ilk kez bağlantı kurulduktan sonra kullanıcıya otomatik olarak bir eşleme isteği sunulur. Bir cihaz eşlendiğinde, cihazla ilgili temel bilgiler (ör. cihazın adı, sınıfı ve MAC adresi) kaydedilir ve Bluetooth API'leri kullanılarak okunabilir. Uzaktan cihazın bilinen MAC adresi kullanılarak, cihazın kapsama alanında olduğu varsayılarak keşif işlemi gerçekleştirmeden dilediğiniz zaman cihazla bağlantı kurulabilir.

Eşleme ile bağlantı kurma arasında bir fark olduğunu unutmayın:

  • Eşleştirme, iki cihazın birbirinin varlığından haberdar olduğu, kimlik doğrulama için kullanılabilecek paylaşılan bir bağlantı anahtarına sahip olduğu ve birbirleriyle şifrelenmiş bağlantı kurabileceği anlamına gelir.
  • Bağlı olmak, cihazların şu anda bir RFCOMM kanalı paylaştığını ve birbirleriyle veri aktarabildiğini gösterir. Mevcut Bluetooth API'leri, RFCOMM bağlantısı kurulmadan önce cihazların eşlenmesini gerektirir. Bluetooth API'leriyle şifrelenmiş bir bağlantı başlattığınızda eşleme otomatik olarak gerçekleştirilir.

Aşağıdaki bölümlerde, eşlenen cihazların nasıl bulunacağı ve cihaz keşfini kullanarak yeni cihazların nasıl bulunacağı açıklanmaktadır.

Eşlenen cihazları sorgulayın

Cihaz keşfi gerçekleştirmeden önce, istenen cihazın zaten bilinip bilinmediğini görmek için eşlenen cihaz grubunu sorgulamanız önerilir. Bunun için getBondedDevices() numaralı telefonu arayın. Bu işlev, eşlenen cihazları temsil eden bir dizi BluetoothDevice nesnesi döndürür. Örneğin, aşağıdaki kod snippet'inde gösterildiği gibi tüm eşlenen cihazları sorgulayabilir ve her cihazın adını ve MAC adresini alabilirsiniz:

Kotlin

val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter?.bondedDevices
pairedDevices?.forEach { device ->
   val deviceName = device.name
   val deviceHardwareAddress = device.address // MAC address
}

Java

Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();

if (pairedDevices.size() > 0) {
   // There are paired devices. Get the name and address of each paired device.
   for (BluetoothDevice device : pairedDevices) {
       String deviceName = device.getName();
       String deviceHardwareAddress = device.getAddress(); // MAC address
   }
}

Bluetooth cihazıyla bağlantı başlatmak için ilişkili BluetoothDevice nesnesinden gereken tek şey MAC adresidir. Bu adresi getAddress() çağırarak alabilirsiniz. Bluetooth cihazları bağlama başlıklı makalede bağlantı oluşturma hakkında daha fazla bilgi edinebilirsiniz.

Cihazları keşfetme

Cihazları keşfetmeye başlamak için startDiscovery() numaralı telefonu arayın. Süreç asenkrondur ve keşfin başarıyla başlatılıp başlatılmadığını belirten bir boole değeri döndürür. Keşif işlemi genellikle yaklaşık 12 saniyelik bir sorgu taraması ve ardından bulunan her cihazın Bluetooth adını almak için sayfa taraması içerir.

Uygulamanızın, keşfedilen her cihazla ilgili bilgi alabilmesi için ACTION_FOUND intent'i için bir BroadcastReceiver kaydettirmesi gerekir. Sistem bu intent'i her cihaz için yayınlar. Intent, EXTRA_DEVICE ve EXTRA_CLASS ek alanlarını içerir. Bu alanlar sırasıyla bir BluetoothDevice ve BluetoothClass içerir. Aşağıdaki kod snippet'inde, cihazlar bulunduğunda yayını işlemek için nasıl kaydolabileceğiniz gösterilmektedir:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
   ...

   // Register for broadcasts when a device is discovered.
   val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
   registerReceiver(receiver, filter)
}

// Create a BroadcastReceiver for ACTION_FOUND.
private val receiver = object : BroadcastReceiver() {

   override fun onReceive(context: Context, intent: Intent) {
       val action: String = intent.action
       when(action) {
           BluetoothDevice.ACTION_FOUND -> {
               // Discovery has found a device. Get the BluetoothDevice
               // object and its info from the Intent.
               val device: BluetoothDevice =
                       intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
               val deviceName = device.name
               val deviceHardwareAddress = device.address // MAC address
           }
       }
   }
}

override fun onDestroy() {
   super.onDestroy()
   ...

   // Don't forget to unregister the ACTION_FOUND receiver.
   unregisterReceiver(receiver)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
   ...

   // Register for broadcasts when a device is discovered.
   IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
   registerReceiver(receiver, filter);
}

// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
   public void onReceive(Context context, Intent intent) {
       String action = intent.getAction();
       if (BluetoothDevice.ACTION_FOUND.equals(action)) {
           // Discovery has found a device. Get the BluetoothDevice
           // object and its info from the Intent.
           BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
           String deviceName = device.getName();
           String deviceHardwareAddress = device.getAddress(); // MAC address
       }
   }
};

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

   // Don't forget to unregister the ACTION_FOUND receiver.
   unregisterReceiver(receiver);
}

Bluetooth cihazla bağlantı başlatmak için ilişkili MAC adresini almak üzere BluetoothDevice üzerinde getAddress() işlevini çağırırsınız.

Bulunabilirliği etkinleştirme

Yerel cihazı diğer cihazlar tarafından bulunabilir hâle getirmek için ACTION_REQUEST_DISCOVERABLE intent'iyle startActivityForResult(Intent, int) işlevini çağırın. Bu işlem, Ayarlar uygulamasına gitmek zorunda kalmadan sistemin keşfedilebilir modunu etkinleştirme isteği gönderir. Bu işlem, kendi uygulamanızı durdurur. Cihaz varsayılan olarak iki dakika boyunca keşfedilebilir hale gelir. EXTRA_DISCOVERABLE_DURATION simgesini ekleyerek beş dakikaya kadar farklı bir süre tanımlayabilirsiniz.

Aşağıdaki kod snippet'i, cihazı beş dakika boyunca bulunabilir olarak ayarlar:

Kotlin

val requestCode = 1;
val discoverableIntent: Intent = Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE).apply {
   putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300)
}
startActivityForResult(discoverableIntent, requestCode)

Java

int requestCode = 1;
Intent discoverableIntent =
       new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivityForResult(discoverableIntent, requestCode);


Şekil 2: Keşfedilebilirliği etkinleştirme iletişim kutusu.

Şekil 2'de gösterildiği gibi, cihazı bulunabilir hale getirmek için kullanıcıdan izin isteyen bir iletişim kutusu gösterilir. Kullanıcı "İzin ver" yanıtını verirse cihaz, belirtilen süre boyunca bulunabilir hale gelir. Ardından etkinliğiniz, onActivityResult() geri çağırma işlevine bir çağrı alır. Bu çağrıda, cihazın bulunabilir olduğu süreye eşit bir sonuç kodu bulunur. Kullanıcı "Reddet" yanıtını verdiyse veya bir hata oluştuysa sonuç kodu RESULT_CANCELED olur.

Cihaz, ayrılan süre boyunca sessiz bir şekilde bulunabilir modda kalır. Bulanık mod değiştiğinde bildirim almak için ACTION_SCAN_MODE_CHANGED intent'i için bir BroadcastReceiver kaydedin. Bu intent, sırasıyla yeni ve eski tarama modunu sağlayan EXTRA_SCAN_MODE ve EXTRA_PREVIOUS_SCAN_MODE ek alanlarını içerir. Her ek için olası değerler şunlardır:

SCAN_MODE_CONNECTABLE_DISCOVERABLE
Cihaz, bulunabilir modda olmalıdır.
SCAN_MODE_CONNECTABLE
Cihaz, bulunabilir modda değil ancak yine de bağlantı alabilir.
SCAN_MODE_NONE
Cihaz, bulunabilir modda değil ve bağlantı alamıyor.

Uzaktan bir cihaza bağlantı başlatıyorsanız cihazın bulunabilirliğini etkinleştirmeniz gerekmez. Bulanıklığı etkinleştirmek yalnızca uygulamanızın gelen bağlantıları kabul eden bir sunucu soketi barındırmasını istediğinizde gereklidir. Çünkü uzak cihazlar, diğer cihazlarla bağlantı başlatmadan önce diğer cihazları keşfedebilmelidir.