1. 程式人生 > >Android之Bluetooth—藍芽操作

Android之Bluetooth—藍芽操作

2. 配置本機藍芽模組

在這裡首先要了解對藍芽操作一個核心類BluetoothAdapter

程式碼如下:
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
//直接開啟系統的藍芽設定面板
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 0x1);
//直接開啟藍芽
adapter.enable();
//關閉藍芽
adapter.disable();
//開啟本機的藍芽發現功能(預設開啟120秒,可以將時間最多延長至300秒)
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//設定持續時間(最多300秒)

3.搜尋藍芽裝置

使用BluetoothAdapter的startDiscovery()方法來搜尋藍芽裝置

startDiscovery()方法是一個非同步方法,呼叫後會立即返回。該方法會進行對其他藍芽裝置的搜尋,該過程會持續12秒。該方法呼叫後,搜尋過程實際上是在一個System Service中進行的,所以可以呼叫cancelDiscovery()方法來停止搜尋(該方法可以在未執行discovery請求時呼叫)。

請求Discovery後,系統開始搜尋藍芽裝置,在這個過程中,系統會發送以下三個廣播:

ACTION_DISCOVERY_START:開始搜尋

ACTION_DISCOVERY_FINISHED:搜尋結束

ACTION_FOUND:找到裝置,這個Intent中包含兩個extra fields:EXTRA_DEVICE和EXTRA_CLASS,分別包含BluetooDevice和BluetoothClass。

我們可以自己註冊相應的BroadcastReceiver來接收響應的廣播,以便實現某些功能

程式碼如下:
// 建立一個接收ACTION_FOUND廣播的BroadcastReceiver
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // 發現裝置
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // 從Intent中獲取裝置物件
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // 將裝置名稱和地址放入array adapter,以便在ListView中顯示
            mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
        }
    }
};
// 註冊BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // 不要忘了之後解除繫結

4. 藍芽Socket通訊

如果打算建議兩個藍芽裝置之間的連線,則必須實現伺服器端與客戶端的機制。當兩個裝置在同一個RFCOMM channel下分別擁有一個連線的BluetoothSocket,這兩個裝置才可以說是建立了連線。

伺服器裝置與客戶端裝置獲取BluetoothSocket的途徑是不同的。伺服器裝置是通過accepted一個incoming connection來獲取的,而客戶端裝置則是通過開啟一個到伺服器的RFCOMM channel來獲取的。

伺服器端的實現

通過呼叫BluetoothAdapter的listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket(UUID用於客戶端與伺服器端之間的配對)

呼叫BluetoothServerSocket的accept()方法監聽連線請求,如果收到請求,則返回一個BluetoothSocket例項(此方法為block方法,應置於新執行緒中)

如果不想在accept其他的連線,則呼叫BluetoothServerSocket的close()方法釋放資源(呼叫該方法後,之前獲得的BluetoothSocket例項並沒有close。但由於RFCOMM一個時刻只允許在一條channel中有一個連線,則一般在accept一個連線後,便close掉BluetoothServerSocket)

程式碼如下:
private class AcceptThread extends Thread {
    private final BluetoothServerSocket mmServerSocket;

    public AcceptThread() {
        // Use a temporary object that is later assigned to mmServerSocket,
        // because mmServerSocket is final
        BluetoothServerSocket tmp = null;
        try {
            // MY_UUID is the app's UUID string, also used by the client code
            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        // Keep listening until exception occurs or a socket is returned
        while (true) {
            try {
                socket = mmServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            // If a connection was accepted
            if (socket != null) {
                // Do work to manage the connection (in a separate thread)
                manageConnectedSocket(socket);
                mmServerSocket.close();
                break;
            }
        }
    }

    /** Will cancel the listening socket, and cause the thread to finish */
    public void cancel() {
        try {
            mmServerSocket.close();
        } catch (IOException e) { }
    }
}


客戶端的實現
通過搜尋得到伺服器端的BluetoothService

呼叫BluetoothService的listenUsingRfcommWithServiceRecord(String, UUID)方法獲取BluetoothSocket(該UUID應該同於伺服器端的UUID)

呼叫BluetoothSocket的connect()方法(該方法為block方法),如果UUID同伺服器端的UUID匹配,並且連線被伺服器端accept,則connect()方法返回

注意:在呼叫connect()方法之前,應當確定當前沒有搜尋裝置,否則連線會變得非常慢並且容易失敗

程式碼如下:
private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
        BluetoothSocket tmp = null;
        mmDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();

        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        // Do work to manage the connection (in a separate thread)
        manageConnectedSocket(mmSocket);
    }

    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}


連線管理(資料通訊)
分別通過BluetoothSocket的getInputStream()和getOutputStream()方法獲取InputStream和OutputStream

使用read(bytes[])和write(bytes[])方法分別進行讀寫操作

注意:read(bytes[])方法會一直block,知道從流中讀取到資訊,而write(bytes[])方法並不是經常的block(比如在另一裝置沒有及時read或者中間緩衝區已滿的情況下,write方法會block)

程式碼如下:
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;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main Activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }

    /* Call this from the main Activity to shutdown the connection */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}

  除了這個常量,有提供其它的API,支援不同任務的其他常數。它們在下面列出。

Sr.No 常數說明
1 ACTION_REQUEST_DISCOVERABLE
此常數用於開啟藍芽的發現
2 ACTION_STATE_CHANGED
此常量將通知藍芽狀態已經改變
3 ACTION_FOUND
此常數用於接收關於所發現的每個裝置的資訊

啟用了藍芽功能之後,可以通過呼叫 getBondedDevices()方法來獲取配對裝置列表。它返回一組的藍芽裝置。其語法如下:

privateSet<BluetoothDevice>pairedDevices;
pairedDevices = BA.getBondedDevices();

除了配對的裝置,還有API,讓更多藍芽控制權等方法。它們在下面列出。

Sr.No 方法及說明
1 enable()
這種方法使介面卡,如果未啟用
2 isEnabled()
如果介面卡已啟用此方法返回true
3 disable()
該方法禁用介面卡
4 getName()
此方法返回的藍芽介面卡的名稱
5 setName(String name)
此方法更改藍芽名稱
6 getState()
此方法返回藍芽介面卡的當前狀態
7 startDiscovery()
此方法開始藍芽120秒的發現過程。


相關推薦

AndroidBluetooth操作

2. 配置本機藍芽模組 在這裡首先要了解對藍芽操作一個核心類BluetoothAdapter 程式碼如下: BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); //直接開啟系統的藍芽設定面板 Intent intent = ne

Android通過Bluetooth傳送手機照片檔案到Windows PC:Java實現

Android通過Bluetooth藍芽傳送手機照片檔案到Windows PC:Java實現 本文在《Android通過藍芽傳送資料到Windows PC電腦:Java實現(連結地址:https://blog.csdn.net/zhangphil/article/details/831467

Bluetooth 操作

//佈局<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app=

Android Bluetooth 強度Rssi

轉自 https://blog.csdn.net/lhc1105/article/details/54585632 轉自 https://blog.csdn.net/jasonwang18/article/details/73131020 轉自 http://www.cnblogs.co

Android手機總結傳統

出處:Android手機藍芽總結之傳統藍芽   最近,公司有一個專案時關於手機藍芽和硬體藍芽相互通訊的需求。基於之前很久沒有學習硬體的知識,這次記錄下來,以備下次需要時使用。 首先,需要搞清楚一些基本的概要,藍芽3.0以前的是傳統藍芽,4.0以後的是低功耗藍芽,Android藍

Android開發經典2.0)開發全記錄

前言部分 最近因為需要開始藍芽相關開發,所以在網上搜索了很多內容,並且結合自己的開發過程做了一個總結,先儲備上,也許可能幫到正在做藍芽開發的同學。 藍芽很早就是android裝置上基本通訊功能了,只是以前的沒有那麼多藍芽裝置,現在藍芽裝置種類繁多,所以經常會有人遇到藍芽相關的開發

Android移動開發-BlueTooth)裝置檢測連線的實現

無論是WIFI還是4G網路,建立網路連線後都是訪問網際網路資源,並不能直接訪問區域網資源。比如兩個人在一起,A要把手機上的視訊傳給B,通常情況是開啟手機QQ,通過QQ傳送檔案給對方。不過上傳視訊很耗流量,如果現場沒有可用的WIFI,手機的資料流量又不足,那

Android開發通過耳機實現訊飛語音識別的功能

近階段在開發一款app,實現通過藍芽耳機進行訊飛語音識別,獲取識別結果之後再通過語音合成從藍芽耳機播報出識別結果。上網也查了很多資料,大多是說通過一下兩行程式碼:      mAudioManager.setBluetoothScoOn(true);           

Android開發(一)開啟和裝置搜尋

Android藍芽開發系列目錄: 一、判斷是否系統是否支援藍芽 在使用藍芽之前,我們首先要判斷手機裝置是否支援藍芽,雖然現在基本都支援藍芽了,但是為了程式碼的嚴謹性我們還是需要在程式碼中判斷: private BluetoothManager bluetoothma

Android Bluetooth 4.0 詳解

本文介紹Android ble 藍芽4.0,也就是說API level >= 18,且支援藍芽4.0的手機才可以使用,如果手機系統版本API level < 18,也是用不了藍芽4.0的哦。 一、瞭解api及概念 1.1 BluetoothGatt 繼

Android提高第十三篇探祕隱藏API

package com.testReflect; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import

Bluetooth-->開發狀態判斷

1:判斷裝置是否支援藍芽 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (null == adapter)

Android監聽耳機的按鍵事件 無法響應KeyEvent監聽不到

需求:藍芽耳機的按鍵事件,暫停/播放 音訊/視訊 ,無法響應藍芽KeyEvent的事件 此問題是由於中的藍芽KeyEvent監聽不到導致的,可以通過以下方法監聽藍芽按鍵事件    private MediaSession mSession;  &

Android中實現錄放音

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

BlueTooth 4 0技術細節

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Bluetooth---

轉載自: https://blog.csdn.net/it1039871366/article/details/46441507 Tieto公司某藍芽大牛寫得《程式設計師》投稿文章 Android 4.2藍芽介紹 藍芽一詞源於公元十世紀丹麥國王HaraldBlatand名字中的Bla

BlueTooth 4 0技術細節

  雖然藍芽(Bluetooth)3.0都還尚未完全普及,Bluetooth SIG(藍芽技術聯盟,Bluetooth Special InterestGroup,後文簡稱BluetoothSIG)卻又再次推出了藍芽4.0規範,並表示這又是藍芽發展史上一次重大的革新。值藍芽4.0推出之時,我們特地採訪了Blu

IOSBLE讀取資料與寫入資料

1.本篇文章歸納了詳細的藍芽讀取,與藍芽寫入的通訊。 2.藉助公司最近一直研發藍芽裝置專案,博主一路走過來,也遇到不少的坑,希望在此能夠給予更多看官的幫助。 藍芽的讀取 UUID的主要類檔案,歸納放置在一個檔案:Constants.h #define APP

Nordic nRF5 SDK 學習筆記九, Central 掃描函式 sd_ble_gap_scan_start() 理解

軟體: nRF SKD Ver 15.2 藍芽 Central 掃描函式 uint32_t sd_ble_gap_scan_start (ble_gap_scan_params_t const * p_scan_params,ble_data_t const * p_

BlueTooth: 歷史與發展

藍芽歷史:    藍芽(Bluetooth),或稱為藍芽,是一種無線個人區域網(Wireless PAN),最初由愛立信創制,後來由藍芽技術聯盟訂定技術標準。據說因為此技術尚在萌芽的階段,故將Bluetooth以“藍芽”的中文譯名在臺灣進行商 業的註冊,不過在2006年,該組