Android蓝牙串口通信模板及demo,trick

来源:互联网 发布:淘宝申请企业店铺条件 编辑:程序博客网 时间:2024/04/28 07:29

转载请注明出处,谢谢http://blog.csdn.net/metalseed/article/details/7988945

Android蓝牙操作:与蓝牙串口模块通信,或其他蓝牙设备通信。


初涉android的蓝牙操作,按照固定MAC地址连接获取Device时,程序始终是异常终止,查了好多天代码都没查出原因。今天改了一下API版本,突然就成功连接了。总结之后发现果然是个坑爹之极的错误。

为了这种错误拼命查原因浪费大把时间是非常不值得的,但是问题不解决更是揪心。可惜我百度了那么多,都没有给出确切原因。今天特此mark,希望后来者遇到这个问题的时候能轻松解决。

下面是我的连接过程,中间崩溃原因及解决办法。

1:用AT指令获得蓝牙串口的MAC地址,地址是简写的,按照常理猜测可得标准格式。

2:开一个String adress= "************" //MAC地址, String MY_UUID= "************"//UUID根据通信而定,网上都有。

3:取得本地Adapter用getDefaultAdapter(); 远程的则用getRemoteDevice(adress); 之后便可用UUID开socket进行通信。

如果中途各种在getRemoteDevice处崩溃,大家可以查看一下当前的API版本,如果是2.1或以下版本的话,便能确定是API版本问题,只要换成2.2或者以上就都可以正常运行了~   这么坑爹的错误的确很为难初学者。  唉··········  为这种小trick浪费很多时间真是难过。

(另外有个重要地方,别忘了给manifest里面加以下两个蓝牙操作权限哦~)

[html] view plain copy
 print?
  1. <uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>  
  2. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>  

下面附上Android蓝牙操作中用固定MAC地址传输信息的模板,通用搜索模式日后再补删模板:

[java] view plain copy
 print?
  1. private BluetoothAdapter mBluetoothAdapter = null;      
  2.       
  3. private BluetoothSocket btSocket = null;      
  4.       
  5. private OutputStream outStream = null;      
  6.       
  7. private InputStream inStream = null;      
  8.       
  9. private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  //这条是蓝牙串口通用的UUID,不要更改      
  10.       
  11. private static String address = "00:12:02:22:06:61"// <==要连接的蓝牙设备MAC地址      
  12.       
  13.       
  14. /*获得通信线路过程*/      
  15.       
  16.       
  17. /*1:获取本地BlueToothAdapter*/      
  18. mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();      
  19. if(mBluetoothAdapter == null)       
  20. {      
  21.     Toast.makeText(this"Bluetooth is not available.", Toast.LENGTH_LONG).show();      
  22.     finish();      
  23.     return;      
  24. }      
  25. if(!mBluetoothAdapter.isEnabled())       
  26. {      
  27.     Toast.makeText(this"Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();      
  28.     finish();      
  29.     return;      
  30. }       
  31.        
  32. /*2:获取远程BlueToothDevice*/       
  33.     BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);      
  34. if(mBluetoothAdapter == null)       
  35. {      
  36.     Toast.makeText(this"Can't get remote device.", Toast.LENGTH_LONG).show();      
  37.     finish();      
  38.     return;      
  39. }      
  40.        
  41. /*3:获得Socket*/            
  42.     try {      
  43.     btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);      
  44. catch (IOException e) {      
  45.       
  46.     Log.e(TAG, "ON RESUME: Socket creation failed.", e);      
  47.       
  48. }      
  49.       
  50. /*4:取消discovered节省资源*/      
  51. mBluetoothAdapter.cancelDiscovery();              
  52.       
  53.       
  54. /*5:连接*/      
  55.       
  56. try {      
  57.       
  58.     btSocket.connect();      
  59.       
  60.     Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");      
  61.       
  62. catch (IOException e) {      
  63.       
  64.     try {      
  65.         btSocket.close();      
  66.       
  67.     } catch (IOException e2) {      
  68.       
  69.         Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);      
  70.     }      
  71. }       
  72.           
  73. /*此时可以通信了,放在任意函数中*/      
  74. /*  try {   
  75. outStream = btSocket.getOutputStream();   
  76.   
  77. inStream = btSocket.getInputStream(); //可在TextView里显示   
  78.   
  79. } catch (IOException e) {   
  80.     Log.e(TAG, "ON RESUME: Output stream creation failed.", e);   
  81. }   
  82.    
  83.    
  84. String message = "1";   
  85.    
  86. byte[] msgBuffer = message.getBytes();   
  87.    
  88. try {   
  89.     outStream.write(msgBuffer);   
  90.    
  91. } catch (IOException e) {   
  92.     Log.e(TAG, "ON RESUME: Exception during write.", e);   
  93. }   
  94. */       

通用搜索模式代码模板:






简洁简洁方式1 demo


作用: 用VerticalSeekBar控制一个 LED屏幕的亮暗。

直接上码咯~

[java] view plain copy
 print?
  1. package com.example.seed2;  
  2.   
  3.   
  4. import android.app.Activity;  
  5. import android.app.AlertDialog;  
  6. import android.app.Dialog;  
  7. import android.os.Bundle;  
  8. import java.io.IOException;  
  9. import java.io.InputStream;  
  10. import java.io.OutputStream;  
  11. import java.util.UUID;  
  12.   
  13.   
  14.   
  15. import android.bluetooth.BluetoothAdapter;  
  16. import android.bluetooth.BluetoothDevice;  
  17. import android.bluetooth.BluetoothSocket;  
  18. import android.content.DialogInterface;  
  19. import android.util.Log;  
  20. import android.view.KeyEvent;  
  21. import android.widget.Toast;  
  22.   
  23.   
  24.   
  25. public class MetalSeed extends Activity {  
  26.       
  27.     private static final String TAG = "BluetoothTest";  
  28.       
  29.   
  30.     private BluetoothAdapter mBluetoothAdapter = null;  
  31.   
  32.     private BluetoothSocket btSocket = null;  
  33.   
  34.     private OutputStream outStream = null;  
  35.       
  36.     private InputStream inStream = null;  
  37.       
  38.     private VerticalSeekBar vskb = null;  
  39.   
  40.   
  41.     private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  //这条是蓝牙串口通用的UUID,不要更改  
  42.   
  43.   
  44.     private static String address = "00:12:02:22:06:61"// <==要连接的蓝牙设备MAC地址  
  45.   
  46.   
  47.       
  48.     /** Called when the activity is first created. */  
  49.   
  50.     @Override  
  51.   
  52.     public void onCreate(Bundle savedInstanceState) {  
  53.   
  54.         super.onCreate(savedInstanceState);  
  55.         setContentView(R.layout.main);  
  56.   
  57.         this.vskb = (VerticalSeekBar)super.findViewById(R.id.mskb);  
  58.         this.vskb.setOnSeekBarChangeListener(new OnSeekBarChangeListenerX());  
  59.   
  60.           
  61.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
  62.         if(mBluetoothAdapter == null)   
  63.         {  
  64.             Toast.makeText(this"Bluetooth is not available.", Toast.LENGTH_LONG).show();  
  65.             finish();  
  66.             return;  
  67.         }  
  68.   
  69.   
  70.         if(!mBluetoothAdapter.isEnabled())   
  71.         {  
  72.             Toast.makeText(this"Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();  
  73.             finish();  
  74.             return;  
  75.   
  76.         }  
  77.   
  78.   
  79.     }  
  80.   
  81.   
  82.     private class OnSeekBarChangeListenerX implements VerticalSeekBar.OnSeekBarChangeListener {  
  83.   
  84.         public void onProgressChanged(VerticalSeekBar seekBar, int progress, boolean fromUser) {  
  85.             //Main.this.clue.setText(seekBar.getProgress());  
  86.         /*  String message; 
  87.             byte [] msgBuffer; 
  88.             try { 
  89.                 outStream = btSocket.getOutputStream(); 
  90.             } catch (IOException e) { 
  91.                 Log.e(TAG,"ON RESUME : Output Stream creation failed.", e); 
  92.             } 
  93.             message =Integer.toString( seekBar.getProgress() ); 
  94.             msgBuffer = message.getBytes(); 
  95.             try{ 
  96.                 outStream.write(msgBuffer); 
  97.             } catch (IOException e) { 
  98.                 Log.e (TAG, "ON RESUME : Exception during write.", e); 
  99.             }       */                
  100.     }   
  101.           
  102.        
  103.         public void onStartTrackingTouch(VerticalSeekBar seekBar) {  
  104.             String message;  
  105.             byte [] msgBuffer;  
  106.             try {  
  107.                 outStream = btSocket.getOutputStream();  
  108.             } catch (IOException e) {  
  109.                 Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);  
  110.             }  
  111.             message =Integer.toString( seekBar.getProgress() );  
  112.             msgBuffer = message.getBytes();  
  113.             try{  
  114.                 outStream.write(msgBuffer);  
  115.             } catch (IOException e) {  
  116.                 Log.e (TAG, "ON RESUME : Exception during write.", e);  
  117.             }           
  118.         }  
  119.   
  120.         public void onStopTrackingTouch(VerticalSeekBar seekBar) {  
  121.             String message;  
  122.             byte [] msgBuffer;  
  123.             try {  
  124.                 outStream = btSocket.getOutputStream();  
  125.             } catch (IOException e) {  
  126.                 Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);  
  127.             }  
  128.             message =Integer.toString( seekBar.getProgress() );  
  129.             msgBuffer = message.getBytes();  
  130.             try{  
  131.                 outStream.write(msgBuffer);  
  132.             } catch (IOException e) {  
  133.                 Log.e (TAG, "ON RESUME : Exception during write.", e);  
  134.             }           
  135.         }  
  136.     }      
  137.       
  138.       
  139.     @Override  
  140.     public void onStart()   
  141.     {  
  142.   
  143.         super.onStart();  
  144.   
  145.     }  
  146.   
  147.   
  148.     @Override  
  149.     public void onResume()   
  150.     {  
  151.   
  152.         super.onResume();  
  153.   
  154.         BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);  
  155.   
  156.         try {  
  157.   
  158.             btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);  
  159.   
  160.         } catch (IOException e) {  
  161.   
  162.             Log.e(TAG, "ON RESUME: Socket creation failed.", e);  
  163.   
  164.         }  
  165.         mBluetoothAdapter.cancelDiscovery();  
  166.         try {  
  167.   
  168.             btSocket.connect();  
  169.   
  170.             Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");  
  171.   
  172.         } catch (IOException e) {  
  173.   
  174.             try {  
  175.                 btSocket.close();  
  176.   
  177.             } catch (IOException e2) {  
  178.   
  179.                 Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);  
  180.             }  
  181.   
  182.         }  
  183.   
  184.   
  185.         // Create a data stream so we can talk to server.  
  186.   
  187.     /*  try { 
  188.         outStream = btSocket.getOutputStream(); 
  189.  
  190.         inStream = btSocket.getInputStream(); 
  191.          
  192.         } catch (IOException e) { 
  193.             Log.e(TAG, "ON RESUME: Output stream creation failed.", e); 
  194.         } 
  195.  
  196.  
  197.         String message = "read"; 
  198.  
  199.         byte[] msgBuffer = message.getBytes(); 
  200.  
  201.         try { 
  202.             outStream.write(msgBuffer); 
  203.  
  204.         } catch (IOException e) { 
  205.             Log.e(TAG, "ON RESUME: Exception during write.", e); 
  206.         } 
  207.         int ret  = -1; 
  208.  
  209.         while( ret != -1) 
  210.         { 
  211.                     try { 
  212.          
  213.                     ret = inStream.read(); 
  214.              
  215.                     } catch (IOException e)  
  216.                         { 
  217.                             e.printStackTrace(); 
  218.                         } 
  219.         } 
  220.          
  221.     */  
  222.   
  223.     }  
  224.   
  225.   
  226.     @Override  
  227.   
  228.     public void onPause()   
  229.     {  
  230.   
  231.         super.onPause();  
  232.   
  233.         if (outStream != null)  
  234.         {  
  235.             try {  
  236.                 outStream.flush();  
  237.             } catch (IOException e) {  
  238.                 Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);  
  239.             }  
  240.   
  241.         }  
  242.   
  243.   
  244.         try {  
  245.             btSocket.close();  
  246.         } catch (IOException e2) {  
  247.             Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);  
  248.         }  
  249.   
  250.     }  
  251.   
  252.   
  253.     @Override  
  254.   
  255.     public void onStop()  
  256.     {  
  257.   
  258.         super.onStop();  
  259.   
  260.     }  
  261.   
  262.   
  263.     @Override  
  264.   
  265.     public void onDestroy()   
  266.     {  
  267.   
  268.         super.onDestroy();  
  269.   
  270.     }  
  271.   
  272.        @Override  
  273.         public boolean onKeyDown(int keyCode, KeyEvent event){  
  274.         if(keyCode == KeyEvent.KEYCODE_BACK){  
  275.             this.exitDialog();  
  276.         }  
  277.         return false;  
  278.        }  
  279.         private void exitDialog(){  
  280.         Dialog dialog = new AlertDialog.Builder(MetalSeed.this)  
  281.                 .setTitle("退出程序?")  
  282.                 .setMessage("您确定要退出本程序吗?")  
  283.                 .setPositiveButton("确定"new DialogInterface.OnClickListener() {  
  284.                         public void onClick(DialogInterface dialog, int whichButton) {  
  285.                             MetalSeed.this.finish();                          
  286.                         }  
  287.                     }).setNegativeButton("取消"new DialogInterface.OnClickListener() {                    
  288.                         public void onClick(DialogInterface dialog, int whichButton) { }  
  289.                     }).create();  
  290.         dialog.show();  
  291.        }  
  292.           
  293. }  

此为上述demo的layout

[html] view plain copy
 print?
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="@drawable/bcf" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/myt"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_alignParentTop="true"  
  12.         android:layout_centerHorizontal="true"  
  13.         android:layout_marginTop="48dp"  
  14.         android:text="MetalSeed"  
  15.         android:textSize="40dip" />  
  16.   
  17.     <com.example.seed2.VerticalSeekBar  
  18.         android:id="@+id/mskb"  
  19.         android:layout_width="105dp"  
  20.         android:layout_height="219dp"  
  21.         android:layout_below="@+id/myt"  
  22.         android:layout_centerHorizontal="true"  
  23.         android:layout_marginTop="85dp"  
  24.         android:maxHeight="95dip"  
  25.         android:minHeight="95dip"  
  26.         android:minWidth="95dip"  
  27.         android:thumbOffset="0dip" />  
  28.   
  29. </RelativeLayout>  
0 0