zhuchengyi

1、添加蓝牙权限

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

 

2、获取本地蓝牙适配器

  通过本地蓝牙适配器可以做以下一系列操作

BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();

  

3、手机是否支持蓝牙

  蓝牙适配器不为空,则支持蓝牙

    /**
     * 是否支持蓝牙
     * @return
     */
    public boolean isSupportBlueTooth(){
        if(mAdapter != null){
            return true;
        }
        return false;
    }

 

4、蓝牙是否打开

    /**
     * 蓝牙是否打开
     * @return
     */
    public boolean getBlueToothStatus(){
        if(mAdapter != null){
            return mAdapter.isEnabled();
        }
        return false;
    }

 

5、蓝牙打开与关闭

  

    /**
     * 打开蓝牙
     * @param activity
     * @param requestCode 用于onActivityResult中判断
     */
    public void turnOnBlueTooth(Activity activity, int requestCode){
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        activity.startActivityForResult(intent, requestCode);
        // google不建议直接打开 mAdapter.enable();
    }

    /**
     * 关闭蓝牙
     */
    public void turnOffBlueTooth() {
        mAdapter.disable();
    }

 

6、处理返回状态

  蓝牙的打开关闭等状态通过广播和Activity返回

  

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 蓝牙状态广播
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            switch (state){
                case BluetoothAdapter.STATE_OFF:
                    showToast("broadcast-->蓝牙关闭");
                    break;

                case BluetoothAdapter.STATE_ON:
                    showToast("broadcast-->蓝牙打开");// 真机测试此处未执行,在Activity的回调中执行
                    break;

                case BluetoothAdapter.STATE_TURNING_ON:
                    showToast("broadcast-->蓝牙正在打开");
                    break;

                case BluetoothAdapter.STATE_TURNING_OFF:
                    showToast("broadcast-->蓝牙正在关闭");
                    break;

                default:
                    showToast("未知状态");
                    break;
            }
        }
    };

  

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            showToast("打开成功");
        }else{
            showToast("打开失败");
        }
    }

  

        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(receiver, filter);

 

7、其他功能

  以上是蓝牙最基础的判断,下面介绍连接、绑定等功能

  7.1设置可见

    通过Intent设置可见

    /**
     * 打开蓝牙可见
     * @param activity
     */
    public void enableVisibly(Activity activity){
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        // 蓝牙可见时间300秒
        intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        activity.startActivity(intent);
    }

    注册广播监听

  

// 这个蓝牙状态的监听,供参考
// IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
//设备扫描模式改变,可见监听
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);

    广播中处理

@Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
         // 是否可见监听 if( BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) { int scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,0); if( scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { showToast("可见"); } else { showToast("不可见"); } }

  

// 蓝牙状态广播
// int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);

  7.2扫描设备

            // 查找设备,点击绑定
            case R.id.find_device:
                mAdapter.refresh(mDeviceList);
                mController.findDevice();
                mListView.setOnItemClickListener(bindDeviceClick);
                break;

  

        //开始查找
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        //结束查找
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        //查找设备
        filter.addAction(BluetoothDevice.ACTION_FOUND);

  

            // 开始扫描
            if( BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action) ) {
                //初始化数据列表
                showToast("开始扫描");
                mDeviceList.clear();
                mAdapter.notifyDataSetChanged();
            }
            // 扫描完成
            if( BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                showToast("扫描完成");
            }
            // 发现设备
            if( BluetoothDevice.ACTION_FOUND.equals(action)) {
                showToast("发现设备");
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                //找到一个,添加一个
                mDeviceList.add(device);
                mAdapter.notifyDataSetChanged();
            }

  7.3绑定设备

    /**
     * 绑定设备
     */
    private AdapterView.OnItemClickListener bindDeviceClick = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            BluetoothDevice device = mDeviceList.get(position);
            // android 4.4才支持应用绑定蓝牙
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                device.createBond();
            }else{
                try {
                    createBond(device.getClass(), device);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };

  

    /**
     * 与设备配对 参考源码:platform/packages/apps/Settings.git
     * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
     */
    static public boolean createBond(Class btClass,BluetoothDevice btDevice) throws Exception {
        Method createBondMethod = btClass.getMethod("createBond");
        Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
        return returnValue.booleanValue();
    }

    /**
     * 与设备解除配对 参考源码:platform/packages/apps/Settings.git
     * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
     */
    static public boolean removeBond(Class btClass,BluetoothDevice btDevice) throws Exception {
        Method removeBondMethod = btClass.getMethod("removeBond");
        Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
        return returnValue.booleanValue();
    }

  

           // 绑定状态监听
            if( BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action) ) {
                BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if( remoteDevice == null ) {
                    showToast("没有设备");
                    return;
                }
                int status = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,0);
                if( status == BluetoothDevice.BOND_BONDED) {
                    showToast("已绑定 " + remoteDevice.getName());
                }
                else if( status == BluetoothDevice.BOND_BONDING){
                    showToast("绑定中 " + remoteDevice.getName());
                }
                else if(status == BluetoothDevice.BOND_NONE){
                    showToast("未绑定 " + remoteDevice.getName());
                }
            }
        }

  7.4连接设备

    /**
     * 连接设备
     */
    private AdapterView.OnItemClickListener bindedDeviceClick = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            BluetoothDevice device = mBondedDeviceList.get(i);
            ChatController.getInstance().startChatWith(device, mController.getAdapter(), mUIHandler);
        }
    };

  7.5三个线程

