2012年1月27日 星期五

Android Bluetooth 應用之 HelloBTUart(RS-232)

在NDK這篇HelloUart中,有人詢問到開發平台轉移至智慧型手機上應該如何實現呢??
另一個答案就是藍牙(Bluetooth)

因此,今天的主題就是在Android手機上實現藍牙規範中的 Serial Port Profile(SPP)作為RS-232的通訊。



本文是使用 "藍牙GPS" 作為範例,如果要實作在電路的話,網路上可以搜尋" 藍牙模組 "可以找到類似下圖的產品,售價大概在NT$300-1900,差別在於藍芽版本及傳輸距離(Class)。
另外通常這類模組只吃TTL信號,因此如果是RS-232信號的話別忘了還要用MAX232轉,這部分可以查 MAX232 datasheet很容易找到相關電路。


Android從2.0版本開始就已經支援藍牙,相關程式撰寫可參考android.bluetooth這個package:
http://developer.android.com/reference/android/bluetooth/package-summary.html

一般來說,藍芽裝置通訊步驟如下:
1.設定藍芽
2.搜尋已配對的或接收範圍內的裝置
3.連接裝置
4.傳輸資料
因此,經常會用的類包括:
BluetoothAdapter : 藍牙裝置選擇,主要用來管理藍牙的基本服務,包括初始化藍牙、藍牙的配對、資料傳輸的管理。
BluetoothDevice : 描述藍牙裝置。
BluetoothSocket : 藍牙Socket;這有點類似TCP/IP的Socket是用在藍牙間的通訊。
BluetoothServerSocket : 藍牙Server Socket;類似TCP/IP的Server Socket。與上述不同處在於一個是連接時通訊使用;而這個類比較像是監聽的功能。

程式說明:
1. main.xml 部分沿用HelloUart;使用 RelativeLayout (相對佈局)方式,用到有:
ScrollView : @+id/uart_scrollview
TextView : @+id/uart_view
EditText : @+id/uart_edit
Spinner : @+id/uart_select
Button : @+id/uart_button0 (CONNECT) 、 @+id/uart_button1 (DISCOVER) 、 @+id/uart_button2 (BT_SWITCH) 、 @+id/uart_button3 (DISCOVERABLE) 、 @+id/uart_button4 (SEND)、 @+id/uart_button5 (CLEAR)、 @+id/uart_button6 (EXIT)
這部份算基本功礙於篇幅這部分就忽略說明,我所建立的執行畫面如下:


2. MainActivity.java
程式中第34行有一個UUID的部分,由於Android系統目前只支援 RFCOMM 連線方式,所以需要用SPP來與對方裝置溝通連線Profile,如果藍牙使用的是其他功能例如傳檔案、聽音樂、...等功能大多是決定在這個UUID的部分,也就是前面所說BluetoothDevice,詳細請參照下面網址說明:
http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
http://kunyichen.wordpress.com/2007/06/08/bluetooth-service-uuid-list/
由上述網站得知欲使用藍牙Serial Port Profile (SPP)其UUID = 00001101-0000-1000-8000-00805F9B34FB
其餘說明都在程式中,完整程式內容如下:













最後別忘了在AndroidManifest.xml加入下面兩行:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

下面是測試環境:
HTC Hero
Android 2.1 Eclair
Bluetooth GPS
Eclipse 3.5.2/3.7.1 + Android SDK

執行結果:
下圖是執行後的畫面:
環境:
手機 <--> 藍牙GPS接收器



手機 <--> PC+藍牙 <--> AccessPort
註:在手機打開程式後,按下 "可搜尋"此時手機變成藍牙slave角色 ,然後使用PC與手機配對,接著選擇配對後的COM Port按下連線,此時雙方就連線成功。
手機端畫面(接收):

手機端畫面(傳送):

電腦端畫面,採用軟體AccessPort(免費)


手機 <--> 8051+藍牙 <--> DS1821+GPIO

測試步驟 : 搜尋藍牙 --> 藍牙連接 --> DS1821溫度變化測試(8051) --> 8051 GPIO測試(LED亮滅)


應用1: 智慧家庭之電燈控制,使用兩個繼電器控制電燈。


應用2:車載資通訊運用,由於"敏哥"老師是車載資通訊的先驅,所以身為學生的我不能洩氣,花了一個晚上時間改寫了上述程式+OBD2藍牙讀取器+Car就完成下面結果。



後記:
1.在藍牙模組中RS-232的Baud rate在上述測試環境中皆設定9600,相關可參考: 執行AT命令(AT-command)修改藍芽模組的資料傳輸速率
2.藍牙模組我使用的是網拍中最便宜的,除非需要使用到class1 100米遠距離或者是低Baud rate的傳輸(1200 or 2400)否則不用花大錢買模組。另外Baud rate不要設超過115200,聽說會有斷線的問題。
3.市售的藍牙模組全都是Series Port Profile(UART/TTL),所以無法傳送檔案、聲音、...等其他功能。(已經有看到傳聲音的藍牙模組了!)
4.上述程式多少有些Bug,執行過程中出現問題的話建議使用logcat進行除錯;另外程式內說明如果不是很清楚的話可以Google搜尋一下,應該可以找到解答。


==============相關閱讀=====================
Java Native Interface (JNI) Android實戰篇(使用NDK) -- HelloUart

186 則留言:

  1. 請問可以跟您索取此SAMPLE CODE?

    回覆刪除
    回覆
    1. 目前所有的core文章內容全部沒有隱藏都貼出來了,至於layout部分您可以參考下篇的uart.xml。

      [ Android RS232 ] 在Android系統下實作RS232應用程式
      http://cheng-min-i-taiwan.blogspot.com/2012/01/android-rs232-androidrs232.html

      您試試看,如果有問題歡迎討論討論!

      刪除
    2. 因為code還蠻多的,我是初學者,怕打錯!
      如果可以的話,不知道可否提供完整的程式?
      如果不方便也沒關西,非常感謝這篇文章的分享,對我有很大的幫助!
      假如可以的話我將留下我的mail,請您提供我參考研究!

      非常感謝^^

      刪除
  2. 很久沒來這邊逛逛了, 看樣子我們文子哥很用心喔! 關於這個模組小弟可以給一點小小的建議, 由於這片藍芽模組預設值的鮑率是設定為9600bps,如果想要再快一點的話,可以透過AT command來修改, 有興趣的可以試看看

    回覆刪除
    回覆
    1. 您好,想請問一下如果藍芽模組已經設定好115200的話,
      android的程式要如何變更spp的baudrate?

      thanks!

      刪除
    2. 您可以參考之前的文章, 連結如下
      http://cheng-min-i-taiwan.blogspot.com/2012/01/android-rs232-androidrs232.html

      刪除
  3. 45行的程式SppServer sppServer
    SpperServer 這裡出現錯誤
    這個部份我看不太懂
    不知是不是有特殊的東西

    回覆刪除
    回覆
    1. 在程式108行會產生一個物件 sppServer = new SppServer();
      再產生物件前要宣告一個物件 SppServer sppServer; (45行)
      另外一種寫法也可以SppServer sppServer = new SppServer(); (45行去掉,改108行)

      SppServer sppServer;
      指的是類別MainActivity以類別SppServer為範本,宣告了一個物件,它的名字為 sppServer 。

      sppServer = new SppServer();
      等號右邊,new SppServer() 的意義是:以類別SppServer 為範本產生一個物件。
      經過指定運算 (等號) 後,這個以類別 SppServer 為範本所產生的新物件,它的名字就叫做 sppServer。

      這部分的資料可以從JAVA"物件與類別"部分查詢到,至於程式部分確定是沒問題的啦!因為我下面DEMO部分就是這支程式來跑的,您再確認一下。

      刪除
    2. 忘了說還前提要配合第186行的Class
      private class SppServer extends Thread {
      ...
      }

      刪除
  4. 你好~請問一下~若我不想顯示ASCII碼的文字~只想顯示數值~是改這一行嗎?
    msg = new String(data,0,length,"ASCII")+"\n";

    回覆刪除
    回覆
    1. 是的,這部分只是為了呈現出我們可以讀的資訊所轉換成ASCII的,下面的討論區有討論到這部分.....
      http://stackoverflow.com/questions/7793504/convert-a-string-of-bytes-into-ascii

      至於你要顯示數值的部分,如過你藍牙端傳過來的不是ASCII數值的話,就只要是要把接收到到資訊流轉換成數值既可。

      刪除
  5. 所以是資訊流轉換成數值再轉成String再透過msg傳出去嗎^^! 若問到笨問題請見諒~~~還是能否提供一下範例呢~就資訊流轉換成數值並傳出去這部份~

    回覆刪除
    回覆
    1. 資訊流我這邊把它定義成RS-232會餵給我們的資訊,程式中定義一個空間當作一個接收暫存空間,msg那行只是很單純的顯示訊息。
      舉個白話點的實例,例如GPS會一直送資訊到手機(資訊流)手機要先找個地方收容(string)然後要顯示出來GPS資訊的每一行(msg)就這樣而已。
      至於程式中252~278應該就是您需要的範例,相關參數你在程式中可以解讀出來的。這部分比較屬於 Java語言,如果還有看不懂的地方,你可以Google一下Java string部分。

      刪除
  6. 不好意思
    如果距離拉遠失去通訊 要怎麼寫阿


    我想寫一個失去通訊之後告知
    要怎麼改阿 一直改不出來

    回覆刪除
    回覆
    1. 這部分就要跟您說聲sorry囉~這個問題我曾思考過,藍芽class2通常都不到10米的傳輸距離,所以你所說的情況會經常發生,不過.....重點是還沒時間來做這段啦..

      刪除
  7. 不好意思
    請問一下關於傳送資料的部分
    我最近試著寫連接的部分已經可以成功連結藍芽裝置
    但是當我傳資料時卻發生錯誤
    我是使用324行上的btOut.write
    我有宣告OutputStream btOut
    這行程式還有跟其他行有連結嗎?
    我使這行時發生錯誤

    回覆刪除
    回覆
    1. 324行指的是將輸入的內容送給藍牙裝置,這個部分只會發生在你Button4的時候,所以你講的連結應該是要有一個在main.xml中要有EditText然後324行是將你輸入的字取出後改成String再轉成Bytes然後寫入藍芽裝置。
      如果你出錯的話建議你在前面加一些Log.i(tag, "輸入資訊")來追查看看是哪裡出錯,另外你可以用eclipse的DDMS來看出錯前Android裝置到底發生了何事,我的經驗是經常是出錯在送出去的值正確回覆的值原本應該會是數字結果回來字串導致輸出錯誤的經驗...你再試試看由於所提供的資訊不是很夠所以僅能回答這樣的結果。

      刪除
  8. 您好 我想請問您有沒有發生過 在將資料送出去時 他就會自己關閉呢~~
    當我想傳送資料給電腦時 可是按下SEND時 他就會自己跳離程式了

    我電腦傳送給手機是沒問題的@@~~

    回覆刪除
  9. 謝謝您前面的回答,也已經解決問題了

    關於程式碼249-277間都是為接收的程式部分
    是不是主要使用一個Thread在處理接收資料的部分
    那麼打輸入249-277行的程式並無法進行接收
    我有輸入第233行的程式start
    想問處此之外我有那裡沒有注意的道所以導致程式無法接收
    在這先感謝您的回答

    回覆刪除
    回覆
    1. 第108、109行有輸入嗎?我的建議是你用logcat來觀察有沒有抓到Log.i(tag, "SppReceiver");的訊息,如果沒有的話可以往上追蹤看看...如過沒有資料送進來的話,Thread每起來的機會很大ㄡ....

      刪除
  10. 我已經解決問題了 原來是button搞反 難怪一點SEND 就離開

    回覆刪除
  11. 您好
    關於接收資料的部分
    您是在258行設一個byte[] data作為接收藍芽傳進來的資料所暫存的陣列
    而今天的設備傳進來的是如0x02這樣char型態的資料
    那我是否只要將data改成char[]的型態就可以了呢?
    我直接改的結果
    會在下半部的write函式中出現錯誤
    我的理解是write函式無法用在char型態的陣列
    因為JAVA關於資料流傳輸的部份我尚為初學
    但最近得將程式先趕出來
    所以來向您請教
    當傳入資料為char型態時
    需要修改或注意哪些地方?
    直接這樣向您請教
    如有冒犯的地方
    敬請見諒
    謝謝

    回覆刪除
    回覆
    1. 抱歉!一直沒有看到您的問題,拖到今天才回...也許你的問題已經解了!
      你有試過將char 轉成 byte 嗎?
      程式中我也是將收到的資訊轉成ASCII
      或將送出的text轉成 byte給藍牙..
      不過我藍牙送出來的部分都自己寫協定,倒是沒有寫成char的方式,所以.....可能幫不上啥!Sorry!!
      @@|||

      刪除
  12. 您好
    請問手機預設的鮑率是9600嗎??
    要如何做調整呢??

    回覆刪除
    回覆
    1. 我使用的經驗是手機中不用設定鮑率我用過9600與4800差別,不過有些設備在讀取資料時要控制delay time長短才能不會有段行才能完整接受到正確訊息,至於115200部分因為擔心連線不穩定我倒是沒試過的.....

      刪除
  13. 請問一下 你這支程式 我裝在2支手機上 用你的程式在兩支手機上傳送訊息嗎?

    其實我有測試過 但是連接裝置的時候 他出現連接埠的異常問題

    回覆刪除
  14. 你好 我看完了你的範例之後照著打了一個 但是我一跑模擬後他會自己突然停止耶
    我對照了很多次 程式碼都沒錯 但是就是會自己突然停止 還是有什麼地方需要增加東西我沒用到??

    回覆刪除
    回覆
    1. 將你Logcat發生錯誤的前面一段貼上來!

      刪除
  15. 你好
    我將程式碼照打了一遍之後
    模擬器沒有辦法跑 他會強制關閉
    後來丟到手機去測試
    手機在開關藍芽以及可被偵測部份都可以動作
    也可以成功搜尋到其他藍芽裝置
    但是按下連結裝置按鈕之後他顯示"連結埠異常"

    回覆刪除
    回覆
    1. 1.藍牙在模擬器目前應該尚未支援...
      2.要確認接收的裝置是否為SPP裝置!

      刪除
    2. 感謝看來是模擬器沒支援

      刪除
  16. 07-07 14:16:30.440: E/AndroidRuntime(343): java.lang.RuntimeException:
    Unable to start activity ComponentInfo{bbt.Android/bbt.Android.BbtActivity}:
    java.lang.NullPointerException

    是這一段嗎??

    回覆刪除
    回覆
    1. 您的這個範例會使用到前面HelloUart中Android.mk和hello_uart.c
      這2個因為我看完了HelloUart的範例後發現有少這幾種東西,會不會是因為這樣所以才會無法執行?

      刪除
    2. 從java.lang.NullPointerException這個訊息搜尋了一下Google似乎你的設備會丟null的東西導致程式中斷(猜測的!!),或許你可以在程式269行左右 /* 接收SPP訊息.... */ 下一個Log.d查看你接收的資料是不是沒處理好造成程式中斷。

      刪除
    3. 另外Android.mk和hello_uart.c是jni的.....跟這篇完全沒關係。

      刪除
  17. 您好,我照版大上面的全部key過一次,也檢查了不少次
    但每當一執行到 btAdapt.startDiscovery(); 就會出現異常終止
    請問版大有解嗎
    感謝

    回覆刪除
    回覆
    1. 在btAdapt.startDiscovery();前面加Log.d(tag,"本機藍牙位址:" + btAdapt.getAddress());查看有無抓到本機藍牙,如果沒有就往上追程式看哪邊key錯了。
      PS:這個動作前要確定藍牙是開啟狀態....

      刪除
    2. 您好,
      我和"平常心"依樣執行到btAdapt.startDiscovery();就會出現異常中止耶
      加入您建議的Log.d(tag,"本機藍牙位址:" + btAdapt.getAddress());
      查的到本機藍芽!
      但無法執行><
      請問版大有解嗎?
      謝謝您!!
      ___________________________________________________________
      10-31 22:47:30.210: D/qdmemalloc(15389): ion: Mapped buf base:0x6e0c2000 size:8355840 offset:0 fd:58
      10-31 22:47:30.210: D/qdmemalloc(15389): ion: Mapped buf base:0x66e3a000 size:4096 offset:0 fd:59
      10-31 22:47:30.290: D/qdmemalloc(15389): ion: Mapped buf base:0x6f0c3000 size:8355840 offset:0 fd:60
      10-31 22:47:30.290: D/qdmemalloc(15389): ion: Mapped buf base:0x67601000 size:4096 offset:0 fd:61
      10-31 22:47:44.285: D/ㄚㄚㄚㄚ!!!!!!!!!!!!!!!!!!!!(15389): 本機藍牙位址:98:0D:2E:27:39:28
      10-31 22:47:44.285: W/dalvikvm(15389): threadid=1: thread exiting with uncaught exception (group=0x415e8970)
      10-31 22:47:44.285: E/AndroidRuntime(15389): FATAL EXCEPTION: main
      10-31 22:47:44.285: E/AndroidRuntime(15389): java.lang.SecurityException: Need BLUETOOTH ADMIN permission: Neither user 10055 nor current process has android.permission.BLUETOOTH_ADMIN.
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.os.Parcel.readException(Parcel.java:1440)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.os.Parcel.readException(Parcel.java:1394)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.bluetooth.IBluetooth$Stub$Proxy.cancelDiscovery(IBluetooth.java:989)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.bluetooth.BluetoothAdapter.cancelDiscovery(BluetoothAdapter.java:881)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at com.example.bt_connect.MainActivity$4.onClick(MainActivity.java:293)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.view.View.performClick(View.java:4280)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.view.View$PerformClick.run(View.java:17984)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.os.Handler.handleCallback(Handler.java:730)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.os.Handler.dispatchMessage(Handler.java:92)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.os.Looper.loop(Looper.java:158)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at android.app.ActivityThread.main(ActivityThread.java:5789)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at java.lang.reflect.Method.invokeNative(Native Method)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at java.lang.reflect.Method.invoke(Method.java:525)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:843)
      10-31 22:47:44.285: E/AndroidRuntime(15389): at dalvik.system.NativeStart.main(Native Method)

      刪除
  18. 嗯嗯 我解決的 謝謝 那可以再請問你ScrollView是怎麼設定的 我自己擺的方式它好像是都沒有動作 是把它和msgtext放在一起嗎? 有上網去找了一下 但是還是看不太懂

    回覆刪除
    回覆
    1. 改(參考) http://cheng-min-i-taiwan.blogspot.tw/2012/01/android-rs232-androidrs232.html 這篇中的 uart.xml.....

      刪除
  19. 您好
    先前因為也有需要手機連接RS232介面之sensor的應用
    而使用您所提及的這個程式
    但一直有一問題無法解決
    若我以橫放的方式開啟程式則不會有問題
    但一旦以直立的方式開啟或是從橫放轉為直立時
    程式就會強制關閉
    而loacat出現的紅字訊息為

    07-10 18:03:32.399: E/InputDispatcher(2715): channel '40a8a5f0 com.android.TestLayout/com.android.TestLayout.TestLayoutActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8

    07-10 18:03:32.399: E/InputDispatcher(2715): channel '40a8a5f0 com.android.TestLayout/com.android.TestLayout.TestLayoutActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

    因為程式碼與您的一樣
    也做了許多確認的動作
    所以想請問您是否有遇過一樣的問題
    謝謝

    回覆刪除
  20. 這是因為當螢幕旋轉時會觸發onCreate()所導致,解決方法你可以參考下面網站:
    http://blog.yam.com/jackiefu/article/38667492
    不過通常我比較懶直接就指定我要螢幕是橫向還是直立:
    int currentOrientation = getResources().getConfiguration().orientation;
    switch(currentOrientation) {
    case Configuration.ORIENTATION_LANDSCAPE:
    break;
    case Configuration.ORIENTATION_PORTRAIT:
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    break;
    default:
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }

    回覆刪除
  21. 版大您好
    我的程式似乎只要碰到startDiscovery();
    程式就會自動關閉,請問有沒有辦法解,手機是acer的E140
    程式已檢查過好幾次了....

    我程式寫好後都用模擬器跑過一次後(雖然不能在電腦上模擬),再將整個程式的資料夾放到手機裡,再按XXXX.apk安裝完後執行,還是說我的步驟有錯呢??
    請問大大是否可解呢 感謝

    回覆刪除
    回覆
    1. 將你Logcat發生錯誤的開始部分貼上來!

      刪除
  22. 請問您第二次影片顯示:搜尋藍牙 --> 藍牙連接 --> DS1821溫度變化測試(8051) --> 8051 GPIO測試(LED亮滅),除了手機我看得懂外,另外兩個工具是甚麼?尤其是有一個板子可以有LED燈顯示?

    回覆刪除
    回覆
    1. 這只是很簡單的8051+GPIO+RS-232的板子,當時用洞洞板焊出來的所以做成兩塊一塊主體,另一塊只有LED如此而已。

      刪除
    2. 作者已經移除這則留言。

      刪除
  23. 程式第101-104行的Intent.addAction會出err?

    回覆刪除
    回覆
    1. 可能需要再確認一下:
      1.藍牙有沒有開啟??
      2.AndroidManifest.xml(權限)有沒有加入下面兩行??
      <uses-permission android:name="android.permission.BLUETOOTH" />
      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
      3.如果還是有錯誤需要錯誤Log資訊.....

      刪除
    2. key錯大小寫,改成小寫就可以執行了,謝謝.另外請教一下,現在只要按下send鍵,程式就會跳出去,我找不到bug..?

      刪除
    3. 需要你DDMS的錯誤Log,你把出錯開始的3~5行貼上來^^

      刪除
    4. 08-23 11:34:06.388: W/System.err(4366): at android.bluetooth.BluetoothSocket.acceptNative(Native Method)
      08-23 11:34:06.388: W/System.err(4366): at irdc.com.tw.TEST1$SppServer.run(TEST1.java:213)
      08-23 11:34:06.388: D/BtSPP(4366): ServerSocket accept failed

      08-23 11:34:35.697: W/System.err(4366): java.io.IOException: Service discovery failed
      08-23 11:34:35.717: W/System.err(4366): at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:403)
      08-23 11:34:35.737: W/System.err(4366): at android.os.Handler.dispatchMessage(Handler.java:92)
      08-23 11:34:35.737: W/System.err(4366): at android.os.Looper.loop(Looper.java:156)
      08-23 11:34:35.737: W/System.err(4366): at android.app.ActivityThread.main(ActivityThread.java:4977)
      08-23 11:34:35.737: W/System.err(4366): at java.lang.reflect.Method.invokeNative(Native Method)
      08-23 11:34:35.737: W/System.err(4366): at java.lang.reflect.Method.invoke(Method.java:511)
      08-23 11:34:35.737: W/System.err(4366): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
      08-23 11:34:35.737: W/System.err(4366): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
      08-23 11:34:35.747: W/System.err(4366): at dalvik.system.NativeStart.main(Native Method)

      刪除
    5. 點選連接裝置會時出現"連接阜異常"..這個連街阜是指哪個?手機還是電腦?

      刪除
    6. 第三行:
      08-23 11:34:06.388: D/BtSPP(4366): ServerSocket accept failed
      這是程式第214行出現的問題,也就是說202行try{ ....}出錯了,往上追看看btServerSocket部分有每有出錯例如UUID等,應該是在連結時就出錯了,可以多放幾個Log.d追追看程式。

      另外,確認藍牙對方設備是Serial Port Profile(SPP)??如果對方是手機的話我沒有試過這隻程式ㄡ!不確定可以使用.....
      PS:如果是手機隊手機傳訊息的話,請參考/samples/android-/BluetoothChat這裡有一個藍牙聊天的程式可以參考。

      刪除
    7. 我用筆電跟手機互聯的,筆電是Acer win7系統,手機則是HTC One V.所以手機只能變成Slaver端,才可以被筆電搜尋到,而兩個系統似乎在打架似的,可以配對成功,但是一按下連接的按鈕時,就會出現"連接阜"異常.

      刪除
    8. 嗯嗯!您做的跟我文章中手機 <--> PC+藍牙 <--> AccessPort 作的是同一個實驗,我的作法是手機開啟"可搜尋"就可以了,然後由PC那邊來配對,這樣兩邊就可以互相傳文字,如果不用AccessPort的話用超級終端機也行,您在試試,從你的 Log看出應該是裝置SPP還沒連通..

      刪除
  24. 你好
    我照你的程式打完也檢查很多次
    但是一執行之後就異常終止
    請問這是哪裡錯誤了?

    回覆刪除
    回覆
    1. 需要你DDMS的錯誤Log,你把出錯開始的3~5行貼上來!!

      刪除
    2. 謝謝問題解決了

      刪除
  25. 請問要自行斷線要怎麼做?

    回覆刪除
    回覆
    1. 請參考BluetoothAdapter內容,看看STATE_OFF與STATE_TURNING_OFF哪個項目符合你的需求。
      http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html

      刪除
    2. 作者已經移除這則留言。

      刪除
  26. 我要做1對2的SERVER,要怎麼做才可以知道我要傳給誰和接到誰的,還有再接收完的顯示的HANDLE裡寫太多判斷它就會擋掉,我要能快速的接收和判斷,要怎麼改才好,請求版主的協助。

    回覆刪除
    回覆
    1. Sorry!!沒做過類似的需求..你可以參考http://www.arm9home.net/read.php?tid=22364
      不過該作者不是在藍牙上做但有提供程式碼。

      刪除
  27. 想問一下作左有手機 <--> 8051+藍牙 <--> DS1821+GPIO
    藍芽和8051的CODE可以分享一下嗎?
    如果不能分享的話,可不可以給小弟作者你的聯絡方法(如MSN或QQ等)
    因小弟最近在做類似的PROJECT,但在APP和8051如何與手機交流上頻頻出錯
    希望可以得到作者的幫助.
    謝謝

    回覆刪除
  28. 請問一下8051 如何連接藍牙?
    如何由藍牙傳送資料給8051?
    http://i.imgur.com/se1ux.jpg
    是否把上圖的腳連接到8051 的port 內?

    回覆刪除
    回覆
    1. 找出藍牙模組的rx tx腳位,接到8051的tx rx腳位就可以了。

      刪除
  29. 手機 <--> 8051+藍牙 <--> DS1821+GPIO

    想請問一下假如現在藍芽已經 可以收尋連接和被尋找

    那麼我們要怎樣才能透過手機接收到RS232+藍芽模組 上面的溫度
    然後回傳到手機上顯示

    還有像遠端控制電燈on/off 她大概會怎樣接收指令呢?

    回覆刪除
    回覆
    1. 最簡單的方式就是定義將溫度數字送一份到rs232然後透過藍牙送到手機,GPIO也相同你可以設定類似從RS232送"1"讓pin 1 為high之類的...

      刪除
    2. 定義將溫度數字送一份到rs232
      這個部分是要在哪裡寫?

      還是不太懂

      刪除
    3. 這部分在MCU內寫,大概流程如下:溫度數據--> tx --> 藍牙 RX -->手機接收。
      這部份如果你的MCU是8051的話網路找一下很多資料的。

      刪除
    4. 作者已經移除這則留言。

      刪除
  30. hello 想問一下我想用handler startdiscovery 更新rssi 但好像效率 不怎麼好 要10秒左右才會搜尋一次

    回覆刪除
  31. 作者已經移除這則留言。

    回覆刪除
  32. HELLO~ 請問一下...我依照樓主方式,但是模擬器沒有辦法跑 一直強制關閉....
    是我打錯字?請問樓主文中Android.mk和hello-uart.c 是一定要像 "Java Native Interface (JNI) Android實戰篇(使用NDK) -- HelloUart"這部分中改变?

    回覆刪除
    回覆
    1. 模擬器無法執行藍牙程式!
      另外,本文跟JNI無關所以程式不用Android.mk和hello-uart.c

      刪除
    2. 作者已經移除這則留言。

      刪除
    3. THX 蚊子樓主@.@(十分快地回覆)若果可以請問可以給我樓主您E-MAIL?十分感謝;若果我APPS介面佈局十分差,會有影响?

      刪除
    4. 作者已經移除這則留言。

      刪除
  33. 作者已經移除這則留言。

    回覆刪除
  34. 我想請問一下為什麼一按下 @+id/uart_button4 (SEND)會自動關閉,於無任何bluetooth偵查情況下



    回覆刪除
    回覆
    1. 需要你DDMS的錯誤Log,你把出錯開始的3~5行貼上來!!

      刪除
  35. 11-12 01:49:33.620: E/AndroidRuntime(338): FATAL EXCEPTION: main
    11-12 01:49:33.620: E/AndroidRuntime(338): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.hellouart/com.example.hellouart.MainActivity}: java.lang.NullPointerException
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.os.Handler.dispatchMessage(Handler.java:99)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.os.Looper.loop(Looper.java:123)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.ActivityThread.main(ActivityThread.java:3683)
    11-12 01:49:33.620: E/AndroidRuntime(338): at java.lang.reflect.Method.invokeNative(Native Method)
    11-12 01:49:33.620: E/AndroidRuntime(338): at java.lang.reflect.Method.invoke(Method.java:507)
    11-12 01:49:33.620: E/AndroidRuntime(338): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    11-12 01:49:33.620: E/AndroidRuntime(338): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    11-12 01:49:33.620: E/AndroidRuntime(338): at dalvik.system.NativeStart.main(Native Method)
    11-12 01:49:33.620: E/AndroidRuntime(338): Caused by: java.lang.NullPointerException
    11-12 01:49:33.620: E/AndroidRuntime(338): at com.example.hellouart.MainActivity$SppServer.(MainActivity.java:187)
    11-12 01:49:33.620: E/AndroidRuntime(338): at com.example.hellouart.MainActivity.onCreate(MainActivity.java:106)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    11-12 01:49:33.620: E/AndroidRuntime(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    11-12 01:49:33.620: E/AndroidRuntime(338): ... 11 more

    回覆刪除
    回覆
    1. 您的問題曾經回覆過,請看2012年7月7日回覆的解答。

      刪除
    2. 依照蚊子樓主 到GOOGLE找,但是結果問題依然是這樣,請問可以指導小弟一下?.?"""

      刪除
    3. 你要先追蹤一下為何會收到null值是設備問題還是程式抓的時間點造成null值,這部份最好用Logcat來抓,然後在程式中多增加一個忽略null值,我想應該就可以解決了。

      刪除
  36. 請問樓主是上面這一些?....我連DDMS 都不會用
    (不好意思) ;加上若果把手提倒橫會自動關掉 是否文中没有這功能 ,辛苦樓主

    回覆刪除
    回覆
    1. 問答中有回覆過類似問題,請看2012年7月10日那個回覆。

      刪除
    2. 這裡可以 無問題 THX~~~ >"<""

      刪除
  37. 請問蚊子樓主,如何利用bluetooth接收DATA由 IC 或電腦 (可以指導一下?)
    ;同時,想問一下樓主 這程式中有考慮到 ?若果無任何DATA下 按SEND 這BUTTON, 會有TOAST 這一指令 說"請輸入DATA" 這一些?

    回覆刪除
    回覆
    1. 這部分:
      1.你在Google搜尋一下"8051+藍牙" 或者 "arduino+藍牙" 可以找到不少參考資料。
      2.在程式320-321間加入if判斷sendEdit.getText().toString()是不是null就可以達到了,試試看...

      刪除
  38. 現在一按下SEND BUTTON 程式就自己關閉,但一般來說都是無問題~~

    回覆刪除
    回覆
    1. 從你先前的Log看到,你的問題很大的可能出現在"java.lang.NullPointerException",也就是接收到Null值,所以你的程式需要再送出的案件事件再送出前排除送出Null的值(也有可能出現在"接收"到 Null)用Logcat追蹤一下,應該可以解。

      刪除
  39. 請問一下,有例子是可以由藍牙模組發送data(藍牙模組是接著硬件,例如8051). 然後,由Android接收data 計算出答案?

    回覆刪除
    回覆
    1. 嗯嗯!觀念大致如此...

      刪除
    2. 意思是指這程式有由IC接收數據功能?@@

      刪除
    3. 由於MCU的觀念並非一時一刻用幾個字可以說明的清楚,
      網路上我找到了一篇類似您的需求,他的 MCU用的是TI MSP430+BT ---溫度-> Android
      網址如下,您參考看看MCU的部分可以改成8051之類的,至於MCU程式及電路部分在google上蒐一下就可以找到不少....
      http://www.mikekohn.net/micro/bluetooth_thermometer.php

      刪除
  40. 不好意思,最近遇到一些問題,
    這個問題你上面有些許提到
    就是關於"接收資料截斷問題"
    這個問題你上面是說需要去控制Delay
    這個意思是如果傳輸資料量較大,
    傳資料的裝置,Delay時間也要變長
    還是縮短

    回覆刪除
    回覆
    1. 這就要測試了,又或者送資料的裝置Baud rate太高所導致,所以你必須要計算出正確的時間區接收。如果時間不好抓,正確的作法應該要定義好送資料的裝置的"協定",最好能有一些CRC、parity check之類的,這樣接收端增加接收的封包來解資料會比較正確。

      刪除
  41. 請問第79行spinner1=(Spinner) findViewById(R.id.uart_btselect);
    這樣是對的嗎@@?因為我先把它改成uart_select了...
    還是說是要另外設定uart_btselect?

    12-18 02:53:58.036: E/AndroidRuntime(276): FATAL EXCEPTION: main
    12-18 02:53:58.036: E/AndroidRuntime(276): java.lang.RuntimeException: Unable to start activity ComponentInfo{idv.android.hellobtuart/idv.android.hellobtuart.MainActivity}: java.lang.NullPointerException
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.os.Handler.dispatchMessage(Handler.java:99)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.os.Looper.loop(Looper.java:123)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.ActivityThread.main(ActivityThread.java:4627)
    12-18 02:53:58.036: E/AndroidRuntime(276): at java.lang.reflect.Method.invokeNative(Native Method)
    12-18 02:53:58.036: E/AndroidRuntime(276): at java.lang.reflect.Method.invoke(Method.java:521)
    12-18 02:53:58.036: E/AndroidRuntime(276): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    12-18 02:53:58.036: E/AndroidRuntime(276): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    12-18 02:53:58.036: E/AndroidRuntime(276): at dalvik.system.NativeStart.main(Native Method)
    12-18 02:53:58.036: E/AndroidRuntime(276): Caused by: java.lang.NullPointerException
    12-18 02:53:58.036: E/AndroidRuntime(276): at idv.android.hellobtuart.MainActivity$SppServer.(MainActivity.java:190)
    12-18 02:53:58.036: E/AndroidRuntime(276): at idv.android.hellobtuart.MainActivity.onCreate(MainActivity.java:109)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    12-18 02:53:58.036: E/AndroidRuntime(276): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    12-18 02:53:58.036: E/AndroidRuntime(276): ... 11 more


    感覺也有7/7的問題存在...不過我卻不知道發生甚麼事情...

    回覆刪除
  42. 請問樓主,若果要由MCU接收Data ,然後由Android 顯示結果要如何...(用藍牙模組

    回覆刪除
  43. 01-17 11:22:40.207: D/ddm-heap(224): Got feature list request
    01-17 11:22:40.247: W/dalvikvm(224): Exception Ljava/lang/NumberFormatException; thrown during Lcom/example/new0116/MainActivity;.
    01-17 11:22:40.256: W/dalvikvm(224): Class init failed in newInstance call (Lcom/example/new0116/MainActivity;)
    01-17 11:22:40.256: D/AndroidRuntime(224): Shutting down VM
    01-17 11:22:40.256: W/dalvikvm(224): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
    01-17 11:22:40.256: E/AndroidRuntime(224): Uncaught handler: thread main exiting due to uncaught exception
    01-17 11:22:40.266: E/AndroidRuntime(224): java.lang.ExceptionInInitializerError
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.lang.Class.newInstanceImpl(Native Method)
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.lang.Class.newInstance(Class.java:1479)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.os.Handler.dispatchMessage(Handler.java:99)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.os.Looper.loop(Looper.java:123)
    01-17 11:22:40.266: E/AndroidRuntime(224): at android.app.ActivityThread.main(ActivityThread.java:4363)
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.lang.reflect.Method.invokeNative(Native Method)
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.lang.reflect.Method.invoke(Method.java:521)
    01-17 11:22:40.266: E/AndroidRuntime(224): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    01-17 11:22:40.266: E/AndroidRuntime(224): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    01-17 11:22:40.266: E/AndroidRuntime(224): at dalvik.system.NativeStart.main(Native Method)
    01-17 11:22:40.266: E/AndroidRuntime(224): Caused by: java.lang.NumberFormatException: OOOOllOl
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.lang.Long.parse(Long.java:351)
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.lang.Long.parseLong(Long.java:341)
    01-17 11:22:40.266: E/AndroidRuntime(224): at java.util.UUID.fromString(UUID.java:231)
    01-17 11:22:40.266: E/AndroidRuntime(224): at com.example.new0116.MainActivity.(MainActivity.java:36)
    01-17 11:22:40.266: E/AndroidRuntime(224): ... 15 more
    01-17 11:22:40.287: I/dalvikvm(224): threadid=7: reacting to signal 3
    01-17 11:22:40.296: I/dalvikvm(224): Wrote stack trace to '/data/anr/traces.txt'

    回覆刪除
  44. 大家好,以上是我的LOG,請會的幫幫忙,拜託拜託!感激不盡
    版大~如果看到,請幫幫我呀!感恩~

    回覆刪除
  45. 1. check program 是否有輸入錯誤。(Sorry!!錯誤碼我判斷不出來,但覺得你程式應該有key錯地方)
    2. BT一定要在實體Android裝置執行。

    回覆刪除
    回覆
    1. uart_select 跟 uart_btselect 應該就是把bt去掉,那應該沒問題吧?
      還是要有select 和 btselect 兩個?

      刪除
    2. 原本這段要刪掉嗎?(建立後就已經在裡面的最後一段)

      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.activity_main, menu);
      return true;
      }

      刪除
    3. //將訊息顯示在Textview中畫面*/
      Handler btHandler = new Handler() {
      public void handleMessage(Message m) {
      msgText.append(msg);←←←←←
      scrollView.fullScroll(ScrollView.FOCUS_DOWN); //捲軸自動卷至最底
      }
      };

      這段 msgText.append(msg); 有黃色是因為?

      刪除
    4. 我用手機測試是直接關閉

      刪除
    5. 能否私訊呢?
      FB?SK?RC? 之類

      刪除
    6. 這是我的 Console

      at com.android.ddmlib.AdbHelper.setDevice(AdbHelper.java:752)
      at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:373)
      at com.android.ddmlib.Device.executeShellCommand(Device.java:462)
      at com.android.ddmuilib.logcat.LogCatReceiver$1.run(LogCatReceiver.java:109)
      at java.lang.Thread.run(Unknown Source)

      刪除
    7. 可以執行了,我把108、109行註解掉,經手機測試後,可搜尋
      但是,"連接裝置""送出"兩個按鍵會自動跳出,然而我往上翻有看到
      ↓↓↓↓↓
      2012年4月18日上午10:31
      第108、109行有輸入嗎?我的建議是你用logcat來觀察有沒有抓到Log.i(tag, "SppReceiver");的訊息,如果沒有的話可以往上追蹤看看...如過沒有資料送進來的話,Thread每起來的機會很大ㄡ....

      想請教
      Q1.有關聯嗎?
      Q2.怎找出BUG?

      刪除
  46. 可以執行了,我把108、109行註解掉,經手機測試後,可搜尋
    但是,"連接裝置""送出"兩個按鍵會自動跳出,然而我往上翻有看到
    ↓↓↓↓↓
    2012年4月18日上午10:31
    第108、109行有輸入嗎?我的建議是你用logcat來觀察有沒有抓到Log.i(tag, "SppReceiver");的訊息,如果沒有的話可以往上追蹤看看...如過沒有資料送進來的話,Thread每起來的機會很大ㄡ....

    想請教
    Q1.有關聯嗎?
    Q2.怎找出BUG?
    Q3.點選
    at om.example.new0116.MainActivity$7.onClick(MainActivity.java:327)
    跳至
    btOut.write(sendEdit.getText().toString().getBytes());

    這行有怎樣嗎?

    回覆刪除
    回覆
    1. ps. btOut.write(sendEdit.getText().toString().getBytes());
      是第324行

      刪除
    2. 這行是你要將你輸入的資訊從Android送出去,
      1.你必須先確認接收端裝置能接收的資料格式,如過是ASCII的話那可以用這行,但如果是HEX的話那這個部分要處理後才能送出去。
      2.你可以用本文中執行結果2(手機 <--> PC+藍牙 <--> AccessPort )的方式先測試一下你藍牙程式再送出資料時是否有問題(先排除送出資料的問題)。

      刪除
  47. 蚊子版主你好

    我目前正在寫一個OBDII的程式,依造你的程式架構去修改我要的內容

    現在卡在我收不到OBD送來的訊息,可是我拿藍芽GPS 發射器卻可以收到

    所以SPP應該是有通,是否我需要對OBD下什麼樣的Command,他才會吐資訊出來

    麻煩解答,感謝

    回覆刪除
    回覆
    1. 詳見:
      http://en.wikipedia.org/wiki/OBD-II_PIDs

      刪除
    2. 感謝解答
      再請問一下,我想要取得RPM,我送cmd的程式碼如下
      final String cRPM = "010C";
      try {
      btOut.write(cRPM.getBytes("ASCII"));
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      可是收到的內容卻不是正確的值,請問這樣送cmd作法是對的嗎?

      刪除
    3. 按照前面網頁所述:
      1.你要確認你的ODB是否在MODE 01 模式下(這部份下AT SP 0 應該就可以了,詳見OBD 所使用的 IC datashee上面會有明確說明)
      2.送收都是Hex 所以你改一下btOut.write(cRPM.getBytes());
      3.回來的訊息你應該會看到xx xx xx xx ... 之類的,參考前面的網頁你就可以得到正確得位元值;然後帶入網頁中的"公式"才可以計算出正確的數字。
      您再試試看....

      刪除
  48. 請問如果我想用2隻手機+8051,一隻server一隻是clinet
    我先讓server連結到8051,連接成功後等待client連結server,client傳資料給server,server就傳給8051也就是client->server->8051
    以藍芽來說可以這樣做嗎?
    謝謝

    回覆刪除
  49. 如果我記得沒錯的話,目前手機上藍牙應該是無法同時做到主/從,而且藍牙主裝置(Master)"同時間"只能夠接受7的從裝置(Slave),所以如果你的架構我會建議:
    client --BT--> server --WiFi--> 8051
    or
    client --WiFi--> server --WiFi--> 8051

    回覆刪除
  50. 請問樓主,有一些有關藍芽接收數據要如何寫?若果是由MCU 接收數據,是否要換上UUID?

    回覆刪除
  51. 作者已經移除這則留言。

    回覆刪除
  52. 你好
    可以跟你要下面那兩個實作的原始碼嗎?
    謝謝

    回覆刪除
  53. 版大我想請問一下
    為什麼可以搜尋到手機藍芽,但是按下connect時,卻連接埠異常!!
    可以幫忙解決一下嘛謝謝你的大德!!

    回覆刪除
    回覆
    1. Log,你把出錯開始的3~5行貼上來!!

      刪除
    2. to 蚊子版主
      03-04 14:17:32:613 E 329 AndroidRuntime FATAL EXCEPTION: main
      03-04 14:17:32:613 E 329 AndroidRuntime java.lang.RuntimeException:Unable to start activity ComponentInfo{jan.tt/jan.tt.Main}:java.lang.NullPointerException
      03-04 14:17:32:613 E 329 AndroidRuntime at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
      03-04 14:17:32:613 E 329 AndroidRuntime at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
      03-04 14:17:32:613 E 329 AndroidRuntime at android.app.ActivityThread.access$1500(ActivityThread.java:117)
      03-04 14:17:32:613 E 329 AndroidRuntime at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
      03-04 14:17:32:613 E 329 AndroidRuntime at android.os.Handler.dispatchMessage(Handler.java:99)
      03-04 14:17:32:613 E 329 AndroidRuntime at android.os.Looper.loop(Looper.java:123)
      大概這幾行。
      我知道模擬器無法模擬藍芽,我是使用實際手機來操作,搜尋都正常,但是一旦按下連結鍵就會出現"連接埠異常",
      是否跟UUID有關呢?

      刪除
    3. UUID如果使用的是uart不用改,看來有可能收到裝置名稱時沒有轉成String造成你按下連結時是連結到一個Null名稱,試著在選擇介面後到連接介面前放個 Log.d(tag, 連接裝置名稱)看看拿裡遺漏了。

      刪除
    4. 作者已經移除這則留言。

      刪除
    5. to蚊子版主:
      我再接收SPP訊息找出了錯誤,之後重新匯出成apk
      在手機上又實做了一次,第一次成功了
      可以成功的接收從另一之手機丟出來的資料
      可是之後又重新connect,卻又開始出現連接埠異常!
      這是什麼原因呢?

      刪除
    6. 手機與手機的通訊,這部分我並沒有實做過,不過你可以參考API裡面那支Bluetooth Chat看看:
      http://jayxie.com/mirrors/android-sdk/resources/samples/BluetoothChat/index.html

      刪除
    7. 好的!謝謝蚊子版主耐心解答感恩!
      有問題再向您請教 謝謝

      刪除
  54. 作者已經移除這則留言。

    回覆刪除
  55. 我用AVD模擬 不過打不開 會出現這段SORRY!警告: The application Bluetooth has stopped unexpectedly.
    然後我把它轉成APK想裝到手機測試,結果不能安裝,我試了其他自製的APK可以安裝。而且我這個APK 沒有出現 安裝內容(類似網路通訊 系統工具 等等的允許選項)

    回覆刪除
    回覆
    1. 作者已經移除這則留言。

      刪除
  56. 03-16 12:13:09.524: E/AndroidRuntime(284): Uncaught handler: thread main exiting due to uncaught exception
    03-16 12:13:09.534: E/AndroidRuntime(284): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.bluetooth/com.example.bluetooth.MainActivity}: java.lang.NullPointerException
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.os.Handler.dispatchMessage(Handler.java:99)
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.os.Looper.loop(Looper.java:123)
    03-16 12:13:09.534: E/AndroidRuntime(284): at android.app.ActivityThread.main(ActivityThread.java:4363)

    回覆刪除
    回覆
    1. 你的問題應該也是跟前面的Log相同(java.lang.NullPointerException),我猜測你在執行Thread接受訊號時,你有收到Null之類的,你可以試試看在程式碼接收訊號時排除Nulll字串。

      刪除
  57. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 找找看有沒有myButton0 = (Button) finViewById(R.id.....

      刪除
  58. 版大好:

    我用不同廠牌的溫度sensor,做了一個模組,該模組採用USB介面,完成後接上pc的
    USB port,打開pc端的驗證程式,收到如下的訊息:
    A2 E0 01 02 08 05 06 07 A3
    01 = 溫度正負符號
    02 = 溫度十位數
    08 = 溫度個位數
    05 = 溫度小數位
    06 = 濕度十位數
    07 = 濕度個位數
    其他A2、E0、A3為封包頭尾。

    我想寫一個小app直接顯示上述值,我看書上寫要用SensorManager、Sensor.AMBIENT_TEMPERATURE
    但是版大的主程式都沒用到。是否只有內建sensor才用以上類別及方法,
    外接sensor必須用版大的方法?

    寫的時候是否有需要注意的地方,請版大指導。

    回覆刪除
  59. 請問一下
    關於btAdapt = null這件事要怎麼處理,才能使它變成不是空指標

    回覆刪除
    回覆
    1. http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html

      刪除
    2. 可以使用try catch的方法來排除掉null。

      刪除
  60. 您好

    我想請問,若要將android發送數值給pc的這部分,改成發送給另一個activity,請問要如何修改?

    請問要修改哪段程式碼?

    回覆刪除
    回覆
    1. 249行 SppReceiver Thread這段,相關程式碼可以找有關於Thread的文章或書籍參考一下。

      刪除
  61. 蚊子版主我想請問怎樣才可以設計成像 應用2:車載資通訊運用 這樣
    所接收到的數字可以在TEXTVIEW裡一直刷新~
    可以指點我一下嗎謝謝

    回覆刪除
    回覆
    1. 改264~277行程式,接收訊息後把訊息送到textview後下一個sleep暫停一下指令即可。

      刪除
    2. 那,那邊也是使用ScrollView 嗎?
      還是其實不需要呢?

      刪除
    3. 不用,這是顯示接收傳回來結果用的!

      刪除
    4. 請問 那個OBDII 傳送的是ASCII值嗎?
      另外我每次要連接藍芽裝置的時候
      第一次都會先跳掉
      要開第二次才可以
      這大概是什麼問題呢?
      謝謝

      刪除
    5. ANS:
      1.這要看OBD與藍牙中間用啥來介接了,一般網拍在賣的大多為ELM327,建議您看一下相關datasheet會比較快了解.
      2.類似的產品很多詳細我也不清楚,建議您可以問問看你買得經銷商或製造商看看,或許每家設計上有所不同,另一個方式你用PC去抓看看是否也是這樣結果,如果是的話你就改程式去配合囉!!

      刪除
  62. 紋子版主我想請問一下
    像應用2:車載資通訊運用這邊
    他可以不斷的接收時速的數值
    然後TEXTVIEW一直不斷更新
    這樣怎麼樣實現??
    能否幫我指點一下謝謝您

    回覆刪除
  63. 您好在請問一下
    我在264~277行程式內寫入Thread.sleep()了
    可是他會一直傳送資料像這樣↓
    100
    190
    200
    ...
    一直顯示然後就把畫面一直擠下去
    我想知道要怎樣才可以不要一直累積下去
    讓他傳送一筆新的數據就把舊的數據蓋過去
    謝謝您的熱心回答 感恩

    回覆刪除
    回覆
    1. 270行的+"\n"拿掉試試看!!

      刪除
    2. 這樣就變成傳送資料她會
      100 200 300 400...
      舊的資料似乎不會被刷新@@

      刪除
    3. 270行的+"\n"改成+"\r"試試是不是你要的功能。

      刪除
    4. 換成+"\r"就沒有顯示數據了!@@
      我是用CC2420+MSP430傳送資料,然後連接藍芽模組由藍芽模組發送
      再用手機接收我的資料。(程式部分有傳到電腦去試過是OK的)
      另外我想請問一下關於sleep
      我是寫在266行前面寫Thread.sleep(820);這樣可以嗎?
      謝謝版主耐心指教與回答>_< 真的很感恩!!!!

      刪除
    5. \r 與\n 是Java的字元控制,詳見下列網址上半部說明:
      http://goo.gl/KFRL6

      1.sleep有動作就可以了。
      2."\r"改成放在前面試試看
      msg = "\r" + new String(data, 0, length, "ASCII");

      刪除
    6. to 蚊子
      "\n"好像比較符合我的結果欸
      不過還是一樣的問題舊的數據會一直堆在前面
      新的數據就一子堆下去堆到整個螢幕都是滿滿的數據@@
      我想要的結果是新數據能夠直接蓋過舊數據不要留下之前傳送的數據
      謝謝版主的回答 感謝

      刪除
  64. to 蚊子版主
    請問一下像文章下方的測試影片""測試步驟 : 搜尋藍牙 --> 藍牙連接 --> DS1821溫度變化測試(8051) --> 8051 GPIO測試(LED亮滅)""
    像這部影片中,作者把手按住溫度感測讓溫度上升
    手機螢幕上就可以從20→21→22→...一直刷新
    要怎樣才能達到這種目的呢?
    我的疑問是要怎樣才能讓數字可以在同一個TEXTVIEW一直刷新而不留下舊的數字
    因為我做到現在雖然可以接收,但是就是沒辦法做到像上面的影片那樣
    拜託您解答了 感激不盡!!

    回覆刪除
    回覆
    1. 溫度的部分手機送訊息問-->8051回溫度-->Android TextView顯示-->手機"再"送訊息問-->8051回溫度-->Android TextView清除,顯示-->Loop

      只用了很單純的Text View而已,沒有很複雜的程式碼^__^

      刪除
    2. to 蚊子版主
      恩恩!!
      我後來發現要把283行的msgText.append(msg)改成msgText.setText
      這樣才會持續刷新而且不顯示出舊的數據!!
      謝謝版主這幾天耐心回答

      刪除
  65. 作者已經移除這則留言。

    回覆刪除
  66. 作者已經移除這則留言。

    回覆刪除
  67. 想請教一下,那個8051+藍牙的畫面,是用甚麼方法將8051上溫度顯示傳到手機上的?純粹是Android程式?還是要Android NDK?

    回覆刪除
    回覆
    1. 溫度的部分手機送訊息問-->8051回溫度-->Android TextView顯示-->手機"再"送訊息問-->8051回溫度-->Android TextView清除,顯示-->Loop

      刪除
    2. 可否透露一下,8051那段C是如何將資料傳到藍牙?讓Android可以去讀取藍牙的資料並顯示在手機上

      刪除
    3. 因為目前想要做一個透過藍牙控制MCU播放MP3功能的專案,但是不是很熟悉MCU的運作,才想問一下板主有沒有相關的經驗.

      刪除
    4. 8051那段C是如何將資料傳到藍牙,你搜尋一下8051 uart 或 8051 rs-232很多資料!

      刪除
    5. Sorry! MCU撥放MP3我並沒有做過......^^

      刪除
  68. 不好意思 我有兩個問題
    在 LINE 50 中 的msg 寫著The value of the field MainActivity.msg is not used 會有問題嗎
    另外我在 btHandler.sendEmptyMessage(0); 中的btHandler 寫著 btHandler cannot be resolved 但是其他都是正常的~如何辦??

    回覆刪除
  69. 你好:
    若我從藍芽端傳送資料到手機端時是字串,Ex:BT1051
    但是在textview的畫面是可以顯示正常字串,當我針對字串
    進行判斷,但是所有的判斷都失靈
    就是if(msg=="BT1051"){To do someting}else{Not to do something}
    這串沒作用?

    回覆刪除
  70. 老師您好:
    我的程式會停止在stBocket.connect(); 並顯示連接埠異常,但是stBocket有值...
    所以我有點困惑,以上的同學遇到的問題我看完後沒有太大的感想。

    回覆刪除
  71. 您好,我最近在研究有關藍芽裝置傳輸的程式,我只做到能讓app顯示"藍芽開".'藍芽關"."列出最近配對過的裝置"和"尋找裝置"這四樣功能,但是我不知道要如何把資料"傳送給別的裝置",參考過您的程式碼後,雖然釐清了很多概念,但是仍舊試不出來,想像您請教一下

    回覆刪除
  72. 老師您好
    最近我在研究有關藍芽裝置的傳輸,我只做到了讓程式有"打開藍芽""關閉藍芽""列出之前配對過的裝置"及"尋找裝置"四項功能,但一直無法做出傳輸資料,看完您的程式碼後,雖釐清了很多概念,但仍然做不出來TAT,所以想請教您

    回覆刪除
  73. 我在搜尋裝置的時候發生停止運行,請問該如何解決

    回覆刪除
  74. 老師你好
    我最近要寫一個APP是要跟arduino的藍芽作互動的,APP包含接收資料跟傳送資料
    arduino的藍芽可能是HC-05之類的
    請問上面程式可以跟arduino的藍芽互動嗎?
    因為我看上面是用RS-232 所以上來發問

    回覆刪除
  75. 老師你好
    我在接收訊息時
    從arduino收到的資料是斷斷續續的
    我是傳送距離值
    假設現在是200
    他是會斷開不完整的
    我該怎麼改接收部分

    回覆刪除
    回覆
    1. 您必須設計通訊協定才能收到完整封包。

      刪除
    2. 敏哥你好
      資料斷斷續續這部分我已經改成功了
      不過現在遇到一個問題不知道敏哥是否可以幫解惑

      在選擇完藍牙裝置後按開始連線時
      APP會無回應退出
      第二次之後就不會了這是?
      錯誤提示是血在159行

      刪除
  76. 你好
    我出現了這個錯誤提示
    我不太小得是哪個部分的問題
    上面寫NullPointerException
    但我對過並沒有Null的情況
    11-03 20:11:59.490 18384-18384/com.example.ryan.bt E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.ryan.bt, PID: 18384
    java.lang.NullPointerException
    at com.example.ryan.bt.MainActivity$3.onClick(MainActivity.java:165)
    at android.view.View.performClick(View.java:4487)
    at android.view.View$PerformClick.run(View.java:18737)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5230)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
    at dalvik.system.NativeStart.main(Native Method)

    回覆刪除
  77. 檢查一下這一行,應該是物件不存在

    回覆刪除
    回覆
    1. 165行是
      btServerSocket.close();
      這個會有物件不存在的問題嗎
      這個不是做關閉的動作嗎

      刪除