• 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>
  • 相关阅读:
    Jquery第一篇【介绍Jquery、回顾JavaScript代码、JS对象与JQ对象的区别】
    将数据转成JSON
    AJAX多级下拉联动【JSON】
    AJAX验证码检查
    生成验证码JSP【复用代码】
    AJAX二级下拉联动【XML方式】
    JavaScript总体的介绍【JavaScript介绍、定义函数方式、对象类型、变量类型】
    企业人事管理系统
    java.lang.IllegalArgumentException: node to traverse cannot be null!
    复用代码【SSH配置文件】
  • 原文地址:https://www.cnblogs.com/dennytao/p/5351879.html
Copyright © 2020-2023  润新知