Làm cách nào để lập trình cho biết thiết bị Bluetooth đã được kết nối hay chưa?


86

Tôi hiểu cách lấy danh sách các thiết bị được ghép nối nhưng làm cách nào để biết chúng đã được kết nối hay chưa?

Điều đó phải có thể xảy ra vì tôi thấy chúng được liệt kê trong danh sách thiết bị Bluetooth của điện thoại và nó cho biết trạng thái kết nối của chúng.

Câu trả lời:


155

Thêm quyền bluetooth vào AndroidManifest của bạn,

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

Sau đó, sử dụng bộ lọc ý định lắng nghe ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTEDACTION_ACL_DISCONNECTEDchương trình phát sóng:

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

Một số lưu ý:

  • Không có cách nào để truy xuất danh sách các thiết bị được kết nối khi khởi động ứng dụng. API Bluetooth không cho phép bạn TRẢ LỜI, thay vào đó nó cho phép bạn nghe các THAY ĐỔI.
  • Một công việc khó giải quyết đối với vấn đề trên sẽ là truy xuất danh sách tất cả các thiết bị đã biết / được ghép nối ... sau đó cố gắng kết nối với từng thiết bị (để xác định xem bạn đã kết nối chưa).
  • Ngoài ra, bạn có thể yêu cầu một dịch vụ nền xem API Bluetooth và ghi trạng thái thiết bị vào đĩa để ứng dụng của bạn sử dụng sau này.

2
Điều này tốt miễn là ứng dụng của tôi đang chạy nhưng làm cách nào để tôi có được danh sách hiện tại?
dchappelle

2
Làm thế nào để bạn có kế hoạch thực thi mã mà ứng dụng của bạn không "chạy"? Nếu bạn có nghĩa là bạn cần truy cập nó từ thứ gì đó khác với Activity ... hãy truy cập Google Android Services, tạo một trong những dịch vụ đó để nghe các chương trình phát sóng và lưu nó vào danh sách.
Skylar Sutton

6
Tôi có thể lắng nghe ý định NHƯNG làm cách nào để có được danh sách ban đầu các thiết bị Bluetooth được kết nối? Nếu bất kỳ cái nào đã được kết nối vào thời điểm Hoạt động hoặc Dịch vụ của tôi bắt đầu, tôi sẽ không biết. Tôi sẽ tưởng tượng (hy vọng) dữ liệu này có sẵn ở đâu đó? Tôi sẽ không muốn phải tạo một dịch vụ (chạy liên tục miễn là điện thoại được bật) chỉ để lắng nghe những ý định này.
dchappelle

11
Không có cách nào để truy xuất danh sách các thiết bị được kết nối khi khởi động ứng dụng. API Bluetooth sẽ chỉ cho phép bạn lắng nghe các thay đổi kết nối. Vì vậy, có, cách duy nhất để làm điều đó là tạo một dịch vụ hoạt động lâu dài và thêm / xóa vào danh sách công khai. Đó là một phàn nàn lớn của rất nhiều nhà phát triển. Tùy thuộc vào nhu cầu hiệu suất của bạn, bạn có thể truy xuất danh sách các thiết bị được ghép nối và cố gắng kết nối với từng thiết bị. Nếu nó không thành công, nó không có sẵn. Lời cảnh báo mặc dù: .connect () là một hoạt động chặn.
Skylar Sutton

1
@skylarsutton +1 Cảm ơn rất nhiều vì câu trả lời này, đã giúp tôi bắt đầu với bluetooth
AgentKnopf 14/02/12

33

Trong trường hợp sử dụng của mình, tôi chỉ muốn xem liệu tai nghe Bluetooth có được kết nối cho ứng dụng VoIP hay không. Giải pháp sau đây phù hợp với tôi:

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

Tất nhiên, bạn sẽ cần quyền Bluetooth:

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


2
Đây là một trong những tôi đang tìm kiếm. Chỉ cần kiểm tra khi khởi chạy xem Bluetooth đã được kết nối hay chưa. Cảm ơn nó đã hoạt động!
sud007

11

Cảm ơn Skylarsutton vì câu trả lời của anh ấy. Tôi đăng bài này như một phản hồi cho anh ấy, nhưng vì tôi đang đăng mã nên tôi không thể trả lời dưới dạng nhận xét. Tôi đã ủng hộ câu trả lời của anh ấy vì vậy tôi không tìm kiếm bất kỳ điểm nào. Chỉ cần trả nó về phía trước.

Vì lý do nào đó, Android Studio không thể giải quyết được BluetoothAdapter.ACTION_ACL_CONNECTED. Có lẽ nó đã không được chấp nhận trong Android 4.2.2? Đây là một sửa đổi mã của anh ấy. Mã đăng ký giống nhau; mã người nhận hơi khác một chút. Tôi sử dụng điều này trong một dịch vụ cập nhật cờ kết nối Bluetooth mà các phần khác của ứng dụng tham chiếu.

    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
mã của bạn là đúng; nó không bị phản đối trong 4.2.2. Lớp BluetoothAdapter không chứa ACTION_ACL_CONNECTED. Chuỗi đó nằm trong lớp BluetoothDevice.
RobLabs

Cảm ơn vì đã làm rõ điều đó!
pmont

4

Có một chức năng isConnected trong API hệ thống BluetoothDevice trong https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bl Bluetooth/BluetoothDevice.java

Nếu bạn muốn biết liệu thiết bị được kết nối (ghép nối) hiện có được kết nối hay không, chức năng sau hoạt động tốt đối với tôi:

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

Bạn đã thấy điều này cho một kết quả khác với việc chỉ kiểm tra xem bluetoothManager.getConnectionState(device, BluetoothProfile.GATT) == BluetoothProfile.STATE_CONNECTEDchưa?
Gumby The Green

Từ những gì tôi có thể nói, họ cho kết quả tương tự. Lưu ý rằng đối với người dùng Kotlin, hai dòng đầu tiên chỉ là val m: Method = device.javaClass.getMethod("isConnected")val connected = m.invoke(device).
Gumby The Green

Cảm ơn bạn, chính xác những gì tôi cần! Đây là tương đương kotlin cho phương pháp này: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

1

Mã này dành cho các cấu hình tai nghe, có lẽ nó cũng sẽ hoạt động cho các cấu hình khác. Trước tiên, bạn cần cung cấp trình xử lý hồ sơ (mã 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
        }
    }
}

Sau đó, trong khi kiểm tra bluetooth:

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

Phải mất một chút thời gian cho đến khi onSeviceConnected được gọi. Sau đó, bạn có thể nhận được danh sách các thiết bị tai nghe được kết nối từ:

mBluetoothHeadset!!.connectedDevices

0

BluetoothAdapter.getDefaultAdapter().isEnabled -> trả về true khi bluetooth được mở

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

audioManager.isBluetoothScoOn -> trả về true khi thiết bị được kết nối


0

Tôi thực sự đang tìm cách để tìm nạp trạng thái kết nối của thiết bị chứ không phải lắng nghe các sự kiện kết nối. Đây là những gì đã làm việc cho tôi:

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.