จะบอกทางโปรแกรมได้อย่างไรว่าอุปกรณ์ Bluetooth เชื่อมต่ออยู่หรือไม่?


87

ฉันเข้าใจวิธีรับรายการอุปกรณ์ที่จับคู่ แต่จะทราบได้อย่างไรว่าเชื่อมต่ออยู่

จะต้องเป็นไปได้เนื่องจากฉันเห็นรายการเหล่านี้อยู่ในรายการอุปกรณ์บลูทู ธ ในโทรศัพท์ของฉันและระบุสถานะการเชื่อมต่อ

คำตอบ:


156

เพิ่มสิทธิ์บลูทู ธ ใน AndroidManifest ของคุณ

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

จากนั้นใช้ฟิลเตอร์เจตนาที่จะฟังACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTEDและACTION_ACL_DISCONNECTEDออกอากาศ:

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

หมายเหตุ:

  • ไม่มีวิธีการเรียกดูรายการอุปกรณ์ที่เชื่อมต่อเมื่อเริ่มต้นแอปพลิเคชัน Bluetooth API ไม่อนุญาตให้คุณ QUERY แต่ให้คุณฟัง CHANGES
  • วิธีแก้ไขปัญหาข้างต้นที่น่าเบื่อคือการดึงรายการอุปกรณ์ที่รู้จัก / จับคู่ทั้งหมด ... จากนั้นพยายามเชื่อมต่อกับอุปกรณ์แต่ละเครื่อง (เพื่อตรวจสอบว่าคุณเชื่อมต่ออยู่หรือไม่)
  • หรือคุณสามารถใช้บริการพื้นหลังเพื่อดู Bluetooth API และเขียนสถานะของอุปกรณ์ลงในดิสก์เพื่อให้แอปพลิเคชันของคุณใช้ในภายหลัง

2
นี่เป็นสิ่งที่ดีตราบเท่าที่แอปพลิเคชันของฉันทำงาน แต่ฉันจะรับรายการปัจจุบันได้อย่างไร
dchappelle

2
คุณวางแผนที่จะรันโค้ดโดยที่แอปพลิเคชันของคุณไม่ "ทำงาน" ได้อย่างไร? หากคุณหมายความว่าคุณต้องการเข้าถึงสิ่งนี้จากสิ่งอื่นที่ไม่ใช่กิจกรรม ... ไปที่ Google บริการ Android สร้างหนึ่งในบริการเหล่านั้นเพื่อฟังการออกอากาศและคงอยู่ในรายการ
Skylar Sutton

6
ฉันสามารถฟังความตั้งใจ แต่ฉันจะรับรายการเริ่มต้นของอุปกรณ์บลูทู ธ ที่เชื่อมต่อได้อย่างไร หากมีการเชื่อมต่ออยู่แล้วในเวลาที่เริ่มกิจกรรมหรือบริการของฉันฉันจะไม่รู้ ฉันคิดว่า (หวังว่า) ข้อมูลนี้จะมีอยู่ที่ไหนสักแห่ง? ฉันไม่ต้องการที่จะสร้างบริการ (ที่ทำงานตลอดเวลาตราบเท่าที่โทรศัพท์เปิดอยู่) เพียงเพื่อฟังเจตนาเหล่านี้
dchappelle

11
ไม่มีวิธีการดึงรายการอุปกรณ์ที่เชื่อมต่อเมื่อเริ่มต้นแอปพลิเคชัน Bluetooth API จะให้คุณรับฟังการเปลี่ยนแปลงการเชื่อมต่อเท่านั้น ใช่วิธีเดียวที่จะทำได้คือสร้างบริการที่ใช้งานได้ยาวนานและเพิ่ม / ลบลงในรายการสาธารณะ เป็นเรื่องใหญ่ที่นักพัฒนาหลายคนร้องเรียน ขึ้นอยู่กับความต้องการด้านประสิทธิภาพของคุณคุณสามารถเรียกดูรายการอุปกรณ์ที่จับคู่และลองเชื่อมต่อกับอุปกรณ์แต่ละเครื่อง หากล้มเหลวจะไม่สามารถใช้งานได้ คำเตือนแม้ว่า: .connect () เป็นการดำเนินการปิดกั้น
Skylar Sutton

1
@skylarsutton +1 ขอบคุณมากสำหรับคำตอบนี้ช่วยฉันเริ่มต้นใช้งานบลูทู ธ
AgentKnopf

34

