android开发之手机与单片机蓝牙模块通讯

        我是参考原博客的内容去写的,因为原博客写的不全,少了关键的几个类,而后我就凭借本身扎实的功底补出来了,如今蓝牙工做正常,能发能收!在看这边文章以前你要先了解一下蓝牙的工做状态,个人代码里面可能解释的不是很详细,可是我本身是能看懂的!java

package com.example.fsl.bluetooth;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private Toolbar toolbar;
    private TextView status;
   private StringBuilder mstringbuilder;
    private static final UUID MY_UUID=UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//没有用到
    BluetoothReceiver receiver;
    BluetoothAdapter mBtAdapter;
    BluetoothSocket mBtSocket;
    private  BlueToothTool client;
    private ListView mListView;
    private List<String> ListDevice;
    private ArrayAdapter<String> mAdapter;
    private Button mbutton;
    private EditText editText;
    private ProgressBar progressBar;
    private LoopProgressBar loopProgressBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar=(Toolbar)findViewById(R.id.toolbar);
        status=(TextView)findViewById(R.id.textView2);
        mListView=(ListView)findViewById(R.id.listView);
        mbutton=(Button)findViewById(R.id.button);
        editText=(EditText)findViewById(R.id.editText);
        progressBar=(ProgressBar)findViewById(R.id.progressBar);
        progressBar.setVisibility(View.INVISIBLE);
        loopProgressBar=(LoopProgressBar)findViewById(R.id.loop);
        ListDevice=new ArrayList<String>();
        mstringbuilder=new StringBuilder();
        setSupportActionBar(toolbar);
        enablebluetooth();
        mbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               BlueToothTool.WriteTask W=client.new WriteTask(editText.getText().toString());
               W.start();
            }
        });
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                mBtAdapter.cancelDiscovery();//中止搜索
                progressBar.setVisibility(View.INVISIBLE);
                String str = ListDevice.get(position);
                String macAdress = str.split("\\|")[1];
                BluetoothDevice device = mBtAdapter.getRemoteDevice(macAdress);
                client=new BlueToothTool(device,handler);
                try{
                    client.connect();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     *开启蓝牙且被发现
     */
   private void enablebluetooth(){
        mBtAdapter=BluetoothAdapter.getDefaultAdapter();
       /*if(!mBtAdapter.isEnabled()){这里能够先使能,能够在REQUEST_DISCOVERABLE处使能,这样的话能够连使能和请求被发现一块完成
          // mBtAdapter.enable();
           Intent enableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
           startActivityForResult(enableIntent,REQUEST_ENABLE);
       }
       else {
           show("蓝牙已开启");
       }*/
           Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
           enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
           startActivityForResult(enable, REQUEST_DISCOVERABLE);
   }

    /**
     * 销毁事件,注销广播
     */
   @Override
   protected void onDestroy() {
       unregisterReceiver(receiver);
       super.onDestroy();
   }
    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BlueToothTool.CONNECT_FAILED:
                   show("链接失败");
                    try {
                        client.connect();
                    } catch (Exception e) {
                        Log.e("TAG", e.toString());
                    }
                    break;
                case BlueToothTool.CONNECT_SUCCESS:
                    show("链接成功");
                    mListView.setVisibility(View.INVISIBLE);
                    break;
                case BlueToothTool.READ_FAILED:
                    show("读取失败");
                    break;
                case BlueToothTool.WRITE_FAILED:
                   show("写入失败");
                    break;
                case BlueToothTool.DATA:
                    mstringbuilder.append(msg.obj.toString());
                   show(mstringbuilder.toString());
                    break;
            }
        }
    };
    /**
     * 请求响应结果
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       switch (requestCode){
          /* case REQUEST_ENABLE:
               if(requestCode!= Activity.RESULT_OK){
                 show("蓝牙未开启");
               }
               else
                   show("蓝牙已开启");
               break;*/
           case REQUEST_DISCOVERABLE:
               if(resultCode==Activity.RESULT_CANCELED){
                   show("蓝牙未开启");
               }
               else
                   show("蓝牙已开启");
                break;
               default:
                   break;
       }
    }
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.menu,menu);
        return true;
    }
   private static final int REQUEST_ENABLE=1;
    private static final int REQUEST_DISCOVERABLE=2;

    /**
     * 注册广播事件
     */
    @Override
    public void onResume(){
        super.onResume();
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        receiver = new BluetoothReceiver();
        registerReceiver(receiver, filter);
        filter=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(receiver,filter);
    }

    /**
     * 广播
     */
    private class BluetoothReceiver extends BroadcastReceiver {
         @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String str = device.getName() + "|" + device.getAddress();
                if (ListDevice.indexOf(str) == -1)// 防止重复添加
                    ListDevice.add(str); // 获取设备名称和mac地址
                if (mAdapter != null) {
                    mAdapter.notifyDataSetChanged();
                }
                showDevices();
            }
            else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                progressBar.setVisibility(View.INVISIBLE);
                show("已中止寻找");
            }

        }
    };
    /**
     * 菜单栏点击事件
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.search:
                if(!mBtAdapter.isEnabled()){
                    show("蓝牙未开启");
                }
                else {
                    mBtAdapter.startDiscovery();
                    show("正在寻找设备");
                    progressBar.setVisibility(View.VISIBLE);
                }
                break;
            case R.id.about:
                Toast.makeText(MainActivity.this,"关于咱们",Toast.LENGTH_SHORT).show();
                break;
                default:
        }
        return true;
    }
    private void showDevices() {
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
                ListDevice);
        mListView.setAdapter(mAdapter);
    }
    /**
     * 更新UI方法
     * @param string
     */
    private void show(final String string){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                status.setText(string);
            }
        });
    }
}
而后个人读任务和写任务以及链接任务是在另外一个类里面实现的,也就是BlueToothTool类,这个类一个原博客是没有写的,只是MainActivity中用到了这个类的一些方法,可是没有给出,因此就让一些同窗很蛋疼。我看完以后是本身补全的这个类!

