通过蓝牙模块与单片机通讯

来源:互联网 发布:linux显示行号命令 编辑:程序博客网 时间:2024/05/05 21:48
·简介:由于业务关系,需要开发一个向单片机发送数据的应用,不过由于需求很简单,只  需要发送数据即可,所以该dome的功能只有发送数据功能,并没有对输入的数据  做进一步的处理

这里有蓝牙开发的基本资料,建议蓝牙基础欠缺的可以先悉知一下:http://pan.baidu.com/s/1ntrHntB

这里是我的dome工程目录





布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">    <TextView        android:id="@+id/textView1"        android:text="@string/hello_world"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/textView2"        android:layout_below="@id/textView1"        android:text="@string/hello_world"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/textView3"        android:layout_below="@id/textView2"        android:text="@string/hello_world"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <SeekBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/seekBar1"        android:layout_below="@+id/textView2"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_marginTop="108dp" />    <SeekBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/seekBar2"        android:layout_centerVertical="true"        android:layout_alignParentRight="true"        android:layout_alignParentEnd="true" /></RelativeLayout>

总的来说,通讯过程是:
1、得到本地蓝牙设备,
 void initOpenBluetooth() {        //取得本地蓝牙设备        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();        if (mBluetoothAdapter == null) {            Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_SHORT).show();            finish();            return;        }        //如果蓝牙没打开,提醒用户打开蓝牙        if (!mBluetoothAdapter.isEnabled()) {            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);            startActivityForResult(intent, REQUEST_ENABLE_BT);        }else {            if(mBluetoothAdapter.isEnabled()){                initGetDevice();            }        }    }

2、得到远程设备,
private void initGetDevice(){        //获取远程BlueToothDevice        device = mBluetoothAdapter.getRemoteDevice(address);        textView3.setText(device.getAddress() + ":" + device.getName());        if (mChatService == null) {            mChatService = new BluetoothChatService(this);            if (D) Log.v(TAG, "当前蓝牙状态:" + mChatService.getState());            mChatService.connect(device);//启动了蓝牙连接线程,            if (D) Log.v(TAG, "当前蓝牙状态:" + mChatService.getState());        }    }

3、找到已配对的设备,连接,连接需要唯一的通讯信道UUID
 /*********************    连接线程   ****************/    private class ConnectThread extends Thread {        private final BluetoothSocket mmSocket;        private final BluetoothDevice mmDevice;        public ConnectThread(BluetoothDevice device) {            mmDevice = device;            BluetoothSocket tmp = null;            // Get a BluetoothSocket for a connection with the            // given BluetoothDevice            try {                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);            } catch (IOException e) {                Log.e(TAG, "create() failed", e);            }            mmSocket = tmp;        }        public void run() {            Log.i(TAG, "BEGIN mConnectThread");            setName("ConnectThread");            // Always cancel discovery because it will slow down a connection            mAdapter.cancelDiscovery();            // Make a connection to the BluetoothSocket            try {                // This is a blocking call and will only return on a                // successful connection or an exception                mmSocket.connect();            } catch (IOException e) {                connectionFailed();                // Close the socket                try {                    mmSocket.close();                } catch (IOException e2) {                    Log.e(TAG, "unable to close() socket during connection failure", e2);                }                /*// Start the service over to restart listening mode                BluetoothChatService.this.start();*/                return;            }            // Reset the ConnectThread because we're done            synchronized (BluetoothChatService.this) {                mConnectThread = null;            }            // Start the connected thread            connected(mmSocket, mmDevice);        }        public void cancel() {            try {                mmSocket.close();            } catch (IOException e) {                Log.e(TAG, "close() of connect socket failed", e);            }        }    }

3、连接后的连接管理,通讯
 /*********************   连接管理,通讯线程   **********************/    private class ConnectedThread extends Thread {        private final BluetoothSocket mmSocket;        private final InputStream mmInStream;        private final OutputStream mmOutStream;        public ConnectedThread(BluetoothSocket socket) {            Log.d(TAG, "create ConnectedThread");            mmSocket = socket;            InputStream tmpIn = null;            OutputStream tmpOut = null;            // Get the BluetoothSocket input and output streams            try {                tmpIn = socket.getInputStream();                tmpOut = socket.getOutputStream();            } catch (IOException e) {                Log.e(TAG, "temp sockets not created", e);            }            mmInStream = tmpIn;            mmOutStream = tmpOut;        }        public void run() {            Log.i(TAG, "BEGIN mConnectedThread");            byte[] buffer = new byte[1024];            int bytes;            // Keep listening to the InputStream while connected            while (true) {                try {                    // Read from the InputStream                    bytes = mmInStream.read(buffer);                } catch (IOException e) {                    Log.e(TAG, "disconnected", e);                    connectionLost();                    break;                }            }        }        /**         * Write to the connected OutStream.         * @param buffer  The bytes to write         */        public void write(byte[] buffer) {            try {                mmOutStream.write(buffer);            } catch (IOException e) {                Log.e(TAG, "Exception during write", e);            }        }        public void cancel() {            try {                mmSocket.close();            } catch (IOException e) {                Log.e(TAG, "close() of connect socket failed", e);            }        }    }

4、最后一步,修复一些小Bug,然后可以根据自己的业务需求来更改代码。
     本来还有一个等待连接线程的,但该次业务无此需求,故不列出来了。

5:这里是整个dome的代码:
MainActivity:
public class MainActivity extends ActionBarActivity implements SeekBar.OnSeekBarChangeListener {    // Debugging    private static final String TAG = "MainActivity";    private static final boolean D = true;    //定义打开蓝牙的请求码    private static final int REQUEST_ENABLE_BT = 2;    // 本地蓝牙设备    private BluetoothAdapter mBluetoothAdapter = null;    // Member object for the chat services    private BluetoothChatService mChatService = null;    BluetoothDevice device;    private static String address = "30:14:11:12:38:01";    SeekBar seekBar1,seekBar2;    TextView textView1,textView2,textView3;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if(D) Log.v(TAG, "+++ ON CREATE +++");        System.out.println("+++ ON CREATE +++");        seekBar1 = (SeekBar) findViewById(R.id.seekBar1);        seekBar2 = (SeekBar) findViewById(R.id.seekBar2);        textView1 = (TextView) findViewById(R.id.textView1);        textView2 = (TextView) findViewById(R.id.textView2);        textView3 = (TextView) findViewById(R.id.textView3);        //两种方式监听        seekBar1.setOnSeekBarChangeListener(this);        seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {            @Override            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                textView2.setText("当前值:" + progress);                //  发送数据                String msg = String.valueOf(progress);                if (mChatService.getState() == BluetoothChatService.STATE_CONNECTED) {                    mChatService.write(getHexBytes(msg));                }else {                    System.out.println("没有连接好");                }            }            @Override            public void onStartTrackingTouch(SeekBar seekBar) {            }            @Override            public void onStopTrackingTouch(SeekBar seekBar) {            }        });        initOpenBluetooth();    }    /***************  再按一次退出程序  ****************/    private long _doubleClickedTime = 0;    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            long clickedTime = System.currentTimeMillis();            if (clickedTime - _doubleClickedTime <= 2000) {                // 两次点击退出                finish();            } else {                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();                _doubleClickedTime = clickedTime;            }            return true;        }        return super.onKeyDown(keyCode, event);    }    /***********  退出后,把蓝牙的连接注销   ***********/    @Override    protected void onDestroy() {        super.onDestroy();        mChatService.stop();        finish();    }    /*************  当“打开蓝牙的dialog结束后,要回调的函数”    ************/    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode == REQUEST_ENABLE_BT){            initGetDevice();        }    }    /*******************  initOpenBluetooth    *********************/    void initOpenBluetooth() {        //取得本地蓝牙设备        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();        if (mBluetoothAdapter == null) {            Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_SHORT).show();            finish();            return;        }        //如果蓝牙没打开,提醒用户打开蓝牙        if (!mBluetoothAdapter.isEnabled()) {            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);            startActivityForResult(intent, REQUEST_ENABLE_BT);        }else {            if(mBluetoothAdapter.isEnabled()){                initGetDevice();            }        }    }    /********************  intDetDevice  **********************/    private void initGetDevice(){        //获取远程BlueToothDevice        device = mBluetoothAdapter.getRemoteDevice(address);        textView3.setText(device.getAddress() + ":" + device.getName());        if (mChatService == null) {            mChatService = new BluetoothChatService(this);            if (D) Log.v(TAG, "当前蓝牙状态:" + mChatService.getState());            mChatService.connect(device);//启动了蓝牙连接线程,            if (D) Log.v(TAG, "当前蓝牙状态:" + mChatService.getState());        }    }    /******************** 字符串转换为16进制  **********************/    private byte[] getHexBytes(String message) {        int len = message.length() / 2;        char[] chars = message.toCharArray();        String[] hexStr = new String[len];        byte[] bytes = new byte[len];        for (int i = 0, j = 0; j < len; i += 2, j++) {            hexStr[j] = "" + chars[i] + chars[i + 1];            bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);        }        return bytes;    }    /********************************  拖动发送数据   ********************************/    @Override    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {        textView1.setText("当前值:" + progress);        //  发送数据        String msg = String.valueOf(progress);        if (mChatService.getState() == BluetoothChatService.STATE_CONNECTED) {            mChatService.write(getHexBytes(msg));        }else {            System.out.println("没有连接好");        }    }    @Override    public void onStartTrackingTouch(SeekBar seekBar) {    }    @Override    public void onStopTrackingTouch(SeekBar seekBar) {    }/******************************   标题栏  ************************************/    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }}

工具类:BluetoothChatService:
public class BluetoothChatService {    // Debugging    private static final String TAG = "BluetoothChatService";    private static final boolean D = true;    // Name for the SDP record when creating server socket    private static final String NAME = "BluetoothChat";    // Unique UUID for this application    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");    // Member fields    private final BluetoothAdapter mAdapter;    private AcceptThread mAcceptThread;    private ConnectThread mConnectThread;    private ConnectedThread mConnectedThread;    private int mState;    // Constants that indicate the current connection state    public static final int STATE_NONE = 0;       // we're doing nothing    public static final int STATE_LISTEN = 1;     // now listening for incoming connections    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection    public static final int STATE_CONNECTED = 3;  // now connected to a remote device    public BluetoothChatService(Context context) {        mAdapter = BluetoothAdapter.getDefaultAdapter();        mState = STATE_NONE;    }    private synchronized void setState(int state) {        if (D) Log.d(TAG, "setState() " + mState + " -> " + state);        mState = state;    }    public synchronized int getState() {        return mState;    }    /***************  本来还有个监听线程入口 和 监听线程。此应用没用到  ***********/    /**********************   启动连接线程  ************************/    public synchronized void connect(BluetoothDevice device) {        if (D) Log.d(TAG, "connect to: " + device);        // Cancel any thread attempting to make a connection      /*  if (mState == STATE_CONNECTING) {            if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}        }*/        if (mState == STATE_NONE) {            if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}        }        // Cancel any thread currently running a connection        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}        // Start the thread to connect with the given device        mConnectThread = new ConnectThread(device);        mConnectThread.start();        setState(STATE_CONNECTING);    }    /*******************  启动连接管理,通讯线程的入口 **************************/    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {        if (D) Log.d(TAG, "connected");        // Cancel the thread that completed the connection        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}        // Cancel any thread currently running a connection        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}        // Cancel the accept thread because we only want to connect to one device        if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}        // Start the thread to manage the connection and perform transmissions        mConnectedThread = new ConnectedThread(socket);        mConnectedThread.start();        setState(STATE_CONNECTED);    }    /******************   注销掉所有  *****************/    public synchronized void stop() {        if (D) Log.d(TAG, "stop");        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}        if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}        setState(STATE_NONE);    }    /***************  写出给通许线程,由线程来发送数据  ***********/    public void write(byte[] out) {        // Create temporary object        ConnectedThread r;        // Synchronize a copy of the ConnectedThread        synchronized (this) {            if (mState != STATE_CONNECTED) return;            r = mConnectedThread;        }        // Perform the write unsynchronized        r.write(out);    }    private void connectionFailed() {        setState(STATE_LISTEN);    }    private void connectionLost() {        setState(STATE_LISTEN);    }   /*********************  等待监听线程,此应用没用到  ****************/    private class AcceptThread extends Thread {        // The local server socket        private final BluetoothServerSocket mmServerSocket;        public AcceptThread() {            BluetoothServerSocket tmp = null;            // Create a new listening server socket            try {                tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);            } catch (IOException e) {                Log.e(TAG, "listen() failed", e);            }            mmServerSocket = tmp;        }        public void run() {            if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);            setName("AcceptThread");            BluetoothSocket socket = null;            // Listen to the server socket if we're not connected            while (mState != STATE_CONNECTED) {                try {                    // This is a blocking call and will only return on a                    // successful connection or an exception                    socket = mmServerSocket.accept();                } catch (IOException e) {                    Log.e(TAG, "accept() failed", e);                    break;                }                // If a connection was accepted                if (socket != null) {                    synchronized (BluetoothChatService.this) {                        switch (mState) {                            case STATE_LISTEN:                            case STATE_CONNECTING:                                // Situation normal. Start the connected thread.                                connected(socket, socket.getRemoteDevice());                                break;                            case STATE_NONE:                            case STATE_CONNECTED:                                // Either not ready or already connected. Terminate new socket.                                try {                                    socket.close();                                } catch (IOException e) {                                    Log.e(TAG, "Could not close unwanted socket", e);                                }                                break;                        }                    }                }            }            if (D) Log.i(TAG, "END mAcceptThread");        }        public void cancel() {            if (D) Log.d(TAG, "cancel " + this);            try {                mmServerSocket.close();            } catch (IOException e) {                Log.e(TAG, "close() of server failed", e);            }        }    }   /*********************    连接线程   ****************/    private class ConnectThread extends Thread {        private final BluetoothSocket mmSocket;        private final BluetoothDevice mmDevice;        public ConnectThread(BluetoothDevice device) {            mmDevice = device;            BluetoothSocket tmp = null;            // Get a BluetoothSocket for a connection with the            // given BluetoothDevice            try {                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);            } catch (IOException e) {                Log.e(TAG, "create() failed", e);            }            mmSocket = tmp;        }        public void run() {            Log.i(TAG, "BEGIN mConnectThread");            setName("ConnectThread");            // Always cancel discovery because it will slow down a connection            mAdapter.cancelDiscovery();            // Make a connection to the BluetoothSocket            try {                // This is a blocking call and will only return on a                // successful connection or an exception                mmSocket.connect();            } catch (IOException e) {                connectionFailed();                // Close the socket                try {                    mmSocket.close();                } catch (IOException e2) {                    Log.e(TAG, "unable to close() socket during connection failure", e2);                }                /*// Start the service over to restart listening mode                BluetoothChatService.this.start();*/                return;            }            // Reset the ConnectThread because we're done            synchronized (BluetoothChatService.this) {                mConnectThread = null;            }            // Start the connected thread            connected(mmSocket, mmDevice);        }        public void cancel() {            try {                mmSocket.close();            } catch (IOException e) {                Log.e(TAG, "close() of connect socket failed", e);            }        }    }  /*********************   连接管理,通讯线程   **********************/    private class ConnectedThread extends Thread {        private final BluetoothSocket mmSocket;        private final InputStream mmInStream;        private final OutputStream mmOutStream;        public ConnectedThread(BluetoothSocket socket) {            Log.d(TAG, "create ConnectedThread");            mmSocket = socket;            InputStream tmpIn = null;            OutputStream tmpOut = null;            // Get the BluetoothSocket input and output streams            try {                tmpIn = socket.getInputStream();                tmpOut = socket.getOutputStream();            } catch (IOException e) {                Log.e(TAG, "temp sockets not created", e);            }            mmInStream = tmpIn;            mmOutStream = tmpOut;        }        public void run() {            Log.i(TAG, "BEGIN mConnectedThread");            byte[] buffer = new byte[1024];            int bytes;            // Keep listening to the InputStream while connected            while (true) {                try {                    // Read from the InputStream                    bytes = mmInStream.read(buffer);                } catch (IOException e) {                    Log.e(TAG, "disconnected", e);                    connectionLost();                    break;                }            }        }        /**         * Write to the connected OutStream.         * @param buffer  The bytes to write         */        public void write(byte[] buffer) {            try {                mmOutStream.write(buffer);            } catch (IOException e) {                Log.e(TAG, "Exception during write", e);            }        }        public void cancel() {            try {                mmSocket.close();            } catch (IOException e) {                Log.e(TAG, "close() of connect socket failed", e);            }        }    }}


希望这边文章可以帮到阅读者

顺便一提:参考的出处的时候太久远了,忘了出处,在这里给他(他)说声:不好意思。。。


0 0
原创粉丝点击