zoukankan      html  css  js  c++  java
  • Android蓝牙串口通信模板

    转载请注明出处,谢谢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里面加以下两个蓝牙操作权限哦~)

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

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

    private BluetoothAdapter mBluetoothAdapter = null;    
        
    private BluetoothSocket btSocket = null;    
        
    private OutputStream outStream = null;    
        
    private InputStream inStream = null;    
        
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  //这条是蓝牙串口通用的UUID,不要更改    
        
    private static String address = "00:12:02:22:06:61"; // <==要连接的蓝牙设备MAC地址    
        
        
    /*获得通信线路过程*/    
        
        
    /*1:获取本地BlueToothAdapter*/    
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    
    if(mBluetoothAdapter == null)     
    {    
        Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();    
        finish();    
        return;    
    }    
    if(!mBluetoothAdapter.isEnabled())     
    {    
        Toast.makeText(this, "Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();    
        finish();    
        return;    
    }     
         
    /*2:获取远程BlueToothDevice*/     
        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);    
    if(mBluetoothAdapter == null)     
    {    
        Toast.makeText(this, "Can't get remote device.", Toast.LENGTH_LONG).show();    
        finish();    
        return;    
    }    
         
    /*3:获得Socket*/          
        try {    
        btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);    
    } catch (IOException e) {    
        
        Log.e(TAG, "ON RESUME: Socket creation failed.", e);    
        
    }    
        
    /*4:取消discovered节省资源*/    
    mBluetoothAdapter.cancelDiscovery();            
        
        
    /*5:连接*/    
        
    try {    
        
        btSocket.connect();    
        
        Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");    
        
    } catch (IOException e) {    
        
        try {    
            btSocket.close();    
        
        } catch (IOException e2) {    
        
            Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);    
        }    
    }     
            
    /*此时可以通信了,放在任意函数中*/    
    /*  try {  
    outStream = btSocket.getOutputStream();  
     
    inStream = btSocket.getInputStream(); //可在TextView里显示  
     
    } catch (IOException e) {  
        Log.e(TAG, "ON RESUME: Output stream creation failed.", e);  
    }  
      
      
    String message = "1";  
      
    byte[] msgBuffer = message.getBytes();  
      
    try {  
        outStream.write(msgBuffer);  
      
    } catch (IOException e) {  
        Log.e(TAG, "ON RESUME: Exception during write.", e);  
    }  
    */     

    通用搜索模式代码模板:

    简洁简洁方式1 demo

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

    直接上码咯~

    package com.example.seed2;
    
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.app.Dialog;
    import android.os.Bundle;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.UUID;
    
    
    
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothSocket;
    import android.content.DialogInterface;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.widget.Toast;
    
    
    
    public class MetalSeed extends Activity {
        
        private static final String TAG = "BluetoothTest";
        
    
        private BluetoothAdapter mBluetoothAdapter = null;
    
        private BluetoothSocket btSocket = null;
    
        private OutputStream outStream = null;
        
        private InputStream inStream = null;
        
        private VerticalSeekBar vskb = null;
    
    
        private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  //这条是蓝牙串口通用的UUID,不要更改
    
    
        private static String address = "00:12:02:22:06:61"; // <==要连接的蓝牙设备MAC地址
    
    
        
        /** Called when the activity is first created. */
    
        @Override
    
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            this.vskb = (VerticalSeekBar)super.findViewById(R.id.mskb);
            this.vskb.setOnSeekBarChangeListener(new OnSeekBarChangeListenerX());
    
            
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if(mBluetoothAdapter == null) 
            {
                Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();
                finish();
                return;
            }
    
    
            if(!mBluetoothAdapter.isEnabled()) 
            {
                Toast.makeText(this, "Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();
                finish();
                return;
    
            }
    
    
        }
    
    
        private class OnSeekBarChangeListenerX implements VerticalSeekBar.OnSeekBarChangeListener {
    
            public void onProgressChanged(VerticalSeekBar seekBar, int progress, boolean fromUser) {
                //Main.this.clue.setText(seekBar.getProgress());
            /*    String message;
                byte [] msgBuffer;
                try {
                    outStream = btSocket.getOutputStream();
                } catch (IOException e) {
                    Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);
                }
                message =Integer.toString( seekBar.getProgress() );
                msgBuffer = message.getBytes();
                try{
                    outStream.write(msgBuffer);
                } catch (IOException e) {
                    Log.e (TAG, "ON RESUME : Exception during write.", e);
                }       */                
           } 
            
         
            public void onStartTrackingTouch(VerticalSeekBar seekBar) {
                String message;
                byte [] msgBuffer;
                try {
                    outStream = btSocket.getOutputStream();
                } catch (IOException e) {
                    Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);
                }
                message =Integer.toString( seekBar.getProgress() );
                msgBuffer = message.getBytes();
                try{
                    outStream.write(msgBuffer);
                } catch (IOException e) {
                    Log.e (TAG, "ON RESUME : Exception during write.", e);
                }         
            }
    
            public void onStopTrackingTouch(VerticalSeekBar seekBar) {
                String message;
                byte [] msgBuffer;
                try {
                    outStream = btSocket.getOutputStream();
                } catch (IOException e) {
                    Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);
                }
                message =Integer.toString( seekBar.getProgress() );
                msgBuffer = message.getBytes();
                try{
                    outStream.write(msgBuffer);
                } catch (IOException e) {
                    Log.e (TAG, "ON RESUME : Exception during write.", e);
                }         
            }
        }    
        
        
        @Override
        public void onStart() 
        {
    
            super.onStart();
    
        }
    
    
        @Override
        public void onResume() 
        {
    
            super.onResume();
    
            BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    
            try {
    
                btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
    
            } catch (IOException e) {
    
                Log.e(TAG, "ON RESUME: Socket creation failed.", e);
    
            }
            mBluetoothAdapter.cancelDiscovery();
            try {
    
                btSocket.connect();
    
                Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");
    
            } catch (IOException e) {
    
                try {
                    btSocket.close();
    
                } catch (IOException e2) {
    
                    Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
                }
    
            }
    
    
            // Create a data stream so we can talk to server.
    
        /*     try {
            outStream = btSocket.getOutputStream();
    
            inStream = btSocket.getInputStream();
            
            } catch (IOException e) {
                Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
            }
    
    
            String message = "read";
    
            byte[] msgBuffer = message.getBytes();
    
            try {
                outStream.write(msgBuffer);
    
            } catch (IOException e) {
                Log.e(TAG, "ON RESUME: Exception during write.", e);
            }
            int ret  = -1;
    
            while( ret != -1)
            {
                        try {
            
                         ret = inStream.read();
                 
                         } catch (IOException e) 
                             {
                                 e.printStackTrace();
                             }
            }
            
        */
    
        }
    
    
        @Override
    
        public void onPause() 
        {
    
            super.onPause();
    
            if (outStream != null)
            {
                try {
                    outStream.flush();
                } catch (IOException e) {
                    Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
                }
    
            }
    
    
            try {
                btSocket.close();
            } catch (IOException e2) {
                Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
            }
    
        }
    
    
        @Override
    
        public void onStop()
        {
    
            super.onStop();
    
        }
    
    
        @Override
    
        public void onDestroy() 
        {
    
            super.onDestroy();
    
        }
    
           @Override
            public boolean onKeyDown(int keyCode, KeyEvent event){
               if(keyCode == KeyEvent.KEYCODE_BACK){
                   this.exitDialog();
               }
               return false;
           }
            private void exitDialog(){
               Dialog dialog = new AlertDialog.Builder(MetalSeed.this)
                       .setTitle("退出程序?")
                       .setMessage("您确定要退出本程序吗?")
                       .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                MetalSeed.this.finish();                        
                            }
                        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {                    
                            public void onClick(DialogInterface dialog, int whichButton) { }
                        }).create();
               dialog.show();
           }
            
    }

    此为上述demo的layout

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/bcf" >
    
        <TextView
            android:id="@+id/myt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="48dp"
            android:text="MetalSeed"
            android:textSize="40dip" />
    
        <com.example.seed2.VerticalSeekBar
            android:id="@+id/mskb"
            android:layout_width="105dp"
            android:layout_height="219dp"
            android:layout_below="@+id/myt"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="85dp"
            android:maxHeight="95dip"
            android:minHeight="95dip"
            android:minWidth="95dip"
            android:thumbOffset="0dip" />
    
    </RelativeLayout>
  • 相关阅读:
    easyExcel入门
    UML-从需求到设计--迭代进化
    UML-操作契约总结
    102. Binary Tree Level Order Traversal
    98. Validate Binary Search Tree
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    94. Binary Tree Inorder Traversal
    84. Largest Rectangle in Histogram
    92. Reverse Linked List II
  • 原文地址:https://www.cnblogs.com/dennytao/p/5351879.html
Copyright © 2011-2022 走看看