Bagaimana cara mengetahui secara terprogram apakah perangkat Bluetooth terhubung?

87

Saya memahami cara mendapatkan daftar perangkat yang dipasangkan, tetapi bagaimana cara mengetahui apakah perangkat tersebut terhubung?

Itu harus mungkin karena saya melihatnya tercantum dalam daftar perangkat Bluetooth ponsel saya dan menyatakan status koneksi mereka.

dchappelle
sumber

Jawaban:

156

Tambahkan izin bluetooth ke AndroidManifest Anda,

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

Kemudian gunakan filter niat untuk mendengarkan ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTEDdan ACTION_ACL_DISCONNECTEDsiaran:

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

Beberapa catatan:

  • Tidak ada cara untuk mengambil daftar perangkat yang terhubung saat aplikasi dimulai. Bluetooth API tidak mengizinkan Anda untuk QUERY, melainkan memungkinkan Anda untuk mendengarkan PERUBAHAN.
  • Solusi hoak untuk mengatasi masalah di atas adalah mengambil daftar semua perangkat yang diketahui / dipasangkan ... kemudian mencoba menyambungkan ke masing-masing (untuk menentukan apakah Anda terhubung).
  • Atau, Anda dapat meminta layanan latar belakang untuk mengawasi Bluetooth API dan menulis status perangkat ke disk untuk digunakan aplikasi Anda di kemudian hari.
Skylar Sutton
sumber
2
Ini bagus selama aplikasi saya berjalan tetapi bagaimana saya bisa mendapatkan daftar saat ini?
dchappelle
2
Bagaimana Anda berencana menjalankan kode tanpa aplikasi Anda "berjalan"? Jika maksud Anda, Anda perlu mengakses ini dari sesuatu selain dari Aktivitas ... buka Google Layanan Android, buat salah satu layanan untuk mendengarkan siaran, dan pertahankan ke dalam daftar.
Skylar Sutton
6
Saya dapat mendengarkan maksudnya TETAPI bagaimana saya bisa mendapatkan daftar awal perangkat Bluetooth yang terhubung? Jika ada yang sudah terhubung pada saat Aktivitas atau Layanan saya dimulai, saya tidak akan tahu. Saya akan membayangkan (berharap) data ini tersedia di suatu tempat? Saya tidak ingin membuat layanan (yang berjalan terus-menerus selama ponsel dihidupkan) hanya untuk mendengarkan maksud ini.
dchappelle
11
Tidak ada cara untuk mengambil daftar perangkat yang terhubung saat memulai aplikasi. Bluetooth API hanya akan membiarkan Anda mendengarkan perubahan koneksi. Jadi ya, satu-satunya cara untuk melakukannya adalah membuat layanan yang berjalan lama dan menambah / menghapus ke daftar publik. Ini adalah keluhan besar dari banyak developer. Bergantung pada kebutuhan kinerja Anda, Anda dapat mengambil daftar perangkat yang dipasangkan dan mencoba menyambung ke masing-masing perangkat. Jika gagal, itu tidak tersedia. Kata peringatan: .connect () adalah operasi pemblokiran.
Skylar Sutton
1
@skylarsutton +1 Terima kasih banyak atas jawaban ini, membantu saya memulai bluetooth
AgentKnopf
34

Dalam kasus penggunaan saya, saya hanya ingin melihat apakah headset Bluetooth terhubung untuk aplikasi VoIP. Solusi berikut berhasil untuk saya:

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

Tentu saja Anda memerlukan izin Bluetooth:

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

jobbert
sumber
2
Ini yang saya cari. Hanya untuk memeriksa saat peluncuran bahwa Bluetooth terhubung atau tidak. Terima kasih itu berhasil!
sud007
11

Terima kasih banyak kepada Skylarsutton atas jawabannya. Saya memposting ini sebagai tanggapannya, tetapi karena saya memposting kode, saya tidak dapat membalas sebagai komentar. Saya sudah memberi suara positif pada jawabannya jadi saya tidak mencari poin apa pun. Hanya membayarnya ke depan.

Untuk beberapa alasan BluetoothAdapter.ACTION_ACL_CONNECTED tidak dapat diselesaikan oleh Android Studio. Mungkin itu sudah usang di Android 4.2.2? Berikut ini modifikasi kodenya. Kode registrasinya sama; kode penerima sedikit berbeda. Saya menggunakan ini dalam layanan yang memperbarui tanda yang terhubung dengan Bluetooth yang menjadi referensi bagian lain dari aplikasi.

    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...
    }
};
pmont
sumber
1
kode Anda benar; itu tidak digunakan lagi di 4.2.2. Kelas BluetoothAdapter tidak berisi, ACTION_ACL_CONNECTED. String itu ada di kelas BluetoothDevice.
RobLabs
Terima kasih telah menjelaskannya!
pmont
6

Ada fungsi isConnected di API sistem BluetoothDevice di https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java

Jika Anda ingin tahu apakah perangkat terikat (berpasangan) saat ini terhubung atau tidak, fungsi berikut berfungsi dengan baik untuk saya:

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);
    }
}
LW
sumber
Pernahkah Anda melihat ini memberikan hasil yang berbeda dari sekedar memeriksa apakah bluetoothManager.getConnectionState(device, BluetoothProfile.GATT) == BluetoothProfile.STATE_CONNECTED?
Gumby The Green
Dari apa yang saya tahu, mereka memberikan hasil yang sama. Perhatikan bahwa untuk pengguna Kotlin, dua baris pertama tersebut adalah adil val m: Method = device.javaClass.getMethod("isConnected")dan val connected = m.invoke(device).
Gumby The Green
Terima kasih, apa yang saya butuhkan! Ini adalah kotlin yang setara untuk metode ini: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
(Class []) null 👈 Ini keren!
linjiejun
1

Kode ini untuk profil headset, mungkin juga akan berfungsi untuk profil lain. Pertama, Anda perlu memberikan pemroses profil (kode Kotlin):

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

Kemudian saat memeriksa bluetooth:

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

Perlu sedikit waktu hingga onSeviceConnected dipanggil. Setelah itu Anda bisa mendapatkan daftar perangkat headset yang terhubung dari:

mBluetoothHeadset!!.connectedDevices
pengguna5902306
sumber
0

BluetoothAdapter.getDefaultAdapter().isEnabled -> mengembalikan nilai true saat bluetooth terbuka

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

audioManager.isBluetoothScoOn -> mengembalikan nilai true saat perangkat terhubung

ravid rinek
sumber
0

Saya benar-benar mencari cara untuk mengambil status koneksi perangkat, bukan mendengarkan peristiwa koneksi. Inilah yang berhasil untuk saya:

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
}
connorbode
sumber