Bir Bluetooth cihazının bağlı olup olmadığını programlı olarak nasıl anlarım?


87

Eşleştirilmiş cihazların bir listesini nasıl alacağımı anlıyorum, ancak bağlı olup olmadıklarını nasıl anlayabilirim?

Telefonumun Bluetooth cihaz listesinde listelendiğini gördüğüm ve bağlantı durumlarını belirttiği için mümkün olmalı.

Yanıtlar:


156

AndroidManifest'inize bluetooth izni ekleyin,

<uses-permission android:name="android.permission.BLUETOOTH" />

Sonra dinlemek için niyet filtreleri kullanın ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTEDve ACTION_ACL_DISCONNECTEDyayınları:

public void onCreate() {
    ...
    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    this.registerReceiver(mReceiver, filter);
}

//The BroadcastReceiver that listens for bluetooth broadcasts
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
           ... //Device found
        }
        else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
           ... //Device is now connected
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
           ... //Done searching
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
           ... //Device is about to disconnect
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
           ... //Device has disconnected
        }           
    }
};

Birkaç not:

  • Uygulama başlangıcında bağlı cihazların bir listesini almanın bir yolu yoktur. Bluetooth API, QUERY yapmanıza izin vermez, bunun yerine CHANGES dinlemenize izin verir.
  • Yukarıdaki soruna geçici bir çözüm, bilinen / eşleştirilmiş tüm cihazların listesini almaktır ... sonra her birine bağlanmaya çalışmak (bağlı olup olmadığınızı belirlemek için).
  • Alternatif olarak, Bluetooth API'sini izleyen bir arka plan hizmetine sahip olabilir ve uygulamanızın daha sonraki bir tarihte kullanması için cihaz durumlarını diske yazabilirsiniz.

2
Uygulamam çalıştığı sürece bu iyidir, ancak güncel bir listeyi nasıl edinebilirim?
dchappelle

2
Uygulamanız "çalışmadan" kodu nasıl yürütmeyi planlıyorsunuz? Buna Etkinlik dışında bir şeyden erişmeniz gerektiğini kastediyorsanız ... google Android Hizmetleri'ne gidin, yayınları dinlemek için bunlardan birini oluşturun ve bir listede saklayın.
Skylar Sutton 1811

6
Amaçları dinleyebilirim ANCAK bağlı Bluetooth cihazlarının ilk listesini nasıl alabilirim? Aktivitem veya Hizmetim başladığında zaten bağlıysa, bilmeyeceğim. Bu verilerin bir yerlerde mevcut olduğunu hayal ediyorum (umuyorum)? Sadece bu amaçları dinlemek için (telefon açık olduğu sürece sürekli çalışan) bir hizmet oluşturmak zorunda kalmak istemem.
dchappelle

11
Uygulama başlangıcında bağlı cihazların listesini almanın bir yolu yoktur. Bluetooth API yalnızca bağlantı değişikliklerini dinlemenize izin verir. Yani evet, bunu yapmanın tek yolu uzun süre çalışan bir hizmet oluşturmak ve genel bir listeye eklemek / çıkarmaktır. Pek çok geliştiriciden büyük bir şikayet. Performans ihtiyaçlarınıza bağlı olarak, eşleştirilmiş cihazların listesini alabilir ve her birine bağlanmayı deneyebilirsiniz. Başarısız olursa, mevcut değildir. Yine de uyarı kelimesi: .connect () engelleyen bir işlemdir.
Skylar Sutton

1
@skylarsutton +1 Bu cevap için çok teşekkürler, bluetooth kullanmaya başlamama yardımcı oldu
AgentKnopf

34

Kullanım durumumda, yalnızca bir VoIP uygulaması için bir Bluetooth kulaklığın bağlı olup olmadığını görmek istedim. Aşağıdaki çözüm benim için çalıştı:

public static boolean isBluetoothHeadsetConnected() {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()
            && mBluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothHeadset.STATE_CONNECTED;
} 

Elbette Bluetooth iznine ihtiyacınız olacak:

<uses-permission android:name="android.permission.BLUETOOTH" />


2
Bu benim aradığım şey. Sadece başlatıldığında Bluetooth'un bağlı olup olmadığını kontrol etmek için. Teşekkürler işe yaradı!
sud007

11

Cevabı için Skylarsutton'a çok teşekkürler. Bunu kendisine yanıt olarak gönderiyorum, ancak kod gönderiyorum çünkü yorum olarak yanıtlayamıyorum. Cevabını çoktan artırdım, bu yüzden herhangi bir puan aramıyorum. Sadece ileri ödüyorum.

