18 กุมภาพันธ์ 2555

[Android Code] การเรียกใช้ Bluetooth


        บทความนี้เลิกใช้งานแล้วเพราะว่าเจ้าของบล็อกได้เขียนใหม่เป็นไลบรารีที่สามารถใช้งานได้ง่ายและสะดวกกว่า โดยสามารถอ่านได้ที่ [Android Code] การเชื่อมต่ออุปกรณ์ผ่านบลูทูธแบบง่ายๆโดยใช้ BluetoothSPP

********************************************************

        บทความแรกของเจ้าของบล็อกเลยนะเนี่ย ที่มีเนื้อหาเกี่ยวกับการเขียนโปรแกรม Android เป็นบทความแรกทั้งทีแต่เป็นเรื่อง Bluetooth ซะงั้น เพราะเจ้าของบล็อกคิดว่าพวกพื้นฐานในการเขียน มันก็มีให้หาอ่านกันทั่วไปอยู่แล้ว เลยไม่จำเป็นต้องเขียน โดยเจ้าของบล็อกจะตั้งใจไว้ว่าจะเขียนเนื้อหา จำพวกการใช้งานต่างๆที่ไม่มีเนื้อหาภาษาไทย เพราะว่ามีผู้ที่สนใจอยู่ แต่มีปัญหาเรื่องกำแพงภาษา

        ในบทความนี้จะเป็นพื้นฐานในการเขียนโปรแกรมสำหรับเชื่อมต่อ Android เข้ากับ Bluetooth ซึ่งไม่ได้ครอบคลุมทั้งหมด โดยจะเป็นการใช้งานแบบ Serial Port Profile [SPP] ซึ่งเป็นการส่งข้อมูลแบบอนุกรมเหมือนกับ RS232 แต่ก็ครอบคลุมไปถึงการเชื่อมต่อ Bluetooth ด้วยเช่นกัน จึงสามารถนำเนื้อหาบางส่วนนี้ไปประยุกต์ใช้งานได้ โดยเนื้อหาหลักจะนำมาจาก Bluetooth [Android Developer]

        สำหรับการเชื่อมต่อ Bluetooth บน Android นั้น เจ้าของบล็อกจะเรียงเป็นลำดับขั้นตอนดังนี้

        1. ก่อนอื่นผู้อ่านจะต้องแจ้ง Permission ของ Bluetooth อันนี้สำคัญมาก ถ้าโปรแกรมของเราไม่มีการแจ้ง จะใช้ Bluetooth ไม่ได้ ให้ใส่คำสั่งใน AndroidManifest.xml ดังนี้
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" />



        หรือจะกำหนดผ่านหน้าต่าง Permission เลยก็ได้ ดังรูป



        2. ต่อมาก็ให้กำหนด Bluetooth ในโปรแกรมให้สร้าง Object ที่ชื่อว่า BluetoothAdapter ขึ้นมา ซึ่งเป็น Object หลัก สำหรับควบคุม Bluetooth โดยกำหนดค่าให้เป็น getDefaultAdapter() จะเป็นการกำหนด Bluetooth ให้เป็นค่าเริ่มต้น
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        กรณีที่ต้องการตรวจสอบว่าเครื่องรองรับ Bluetooth หรือไม่ ถ้าไม่รองรับก็จะแจ้งผ่าน Toast แล้วปิดแอปพลิเคชัน ใช้คำสั่ง
if (mBluetoothAdapter == null) { Toast.makeText(getApplicationContext() , "Bluetooth is not available" , Toast.LENGTH_SHORT).show(); finish(); return; }

        ในเงื่อนไขนี้เจ้าของบล็อกก็จะให้แสดง Toast ขึ้นมาเพื่อแจ้งว่าอุปกรณ์ไม่รองรับ Bluetooth แล้วปิดโปรแกรมทันที

        3. เริ่มเปิดใช้งาน Bluetooth ด้วยคำสั่ง
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

        แต่ในการทำงานจริงๆ ควรจะต้องมีการตรวจสอบก่อนว่า Bluetooth นั้นเปิดอยู่หรือไม่ด้วยคำสั่ง .isEnabled() ถ้า Bluetooth ยังไม่ได้เปิดก็จึงจะใช้คำสั่งเปิด Bluetooth แต่ถ้าเปิดไว้อยู่แล้วก็ให้ข้ามคำสั่งไปเลย คำสั่งก็จะได้ดังนี้
if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }


เวลาโปรแกรมทำงานก็จะขึ้น Dialog แบบนี้

        Bluetooth บน Android จะมีการกำหนดให้เครื่องอื่นมองเห็นได้หรือไม่ ซึ่งเจ้าของบล็อกขอเรียกว่า Discoverable ละกัน จะได้เข้าใจง่าย



        กรณีที่เปิด Bluetooth แล้ว แต่ว่ายังไม่ได้เปิด Discoverable เครื่องจะยังค้นหา Bluetooth ของเครื่องอื่นและเชื่อมต่อได้ แต่อุปกรณ์อื่นจะมองไม่เห็น Bluetooth จากเครื่องของเรา ต้อง Discoverable ก่อน เครื่องอื่นๆถึงจะค้นหาเครื่องเจอ ซึ่งสั่งให้เปิด Discoverable จากโปรแกรมได้เช่นกัน โดยใช้คำสั่ง
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra (BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent);

        จากคำสั่งจะเป็นการเปิด Bluetooth และให้ Discoverable นาน 300 วินาที



        4. พอถึงขั้นตอนนี้แล้ว ก็จะเป็นการแสดงรายชื่ออุปกรณ์ Bluetooth ถือว่าเป็นส่วนสำคัญส่วนหนึ่ง เพราะจะให้แสดงรายชื่ออุปกรณ์ที่เคยเชื่อมต่อมาแล้วอย่างน้อยหนึ่งครั้ง ทำให้ไม่ต้องค้นหาอีกครั้ง สามารถกดเชื่อมต่อจากรายชื่อที่มีอยู่ได้ทันที โดยไม่ต้องค้นหา โดยการรับค่ารายชื่อสามารถรับได้จากคำสั่ง .getBondedDevice แล้วเก็บไว้ใน ArrayAdapter แบบ String โดยจะได้คำสั่งดังนี้
private ArrayAdapter<String> mPairedDevicesArrayAdapter; Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } }

        โดยที่ mArrayAdapter ผู้อ่านสามารถนำไปใช้กับ ListView ได้เลย โปรแกรมก็จะแสดงรายชื่ออุปกรณ์ที่เคยเชื่อมต่อ บน ListView
        ในกรณีนี้จะต้องทำการค้นหาอุปกรณ์อื่นๆก่อน [Discovering] ด้วยคำสั่ง startDiscovery() เมื่อมีการค้นพบอุปกรณ์อื่น จากนั้นคำสั่งใน BroadcastReceiver จะถูกเรียกใช้ทันที ใช้สำหรับกำหนดว่าเมื่อค้นหาอุปกรณ์เจอแล้วจะทำอะไรต่อ ดังนั้นผู้อ่านก็จะต้องเขียนคำสั่งให้กับ BroadcastReceiver ด้วย ก่อนอื่นจะต้องมีการเรียก Register ให้กับ BroadcastReceiver ก่อน ซึ่งควรจะประกาศไว้ใน onCreate() เลย โดยมีคำสั่งดังนี้
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter);

        และเมื่อปิดโปรแกรมลงหรือเข้าสู่ onDestroy() ก็ควรจะยกเลิก Register ด้วย เพื่อป้องกันการเรียกใช้งานค้างไว้ แล้วโปรแกรมตัวอื่นมีการเรียกใช้ซ้ำ ซึ่งจะทำให้โปรแกรมอื่นๆผิดพลาดได้ เพราะ Bluetooth ถูกเปิดทิ้งไว้อยู่
this.registerReceiver(mReceiver, filter);

        เมื่อกำหนดการเรียก Register เสร็จแล้ว ก็เข้าสู่คำสั่งสำหรับ BroadcastReceiver จะมีฟังก์ชัน onReceive ซึ่งจะทำงานเมื่อค้นหาเจออุปกรณ์ที่เปิด Bluetooth อยู่ เจ้าของบล็อกจะให้เก็บรายชื่ออุปกรณ์และ Address โดยเก็บไว้ใน mArrayAdapter เหมือนเดิม ซึ่งมีคำสั่งดังนี้
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra( BluetoothDevice.EXTRA_DEVICE); mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } };

        สำหรับคำสั่ง startDiscovery() สามารถเรียกใช้หลังจากเปิด Bluetooth ได้ทันทีหรือจะสร้าง Button ขึ้นมาสำหรับกดเพื่อค้นหาอุปกรณ์อื่นๆก็ได้ แล้วแต่ผู้อ่าน


        5. ต่อมาก็จะเป็นการเริ่มทำการเชื่อมต่อ Bluetooth กันแล้ว การเชื่อมต่อ Bluetooth จะเป็นการสร้าง Class ที่เป็น Thread แยกมาตัวนึง สำหรับควบคุมการทำการเชื่อมต่อกับอุปกรณ์อื่น อาจจะดูยุ่งยากไปหน่อย เจ้าของบล็อกไม่ขออธิบายละกัน เพราะเชื่อว่าเจ้าของบล็อกอธิบายไม่รู้เรื่อง
private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device) { BluetoothSocket tmp = null; mmDevice = device; try { tmp = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { } mmSocket = tmp; } public void run() { mBluetoothAdapter.cancelDiscovery(); try { mmSocket.connect(); } catch (IOException connectException) { try { mmSocket.close(); } catch (IOException closeException) { } return; } manageConnectedSocket(mmSocket); } public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } }

        6. การจัดการการเชื่อมต่อ Bluetooth กับอุปกรณ์อื่นๆ หลังจากที่เชื่อมต่อแล้ว ก็จะต้องมีคำสั่งสำหรับการรับส่งข้อมูล โดยจะต้องสร้าง Class ที่เป็น Thread ขึ้นมาทำหน้าที่นี้โดยเฉพาะ
private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { byte[] buffer = new byte[1024]; int bytes; while (true) { try { bytes = mmInStream.read(buffer); mHandler.obtainMessage(MESSAGE_READ, bytes , -1, buffer) .sendToTarget(); } catch (IOException e) { break; } } } public void write(byte[] bytes) { try { mmOutStream.write(bytes); } catch (IOException e) { } } public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } }

        เสร็จแล้วกับขั้นตอนของโปรแกรมสำหรับการเชื่อมต่อผ่าน Bluetooth ในขั้นตอนหลังๆ เจ้าของบล็อกไม่รู้จะอธิบายออกมายังไงให้เข้าใจง่ายๆ

        สำหรับทั้งหมดนี้ เป็นเพียงแค่คำสั่งพื้นฐานของโปรแกรมเท่านั้น ไม่ได้กล่าวถึงการเรียกใช้งานคำสั่งอื่นๆสำหรับโปรแกรมทั้งหมด และเจ้าของบล็อกมีตัวอย่างโปรแกรมที่ใช้ Bluetooth อยู่ ซึ่งนำโค๊ดตัวอย่างจากทางเว็ป Android Developer มาทำ สามารถนำไปใช้งานได้ทันที และศึกษาการทำงานของคำสั่งได้ Bluetooth Chat [Google Drive] หรือ Android-BluetoothChat [GitHub]



        ซึ่งตัวอย่างนี้จะมีชื่อว่า Bluetooth Chat ใช้สำหรับรับส่งข้อมูล String แบบ SPP ใช้อุปกรณ์ Android สองเครื่องต่อเข้าด้วยกัน หรือจะต่อ Bluetooth เข้ากับคอมพิวเตอร์ก็ได้ แล้วใช้โปรแกรม Hyper Terminal หรือ Tera Term สำหรับรับ-ส่งข้อมูลกับอุปกรณ์ Android แทนก็ได้

        สงสัยอะไรก็ถามเพิ่มเติมในบทความนี้ได้เลย เพราะเจ้าของบล็อกรู้ตัวว่าอธิบายไม่กระจ่าง




เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium