注意:我的这个工程的目的主要是为了连接单片机的HC-06蓝牙模块
参考资料:

1 消息传递

我打算把讲解分成这三个部分,这三个部分是相对独立的,你最好一块一块学,我之前一口气学了之后,感觉非常难理解。这三个部分是:启动蓝牙功能、获取目标蓝牙设备的信息、与蓝牙设备建立连接。

在讲蓝牙之前,你需要先知道两个关于Android信息传递的重要知识点,这两个知识点在其他地方也是用的到的。

1.1 广播监听

Android广播事件,这个其实很好理解,你可以发送广播消息,你也可以接收广播消息。广播消息可能来自你自己,也可能来自系统。主要用于监听某些事件的变化,假设该事件为actionA,当actionA发生变化的时候,你可以利用广播监听进入对应的函数当中,执行你的命令。
这部分知识不难,网上教程很多,我就不自己写了。
你需要学会如下内容:
如何写广播监听函数?如何注册广播监听函数? 如何发送广播?

1.2 Handler、Message、Looper

这三个比较麻烦需要花时间消化一下
Android的消息机制(一)Android的消息机制(二) 你要知道以下内容:
如何在主线程中创建一个Handler类的实例,来实现信息接收的功能?
如何在其他地方用Message类包装数据,用主线程的handler实例来向主线程发送信息?

如何在子线程中利用Looper和Handler创建一个子线程的信息接收器?

这个网上也有很多教程,不过我还是再说几句。
假设消息传递者 A 打算传递消息给 B,分为两种情况:B 是主线程,或 B 是子线程。为什么区分这两种情况。原因在于,利用Handle转递消息时会进入由循环程序中,该循环程序是在Looper 中实现的,而每个线程只能有一个Looper。主线程默认是有一个 Looper 的,子线程的Looper需要自己创建。 在该循环程序中,会持续判断是否有消息传过来,有就处理,没有就继续循环。消息处理的机制是由MessageQueue实现的,它的本质是队列,就是先到的消息先处理,后到的消息后处理。

1.2.1 消息接收者 B 如果是主线程

由于默认有一个Looper,所以直接创建一个 Handler 类的成员就好了

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //消息传递是由Message类进行封装的。
        switch (msg.what)
        {
            //写入判断+处理程序
        }
    }
};
1.2.2 消息接收者 B 如果是主线程

至于为什么下列语句就可以使得 mHandler 与该线程的 Looper 绑定,大家可以去网上查查,是由静态实现的。

//在子线程中
void run(){
	Looper.prepare();                            //创建一个Looper
	mHandler= new Handler() {                    //通过该语句处理消息
	    public void handleMessage(Message msg) {
	        int what = msg.what;
	        Object obj = msg.obj;
	        switch (what) {
	            //此处写入对应的消息处理程序
	        }
	    }
	};
	Looper.loop();                                //打开消息泵
}
1.2.3 发送消息
//用Message类进行封装
Message msg = new Message();
msg.what = 1;//该参数指定消息类型
msg.arg1 = 1;//该参数看你的需求
msg.arg2 = 1;//该参数看你的需求
msg.obj = "这里可以存储任意类型的数据,不过接收后,记得强转";//这里存放消息
handler.sendMessage(msg);//发送消息
//注意,handler必须是目标的handler,你可以使得主线程创建的handler传进这里来

2 启动蓝牙

先讲讲最简单的部分,启动蓝牙。

2.1 蓝牙权限

在 AndroidManifest.xml 文件中添加权限
在 manifest 属性中,application 属性上面添加下面内容

<uses-permission android:name="android.permission.BLUETOOTH" />
<!--允许启动蓝牙功能-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!--允许程序进行发现和配对新的蓝牙设备-->

2.2 启动蓝牙功能

我现在只要实现使手机启动蓝牙这个功能。
1)获取蓝牙适配器,后面要用到

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

2)尝试开启蓝牙功能

Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivity(enableBtIntent);
//我这里是另外写了一个类,所以需要传入主类的 Context 类实例
//如果是在主类中写,只需要写 startActivity(enableBtIntent);

3)广播监听蓝牙开启状态
其实由2)就可以实现开启蓝牙的功能了,但是如果你想检测蓝牙什么时候开启,然后再自动运行指定程序的话,就需要利用广播监听。
先建立广播监听的接收类

private class BluetoothStateBroadcastReceive extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();//取出动作的字符串
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            switch (action) {//判断来自哪一个动作
            	//动作来自蓝牙功能变化
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);//检测当前蓝牙状态
                    if (blueState == BluetoothAdapter.STATE_ON) {
                        try {
                            //蓝牙已经启动,可以注销该广播监听了
                           context.unregisterReceiver(bluetoothStateBroadcastReceive);
                        } catch (Exception e) {
                            Log.d("蓝牙状态", "注销监听失败,监听实例不存在");
                        }
                    }
                    //这里可以执行下一步
                    
            }
        }
    }

4)注册广播监听函数

//创建监听函数的实例,该变量最后是类中的成员变量,因为注销的时候需要用该实例
BluetoothStateBroadcastReceive bluetoothStateBroadcastReceive = new BluetoothStateBroadcastReceive();
//指定监听动作
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);      
//绑定监听动作和监听接收的函数
context.registerReceiver(bluetoothStateBroadcastReceive,filter);

最后附上启动蓝牙部分的完整代码

public class BlueToothTool {
	//建立成员变量
	//来自布局的信息
    BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
    Context context;
    Handler handlerToMain;

	//构造函数
	private BlueToothTool(){
		super();
	}

	public BlueToothTool(BluetoothAdapter mBluetoothAdapter, Context context, Handler handler){
		this.mBluetoothAdapter = mBluetoothAdapter;
		this.context = context;
		this.handlerToMain = handler;
		//打开蓝牙功能
		BlueToothFuctionStart();
    }

	/**
     * 1.尝试打开蓝牙功能
     */
    private void BlueToothFuctionStart(){
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if(mBluetoothAdapter!=null){
            //检测是否开启了蓝牙功能,注意startActivity会开启子线程,无法在此语句后面直接判断蓝牙功能是否被开启
            if(!mBluetoothAdapter.isEnabled()) {
                //尝试开启蓝牙功能
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                context.startActivity(enableBtIntent);
                //注册对蓝牙状态功能的监听事件
                //实例化IntentFilter对象
                IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);      //可以用构造方法添加Action
                context.registerReceiver(bluetoothStateBroadcastReceive,filter);
            }else{
                //直接执行下一步
                //获取过去配对过的信息
                //2.1查找已配对的设备
            }
        }else{
            Toast.makeText(context,"您的设备不支持蓝牙系统",Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 1.1通过广播对蓝牙状态进行监听
     */
     private BluetoothStateBroadcastReceive bluetoothStateBroadcastReceive = new BluetoothStateBroadcastReceive();
    private class BluetoothStateBroadcastReceive extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            switch (action) {
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                    if (blueState == BluetoothAdapter.STATE_ON) {
                        try {
                            //注销对象
                            context.unregisterReceiver(bluetoothStateBroadcastReceive);
                        } catch (Exception e) {
                            Log.d("蓝牙状态", "注销监听失败,监听对象不存在");
                        }
                    }
                    //执行下一步
                    //获取过去配对过的信息
                    //2.1查找已配对的设备
            }
        }
    }
}