Bazı nedenlerden dolayı BluetoothAdapter.ACTION_ACL_CONNECTED, Android Studio tarafından çözülemedi. Belki de Android 4.2.2'de kullanımdan kaldırıldı? İşte kodunun bir değişikliği. Kayıt kodu aynıdır; alıcı kodu biraz farklıdır. Bunu, uygulamanın diğer bölümlerinin referans aldığı Bluetooth bağlantılı bir bayrağı güncelleyen bir hizmette kullanıyorum.

    public void onCreate() {
        //...
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        this.registerReceiver(BTReceiver, filter);
    }

    //The BroadcastReceiver that listens for bluetooth broadcasts
    private final BroadcastReceiver BTReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
            //Do something if connected
            Toast.makeText(getApplicationContext(), "BT Connected", Toast.LENGTH_SHORT).show();
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            //Do something if disconnected
            Toast.makeText(getApplicationContext(), "BT Disconnected", Toast.LENGTH_SHORT).show();
        }
        //else if...
    }
};

1
kodunuz doğru; 4.2.2'de kullanımdan kaldırılmadı. BluetoothAdapter sınıfı, ACTION_ACL_CONNECTED içermiyor. Bu dize, BluetoothDevice sınıfındadır.
RobLabs

Bunu açıkladığınız için teşekkürler!
pmont

6

BluetoothDevice sistem API'sinde https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java'da bir isConnected işlevi vardır.

Sınırlı (eşleştirilmiş) bir cihazın şu anda bağlı olup olmadığını bilmek istiyorsanız, aşağıdaki işlev benim için iyi çalışıyor:

public static boolean isConnected(BluetoothDevice device) {
    try {
        Method m = device.getClass().getMethod("isConnected", (Class[]) null);
        boolean connected = (boolean) m.invoke(device, (Object[]) null);
        return connected;
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
}

Bunun, sadece kontrol etmekten farklı bir sonuç verdiğini gördünüz mü bluetoothManager.getConnectionState(device, BluetoothProfile.GATT) == BluetoothProfile.STATE_CONNECTED?
Gumby The Green

Anladığım kadarıyla aynı sonucu veriyorlar. Kotlin kullanıcıları için bu ilk iki satırın sadece val m: Method = device.javaClass.getMethod("isConnected")ve olduğunu unutmayın val connected = m.invoke(device).
Gumby The Green

Teşekkür ederim, tam olarak ihtiyacım olan şey! Bu, bu yöntem için KOTLIN eşdeğerdir:fun isConnected(device: BluetoothDevice): Boolean { return try { val m: Method = device.javaClass.getMethod( "isConnected" ) m.invoke(device) as Boolean } catch (e: Exception) { throw IllegalStateException(e) } }
Takeya

(Sınıf []) null 👈 Bu harika!
linjiejun

1

Bu kod kulaklık profilleri içindir, muhtemelen diğer profiller için de çalışacaktır. Öncelikle profil dinleyici sağlamanız gerekir (Kotlin kodu):

private val mProfileListener = object : BluetoothProfile.ServiceListener {
    override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
        if (profile == BluetoothProfile.HEADSET) 
            mBluetoothHeadset = proxy as BluetoothHeadset            
    }

    override fun onServiceDisconnected(profile: Int) {
        if (profile == BluetoothProfile.HEADSET) {
            mBluetoothHeadset = null
        }
    }
}

Ardından bluetooth'u kontrol ederken:

mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET)
if (!mBluetoothAdapter.isEnabled) {
    return Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
}

OnSeviceConnected'ın çağrılması biraz zaman alır. Bundan sonra bağlı kulaklık cihazlarının listesini şuradan alabilirsiniz:

mBluetoothHeadset!!.connectedDevices

0

BluetoothAdapter.getDefaultAdapter().isEnabled -> bluetooth açıkken true döndürür

val audioManager = this.getSystemService(Context.AUDIO_SERVICE) as AudioManager

audioManager.isBluetoothScoOn -> cihaz bağlandığında doğru döndürür


0

Bağlantı olaylarını dinlemek değil, bir aygıtın bağlantı durumunu almanın bir yolunu gerçekten arıyordum. İşte benim için çalıştı:

BluetoothManager bm = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
List<BluetoothDevice> devices = bm.getConnectedDevices(BluetoothGatt.GATT);
int status = -1;

for (BluetoothDevice device : devices) {
  status = bm.getConnectionState(device, BLuetoothGatt.GATT);
  // compare status to:
  //   BluetoothProfile.STATE_CONNECTED
  //   BluetoothProfile.STATE_CONNECTING
  //   BluetoothProfile.STATE_DISCONNECTED
  //   BluetoothProfile.STATE_DISCONNECTING
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.