ในกรณีการใช้งานของฉันฉันต้องการดูว่าเชื่อมต่อชุดหูฟังบลูทู ธ สำหรับแอป VoIP หรือไม่ วิธีแก้ปัญหาต่อไปนี้ใช้ได้ผลสำหรับฉัน:

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

แน่นอนคุณจะต้องได้รับอนุญาตจากบลูทู ธ :

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


2
นี่คือสิ่งที่ฉันกำลังมองหา เพียงเพื่อตรวจสอบเมื่อเปิดตัวว่าเชื่อมต่อบลูทู ธ หรือไม่ ขอบคุณมาก!
sud007

11

ขอบคุณมากสำหรับ Skylarsutton สำหรับคำตอบของเขา ฉันโพสต์ข้อความนี้เพื่อตอบกลับเขา แต่เนื่องจากฉันกำลังโพสต์รหัสฉันจึงไม่สามารถตอบกลับเป็นความคิดเห็นได้ ฉันโหวตคำตอบของเขาแล้วดังนั้นฉันจึงไม่ได้มองหาคะแนนใด ๆ เพียงแค่จ่ายเงินไปข้างหน้า

ด้วยเหตุผลบางประการ BluetoothAdapter.ACTION_ACL_CONNECTED ไม่สามารถแก้ไขได้โดย Android Studio บางทีอาจจะเลิกใช้งานใน Android 4.2.2? นี่คือการปรับเปลี่ยนรหัสของเขา รหัสการลงทะเบียนเหมือนกัน รหัสผู้รับแตกต่างกันเล็กน้อย ฉันใช้สิ่งนี้ในบริการที่อัปเดตแฟล็กที่เชื่อมต่อกับบลูทู ธ ที่ส่วนอื่น ๆ ของแอปอ้างอิง

    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
รหัสของคุณถูกต้อง ไม่ได้เลิกใช้งานใน 4.2.2 คลาส BluetoothAdapter ไม่มี ACTION_ACL_CONNECTED สตริงนั้นอยู่ในคลาส BluetoothDevice
RobLabs

ขอบคุณที่ชี้แจง!
pmont

6

มีฟังก์ชันisConnectedใน API ของระบบ BluetoothDevice ใน https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java

หากคุณต้องการทราบว่าอุปกรณ์ที่มีขอบเขต (จับคู่) เชื่อมต่ออยู่หรือไม่ฟังก์ชันต่อไปนี้ใช้ได้ดีสำหรับฉัน:

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

คุณเห็นสิ่งนี้ให้ผลลัพธ์ที่แตกต่างจากการตรวจสอบbluetoothManager.getConnectionState(device, BluetoothProfile.GATT) == BluetoothProfile.STATE_CONNECTEDหรือไม่?
Gumby The Green

จากสิ่งที่ฉันสามารถบอกได้พวกเขาให้ผลลัพธ์เดียวกัน โปรดทราบว่าสำหรับผู้ใช้ Kotlin ทั้งสองบรรทัดแรกเป็นเพียงและval m: Method = device.javaClass.getMethod("isConnected") val connected = m.invoke(device)
Gumby The Green

ขอบคุณสิ่งที่ฉันต้องการ! นี่คือค่าที่เทียบเท่ากับ kotlin สำหรับวิธีนี้: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 👈เจ๋งมาก!
linjiejun

1

รหัสนี้ใช้สำหรับโปรไฟล์ชุดหูฟังซึ่งอาจใช้ได้กับโปรไฟล์อื่น ๆ ด้วย ก่อนอื่นคุณต้องระบุผู้ฟังโปรไฟล์ (รหัส 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
        }
    }
}

จากนั้นขณะตรวจสอบบลูทู ธ :

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

ใช้เวลาสักครู่จนกว่าจะเรียก onSeviceConnected หลังจากนั้นคุณจะได้รับรายชื่ออุปกรณ์ชุดหูฟังที่เชื่อมต่อจาก:

mBluetoothHeadset!!.connectedDevices

0

BluetoothAdapter.getDefaultAdapter().isEnabled -> คืนค่าจริงเมื่อบลูทู ธ เปิดอยู่

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

audioManager.isBluetoothScoOn -> คืนค่าจริงเมื่อเชื่อมต่ออุปกรณ์


0

ฉันกำลังมองหาวิธีดึงข้อมูลสถานะการเชื่อมต่อของอุปกรณ์ไม่ใช่ฟังเหตุการณ์การเชื่อมต่อ นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน:

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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.