package com.example.fsl.bluetooth;

import android.app.Notification;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;

import java.util.logging.LogRecord;

/**
 * Created by Fsl on 2017/12/22.
 */

public class BlueToothTool {
    private BluetoothDevice device;
    private Handler mhandler;
    BluetoothSocket socket;
    static final int CONNECT_FAILED=1;
    static final int CONNECT_SUCCESS=5;
    static final int READ_FAILED=2;
    static final int WRITE_FAILED=3;
    static final int DATA=4;
    private boolean isConnect=false;

    public BlueToothTool(BluetoothDevice device,Handler handler){
        this.device=device;
        this.mhandler=handler;
    }
   /**
   *开辟链接线程任务
   */
    public void connect(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                BluetoothSocket tmp = null;
                Method method;
                try {
                    method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
                    tmp = (BluetoothSocket) method.invoke(device, 1);
                } catch (Exception e) {
                    setState(CONNECT_FAILED);
                    Log.e("TAG", e.toString());
                }
                socket = tmp;
                try {
                    socket.connect();
                    isConnect = true;
                    setState(CONNECT_SUCCESS);
                    Readtask  readtask = new Readtask();  //链接成功后开启读取数据的线程
                    readtask.start();
                } catch (Exception e) {
                    setState(CONNECT_FAILED);
                    Log.e("TAG", e.toString());
                }
            }
            });
            new Thread(thread).start();
        }
		/**
		*开辟线程读任务
		*/
        public class Readtask extends Thread{
        @Override
            public void run(){
            byte[] buffer = new byte[1024];
            int bytes;
            InputStream inputStream ;   //创建输入流读取数据
            while (true) {
                try {
                     inputStream = socket.getInputStream();
                     if ((bytes = inputStream.read(buffer)) > 0) {
                         byte[] buf_data= new byte[bytes];
                         for (int i = 0; i < bytes; i++) {
                             buf_data[i] = buffer[i];
                         }
                         String s = new String(buf_data);
                          Message msg = mhandler.obtainMessage();
                          msg.what = DATA;
                          msg.obj = s;
                          mhandler.sendMessage(msg);
                     }
                } catch (IOException e) {
                    setState(READ_FAILED);
                    Log.e("TAG", e.toString());
                    break;
                }
            }

            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    Log.e("TAG", e.toString());
                }
            }
          }
        }
		/**
		*开辟线程写任务
		*/
        public  class WriteTask extends Thread{
            private String srt;
            public  WriteTask(String str){
            this.srt=str;
            }
            @Override
            public void run(){
              OutputStream outputStream=null;
              byte[] st=srt.getBytes();
              try{
                 outputStream=socket.getOutputStream();
                 outputStream.write(st);
                 }catch (Exception e){
                  setState(WRITE_FAILED);
                  e.printStackTrace();
              }
            }

        }

    
    private void setState(int mes){
         Message message=new Message();
         message.what=mes;
         mhandler.sendMessage(message);

    }
	/**
	*下面这个方法目前尚未用到
	*/
    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;
    }

}
        以上就是个人蓝牙与单片机链接通讯的全过程,顺便说一下,这个链接是自动链接的,不须要什么秘钥什么的,直接搜索到HC-05蓝牙直接就能够肯定链接,亲测有效。我这个程序本身写了两遍,第一遍的时候因为个人硬盘坏了,结果修了一个星期大费周折都没有修好,4年的东西全都没有了,固然也包括这个项目,在这里提醒一下你们,在工做的时候要有备份重要数据的习惯!!真他妈日了狗了!最终固然选择坦然面对啊,一切从头开始,硬盘坏以后,我那几天的感受就是——我两手空空,除了个人脑子,关于一切记忆都没有了,只剩下个人脑子了,20多年来的同窗照片,视频,家人照片,和女友的记忆,我作的课题与项目,全部的一切都没有了,只剩下个人脑子能回忆了!至关惨!

    最后我又把本身以前作到一半的项目凭借仅有的记忆从新写了一遍!很惨!android