package com.example.bluetoothchat.connect;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;

import java.io.IOException;
import java.util.UUID;

/**
 * 服务端等待连接线程
 * Created by Administrator on 2015/7/3.
 */
public class AcceptThread extends Thread {

    private static final String NAME = "BlueTooth";
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    private final BluetoothAdapter mBluetoothAdapter;
    private final Handler mHandler;
    private final BluetoothServerSocket mServerSocket;
    private ConnectedThread mConnectedThread;

    /**
     * 服务端线程构造器,包括创建服务端的Socket
     * @param adapter
     * @param handler
     */
    public AcceptThread(BluetoothAdapter adapter, Handler handler) {
        mBluetoothAdapter = adapter;
        mHandler = handler;
        BluetoothServerSocket tmp = null;
        try {
            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mServerSocket = tmp;
    }


    @Override
    public void run() {
        // 直到发生异常前,一直监听客户端的连接
        BluetoothSocket socket = null;
        while(true){
            try {
                mHandler.sendEmptyMessage(Constant.MSG_START_LISTENING);
                socket = mServerSocket.accept();
            } catch (IOException e) {
                mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
                break;
            }

            // 有连接接收
            if(socket != null){
                manageConnectedSocket(socket);
                try {
                    mServerSocket.close();
                    mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }


    /**
     * 管理Socket连接,只支持一个连接
     * @param socket
     */
    private void manageConnectedSocket(BluetoothSocket socket){
        if(mConnectedThread != null){
            mConnectedThread.cancel();
        }
        mHandler.sendEmptyMessage(Constant.MSG_GOT_A_CLINET);
        mConnectedThread = new ConnectedThread(socket, mHandler);
        mConnectedThread.start();
    }


    /**
     * 关闭socket
     */
    public void cancel(){
        try {
            mServerSocket.close();
            mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 发生数据
     * @param data
     */
    public void sendData(byte[] data){
        if(mConnectedThread != null){
            mConnectedThread.write(data);
        }
    }

}

  

package com.example.bluetoothchat.connect;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;

import java.io.IOException;
import java.util.UUID;

/**
 * 客户端线程连接
 * Created by Administrator on 2015/7/3.
 */
public class ConnectThread extends Thread{

    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    private final BluetoothDevice mDevice;
    private final BluetoothAdapter mBluetoothAdapter;
    private final Handler mHandler;
    private final BluetoothSocket mSocket;
    private ConnectedThread mConnectedThread;

    public ConnectThread(BluetoothDevice device, BluetoothAdapter adapter, Handler handler){
        BluetoothSocket tmp = null;
        mDevice = device;
        mBluetoothAdapter = adapter;
        mHandler = handler;

        try {
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            e.printStackTrace();
        }

        mSocket = tmp;
    }


    @Override
    public void run() {
        // 连接后不再需要扫描了
        mBluetoothAdapter.cancelDiscovery();

        try {
            mSocket.connect();
        } catch (IOException e) {
            mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR));
            try {
                mSocket.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return;
        }

        // 管理Socket连接
        manageConnectedSocket(mSocket);
    }

    private void manageConnectedSocket(BluetoothSocket mSocket) {
        mHandler.sendEmptyMessage(Constant.MSG_CONNECTED_TO_SERVER);
        mConnectedThread = new ConnectedThread(mSocket, mHandler);
        mConnectedThread.start();
    }


    public void cancel(){
        try {
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    public void sendData(byte[] data){
        if(mConnectedThread != null){
            mConnectedThread.write(data);
        }
    }

}

  

package com.example.bluetoothchat.connect;

import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 连接线程
 * Created by Administrator on 2015/7/3.
 */
public class ConnectedThread extends Thread{


    private final BluetoothSocket mSocket;
    private final Handler mHandler;
    private final InputStream mInStream;
    private final OutputStream mOutStream;

    public ConnectedThread(BluetoothSocket socket, Handler handler) {
        mSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        mHandler = handler;

        // 获取Socket的输入输出流
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        mInStream = tmpIn;
        mOutStream = tmpOut;

    }


    @Override
    public void run() {
        byte[] buffer = new byte[1024];
        int bytes;
        while (true){
            try {
                bytes = mInStream.read(buffer);
                if(bytes > 0){
                    Log.d("r","===");
                    Message message = mHandler.obtainMessage(Constant.MSG_GOT_DATA, buffer);
                    mHandler.sendMessage(message);
                }
                Log.d("r", "message size" + bytes);
            } catch (IOException e) {
                e.printStackTrace();
                mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
                break;
            }
        }
    }

    /**
     * 关闭连接
     */
    public void cancel() {
        try {
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 写数据
     * @param data
     */
    public void write(byte[] data) {
        try {
            mOutStream.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  

  

分类:

技术点:

相关文章: