Android 蓝牙通信

一、现在的无线通信方案及差别

在这里插入图片描述
上图是2018年甚至是更老的时候的方案

除以上之外还有 红外线传输
但是红外线是直线的传输方式(单向传输?)不适应无线通讯

二、蓝牙传输功能开发

1、准备阶段

1)权限

1、操作蓝牙需要的权限

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

2、程序与其他程序进行配对需要一下权限

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
2)蓝牙的开启/关闭/状态

有两个比较重要的类:
.BluetoothAdapter 本机的蓝牙适配器
.远程的蓝牙适配器

判断设备是支持蓝牙
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
	// 如果是空的话,就别是当前设备不支持蓝牙
}
获取蓝牙状态
    /**
     * 获取蓝牙的状态
     * @return
     */
    public boolean getBlueToothStatus(){
        assert (mBluetoothAdapter != null);
//        assert
//        如果为true,则程序继续执行。
//        如果为false,则程序抛出AssertionError,并终止执行。
        return mBluetoothAdapter.isEnabled();
    }
启动/关闭
/**
     * 启动蓝牙
     * @param activity
     * @param requestCode
     */
    public void turnOnBlueTooth(Activity activity, int requestCode){
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        activity.startActivityForResult(intent, requestCode);
//        mBluetoothAdapter.enable(); 该方法可以在不经过人为控制的情况下打开蓝牙,但是google不建议这么做
    }
/**
     * 关闭蓝牙
     */
    public void turnOffBlueTooth() {
        mBluetoothAdapter.disable();
    }

2、查找设备

1) 让设备可见

在让设备可见前,当然需要:
.检查设备是否支持蓝牙
.打开蓝牙

/**
* 让设备蓝牙可见
*/
public void enableVisibly(Context context){
	Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
	discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
	context.startActivity(discoverableIntent);
}

可以通过广播来监听设备"可见"与"不可见"状态的切换
在这里插入图片描述

2) 查找设备
首先启动查找设备
/**
*启动,查找设备
*/
public void findDevice(){
	assert (mBluetoothAdapter != null);
	mBluetoothAdapter.startDiscovery();
}
然后是通过广播来获取到查找的结果。

广播监听三种:
在这里插入图片描述
在广播内监听action
.开始查找设备

if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
	//初始化数据列表
	mDeviceList.clear();
	mAdapter.notifyDataSetChanged();
}

.查找到(一个)设备

if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
	BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
	//找到一个,添加一个
	mDeviceList.add(device);
	mAdapter.notifyDataSetChanged();
}

.结束查找设备

if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
	//查找结束后的操作
}
3) 绑定设备
对于已经绑定的设备

获取已经绑定的设备

/**
* 获取绑定设备的集合
*/
public List<BluetoothDevice> getBondedDeviceList(){
	return new ArrayList<>(mBluetoothAdapter.getBondedDevices());
}

将已经绑定的设备添加到ListView中,
点击事件设置为 null 。

mBondedDeviceList = mController.getBondedDeviceList();
mAdapter.refresh(mBondedDeviceList); //ListView的适配器
mListView.setOnItemClickListener(null);
对于未绑定的设备

查找到设备后,将设备添加到展示列表中

mAdapter.refresh(mDeviceList); //ListView的adapter,以及发现的设备列表mDeviceList
mListView.setOnItemClickListener(bindDeviceClick); //设置点击事件,绑定设备

点击对应Item进行绑定

public void onItemClick(AdapterView<?> adapterView, View view, int i, long l){
	BluetoothDevice device = mDeviceList.get(i);
	device.createBond();
	//绑定是什么?,绑定是给予设备双方,各自一个长期安全密钥,让他们两再次连接时不需要进行配对
}

BLE

client

public class BleClientActivity extends AppCompatActivity implements BlueDeviceItemAdapter.AdapterCallBack {

    private static final int BLUE_START_STATE = 1;
    private static final int BLUE_ACTION_DISCOVERY_STARTED = 2;
    private static final int BLUE_ACTION_DISCOVERY_FINISHED = 3;
    private final String TAG = "BluetoothScanActivity";
    private final int BLUE_PERMISSIONS_RECODE = 1;
    private final int BLUE_START_RECODE = 2;
    private final int LOCATION_START_RECODE = 3;

    private RecyclerView mRecyclerView;
    private BlueDeviceItemAdapter mListAdapter;
    private List<BluetoothDevice> mDeviceList;

    private TextView mBlueMessage;
    private BluetoothAdapter mBluetoothAdapter;

    private Thread mToastThread;
    private Thread mReadThead;
    private Thread mWriteThead;
    private boolean isScaning = false;
    private static boolean runWriteServer = false;
    private static boolean runReadServer = false;

    private BluetoothDevice mConnectionDevice;
    private BluetoothGatt mBluetoothGatt;
    private BluetoothGattService mGattService;
    private BluetoothGattCharacteristic mCharacteristic;

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message message) {
            switch (message.what) {
                case BleClientActivity.BLUE_START_STATE:
                    getBlueState(message.arg1);
                    break;
                case BleClientActivity.BLUE_ACTION_DISCOVERY_STARTED:
                    actionDiscovery();
                    break;
                case BleClientActivity.BLUE_ACTION_DISCOVERY_FINISHED:
                    stopDiscovery();
                    break;
                default:
                    break;
            }
            return false;
        }
    });

    private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Message msg = new Message();
            if (action != null) {
                showLog("blue action: " + action);
                switch (action) {
                    case BluetoothAdapter.ACTION_STATE_CHANGED:
                        msg.what = BLUE_START_STATE;
                        msg.arg1 = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                        break;
                    case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                        msg.what = BLUE_ACTION_DISCOVERY_STARTED;
                        break;
                    case BluetoothDevice.ACTION_FOUND:
                        foundBlueDevice(intent);
                        break;
                    case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                        msg.what = BLUE_ACTION_DISCOVERY_FINISHED;
                        break;
                }
                mHandler.sendMessage(msg);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth_scan);
        mRecyclerView = findViewById(R.id.rv_device_list);
        mBlueMessage = findViewById(R.id.tv_mblue_message);
        registerBluetoothListener();
        initList();
    }

    @Override
    protected void onDestroy() {
        mBluetoothAdapter.cancelDiscovery();
        isScaning = false;
        mToastThread = null;
        mConnectionDevice = null;
        mBluetoothGatt = null;
        mGattService = null;
        mCharacteristic = null;

        runReadServer = false;
        runWriteServer = false;
        super.onDestroy();
    }

    private void initList() {
        //设置固定大小
        mRecyclerView.setHasFixedSize(true);
        //创建线性布局
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(RecyclerView.VERTICAL);
        mRecyclerView.setLayoutManager(layoutManager);
        //创建适配器,并且设置
        mDeviceList = new ArrayList<>();
        mListAdapter = new BlueDeviceItemAdapter(this,mDeviceList,this);
        mRecyclerView.setAdapter(mListAdapter);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case BLUE_PERMISSIONS_RECODE:
            case LOCATION_START_RECODE:
                boolean flag = true;
                for (int item : grantResults) {
                    if (item != PackageManager.PERMISSION_GRANTED) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    startBluetoothScan();
                } else {
                    showToast("给权限啊!~");
                }
                break;
            default:
                break;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private void requestBluetoothPermissions() {
        requestPermissions(new String[]{
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
        }, BLUE_PERMISSIONS_RECODE);
    }

    private void registerBluetoothListener() {
        IntentFilter filter = new IntentFilter();
        //开关状态
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        //开始查找
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        //结束查找
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        //查找设备
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        //设备扫描模式变化
        filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        //绑定状态
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(mBluetoothReceiver, filter);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start_bluetooth_scan:
                startBluetoothScan();
                break;
            case R.id.bt_change_read_mode:
                runReadServer = !runReadServer;
                startReadData();
                break;
            case R.id.bt_change_write_mode:
                runWriteServer = !runWriteServer;
                startWriteData();
                break;
        }
    }

    private void startBluetoothScan() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            showToast("本设备没有蓝牙功能");
            return;
        }

        //先判断有没有权限
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED
            ||ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED
            ||ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
            ||ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            showToast("没有给蓝牙权限");
            requestBluetoothPermissions();
            return;
        }

        //判断及启动 位置信息
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        //判断是否开启了GPS
        boolean ok = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (!ok){
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent,LOCATION_START_RECODE);
        }

        //判断及启动 蓝牙
        if (!mBluetoothAdapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            BleClientActivity.this.startActivityForResult(intent, BLUE_START_RECODE);
//            mBluetoothAdapter.enable();
        } else {
            startScan();
        }
    }

    private void startScan() {
        //使自身蓝牙可见
        if (mBluetoothAdapter.isEnabled()) {
            if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
                startActivity(discoverableIntent);
            }
        }

        //展示自身蓝牙信息
        if (mBlueMessage != null && mBluetoothAdapter != null) {
            String name = mBluetoothAdapter.getName();
            String address = mBluetoothAdapter.getAddress();
//            String uuid = UUID.randomUUID().toString();
            mBlueMessage.setText("name : " + name +" address: " + address);
//            mBlueMessage.setText(uuid);
//            showLog("UUID : " + uuid);
        }

        //开始扫描
        if (mBluetoothAdapter != null) {
            // 可以同时发现 经典蓝牙 和 ble 的
            mBluetoothAdapter.startDiscovery();
//            mBluetoothAdapter.setName("pun client");
        }

        getPairedDevices();
    }

    private void getPairedDevices() {
        //获取已经配对的蓝牙设备
        Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
        Log.d(TAG, "bonded device size ="+devices.size());
        for(BluetoothDevice bonddevice:devices){
            Log.d(TAG, "bonded device name ="+bonddevice.getName()+" address"+bonddevice.getAddress());
        }
    }

    private void actionDiscovery() {
        mToastThread = new Thread(new Runnable() {
            @Override
            public void run() {
                isScaning = true;
                while(isScaning){
                    try {
                        showToast("扫描中...");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        mToastThread.start();
    }

    private void stopDiscovery() {
        isScaning = false;
        mToastThread = null;
        showToast("扫描完毕!");
    }

    private void getBlueState(int blueState) {
        switch (blueState) {
            case BluetoothAdapter.STATE_TURNING_ON:
                showLog("蓝牙正在打开");
                break;
            case BluetoothAdapter.STATE_ON:
                showLog("蓝牙已经打开");
                startScan();
                break;
            case BluetoothAdapter.STATE_TURNING_OFF:
                showLog("蓝牙正在关闭");
                break;
            case BluetoothAdapter.STATE_OFF:
                showLog("蓝牙已经关闭");
                break;
        }
    }

    private void foundBlueDevice(Intent intent) {
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (device != null) {
            showLog("device name --> " + device.getName());
            if (!mDeviceList.contains(device)){
                mDeviceList.add(device);
                mListAdapter.setItems(mDeviceList);
            }
        }
    }

    private void showToast(String text) {
        Util.showToast(BleClientActivity.this,text);
    }

    private void showLog(String text) {
        Util.showLog(TAG,text);
    }

    @Override
    public void ClickListener(int position) {
        //取消 扫描
        mBluetoothAdapter.cancelDiscovery();
//        connectByGatt(mBluetoothAdapter.getAddress());
        connectByGatt(mDeviceList.get(position).getAddress());
        mBlueMessage.setText("server name: " + mDeviceList.get(position).getName());
    }

    private void connectByGatt(String mac) {
        if (!TextUtils.isEmpty(mac)){
            mConnectionDevice = null;
            mBluetoothGatt = null;

            //获取设备对象
            mConnectionDevice = mBluetoothAdapter.getRemoteDevice(mac);
            mBluetoothGatt = mConnectionDevice.connectGatt(BleClientActivity.this, false, new BluetoothGattCallback() {
                @Override
                public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                    if (newState == BluetoothProfile.STATE_CONNECTED){
                        showLog("test 启动发现服务 : " + mBluetoothGatt.discoverServices());
                    }
                }

                @Override
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS){
                        //扫描所有服务信息
//                        List<BluetoothGattService> sup = mBluetoothGatt.getServices();
//                        for (BluetoothGattService gattService:sup){
//                            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
//                            for (BluetoothGattCharacteristic gattCharacteristic:gattCharacteristics){
//                                int charaProp = gattCharacteristic.getProperties();
//                                // 2
//                                mBluetoothGatt.setCharacteristicNotification(gattCharacteristic,true);
//                                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0){
//                                    showLog("test PROPERTY_READ service uuid ->" + gattService.getUuid() + " char uuid ->"+gattCharacteristic.getUuid());
//                                }
//                                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0){
//                                    showLog("test PROPERTY_WRITE service uuid ->" + gattService.getUuid() + " char uuid ->"+gattCharacteristic.getUuid());
//                                }
//                                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0){
//                                    showLog("test PROPERTY_NOTIFY service uuid ->" + gattService.getUuid() + " char uuid ->"+gattCharacteristic.getUuid());
//                                }
//                            }
//                        }

                        //获取指定的 服务 及 特征
                        BluetoothGattService service = mBluetoothGatt.getService(Util.BLE_UUID_SERVICE);
                        if (service !=null){
                            mGattService = service;
                            BluetoothGattCharacteristic characteristic = service.getCharacteristic(Util.BLE_UUID_CHARACTERISTIC);
                            if (characteristic == null){
                                showLog("发现特征 失败");
                            }else {
                                showLog("发现特征 成功,并发送数据 \'hello pun server\'");
                                mCharacteristic = characteristic;
                                mBluetoothGatt.setCharacteristicNotification(mCharacteristic,true);

                                runWriteServer = true;
                                runReadServer = true;
                                startWriteData();
                                startReadData();
                            }
                        }else {
                            showLog("发现服务 失败");
                        }

                    }else {
                        showLog("test !GATT_SUCCESS ->" + gatt.getServices().toString());
                        showLog("test status -> "+ status);
                    }
                }

                @Override
                public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                    super.onCharacteristicRead(gatt, characteristic, status);
                    showLog("client onCharacteristicRead");
                    if (mBlueMessage != null){
                        String strV = new String(characteristic.getValue());
                        mBlueMessage.setText("from server: "+strV);
                    }
                }

                @Override
                public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                    super.onCharacteristicWrite(gatt, characteristic, status);
                    showLog("client onCharacteristicWrite");
                }

                @Override
                public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                    showLog("test onCharacteristicChanged ---> characteristic.value : " + characteristic.getValue());
                }
            });
        }
    }

    private void startWriteData() {
        mWriteThead = new Thread(new Runnable() {
            @Override
            public void run() {
                while (runWriteServer){
                    try {
                        if (mCharacteristic != null && mBluetoothGatt != null){
                            Date dd=new Date();
                            SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            String time=sim.format(dd);
                            String strV = "from client\n" + time;
                            mCharacteristic.setValue(strV);
                            mBluetoothGatt.writeCharacteristic(mCharacteristic);
                        }
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        showLog("startWriteData --> e " + e.getMessage());
                    }
                }
            }
        });
        mWriteThead.start();
    }

    private void startReadData() {
        mReadThead = new Thread(new Runnable() {
            @Override
            public void run() {
                while (runReadServer){
                    try {
                        if (mBluetoothGatt != null && mCharacteristic != null){
                            mBluetoothGatt.readCharacteristic(mCharacteristic);
                            Thread.sleep(1000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        showLog("startReadData --> e " + e.getMessage());
                    }
                }
            }
        });
        mReadThead.start();
    }
}

server

public class BleServerActivity extends AppCompatActivity {
    private final String TAG = "BleServerActivity";
    private final int BLUE_PERMISSIONS_RECODE = 1;
    private final int LOCATION_START_RECODE = 3;

    private TextView mStatusView;
    private TextView mClientName;

    private BluetoothManager mBluetoothManager;
    private BluetoothLeAdvertiser mBluetoothLeAdvertiser;
    private BluetoothGattServer mBluetoothGattServer;
    private BluetoothGattServerCallback mBluetoothGattServerCallback = new BluetoothGattServerCallback() {
        //设备连接/断开连接回调
        @Override
        public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
            super.onConnectionStateChange(device, status, newState);
            showLog("连接状态发生改变,安卓系统回调onConnectionStateChange:device name="+
                    device.getName()+
                    "address="+device.getAddress()+
                    "status="+status+"newstate="+newState);
            if (newState == BluetoothProfile.STATE_CONNECTED){
                if (mClientName != null) {
                    mClientName.setText("client name : " + device.getName());
                }
            }
        }

        //特征值读取回调
        @Override
        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
            showLog("客户端有读的请求,安卓系统回调该onCharacteristicReadRequest()方法");
            Date dd=new Date();
            SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time=sim.format(dd);
            String strV = time;
            mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,strV.getBytes());
        }

        //特征值写入回调
        @Override
        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
            super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
            showLog("客户端有写的请求,安卓系统回调该onCharacteristicWriteRequest()方法");
            String strV = new String(value);
            showLog("onCharacteristicWriteRequest strV " + strV);
            if (!TextUtils.isEmpty(strV) && mStatusView != null){
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mStatusView.setText(strV);
                    }
                });
            }else {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mStatusView = findViewById(R.id.tv_server_status);
                    }
                });
            }
            //特征被读取,在该回调方法中回复客户端响应成功
            //这个不返回 客户端 无法 read 服务端数据,而且返回了客户端没有响应?????
            mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value);

            //处理响应内容
            //value:客户端发送过来的数据
            //onResponseToClient(value,device,requestId,characteristic);
        }

        //描述读取回调
        @Override
        public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
            super.onDescriptorReadRequest(device, requestId, offset, descriptor);
            showLog("server onDescriptorReadRequest ");
        }

        //描述写入回调
        @Override
        public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
            showLog("server onDescriptorWriteRequest ");
            mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value);
            // onResponseToClient(value,device,requestId,descriptor.getCharacteristic());
        }

        //添加本地服务回调
        @Override
        public void onServiceAdded(int status,BluetoothGattService service){
            super.onServiceAdded(status,service);
            if (status == BluetoothGatt.GATT_SUCCESS){
                isBroadcasting(true);
                showToast("添加自定义 服务成功");
            }else {
                startBroadcastFail("on onServiceAdded");
            }
        }
    };

    private AdvertiseCallback mAdertiseCallback = new AdvertiseCallback() {
        @Override
        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
            super.onStartSuccess(settingsInEffect);
            showToast("server 广播成功");
            initServices(BleServerActivity.this);
        }

        @Override
        public void onStartFailure(int errorCode) {
            super.onStartFailure(errorCode);
            showToast("server 广播失败");
            startBroadcastFail("on startAdvertising");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ble_server);
        initView();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopBroadcast();
    }

    private void initView() {
        mStatusView = findViewById(R.id.tv_server_status);
        mClientName = findViewById(R.id.tv_client_name);
    }

    public void onClick(View view) {
        switch (view.getId()){
            case R.id.bt_start_ble_server:
                startServer();
                break;
        }
    }

    private void startServer() {
        //先判断有没有权限
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED
                ||ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED
                ||ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                ||ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            showToast("没有给蓝牙权限");
            requestBluetoothPermissions();
            return;
        }

        //判断及启动 位置信息
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        //判断是否开启了GPS
        boolean ok = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (!ok){
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent,LOCATION_START_RECODE);
        }

        if(mBluetoothLeAdvertiser==null){
            mBluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
            if(mBluetoothManager!=null){
                BluetoothAdapter bluetoothAdapter=mBluetoothManager.getAdapter();
                if(bluetoothAdapter!=null){
                    //使自身蓝牙可见
                    if (bluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                        Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
                        startActivity(discoverableIntent);
                    }
//                    bluetoothAdapter.setName("pun server");

                    mBluetoothLeAdvertiser=bluetoothAdapter.getBluetoothLeAdvertiser();
                    startBroadcast();
                }else{
                    showToast("设备不支持蓝牙广播");
                }
            }else{
                showToast("不支持蓝牙");
            }
        }
    }

    private void startBroadcast() {
        showToast("服务开始广播");
        AdvertiseSettings settings = buildAdvertiseSettings();
        AdvertiseData data = buildAdvertiseData();
        //AdvertiseData responseData = buildScanResponseData();

        if(mBluetoothLeAdvertiser!=null){
            mBluetoothLeAdvertiser.startAdvertising(settings,data,mAdertiseCallback);
        }
    }

    private void stopBroadcast() {
        if (mBluetoothLeAdvertiser!=null){
            mBluetoothLeAdvertiser.stopAdvertising(mAdertiseCallback);
        }
    }

    private AdvertiseSettings buildAdvertiseSettings(){
        AdvertiseSettings.Builder settingsBuilder=new AdvertiseSettings.Builder();
        settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);
        settingsBuilder.setTimeout(0);

        return settingsBuilder.build();
    }

    private AdvertiseData buildAdvertiseData(){
        AdvertiseData.Builder dataBuilder=new AdvertiseData.Builder();
        dataBuilder.setIncludeDeviceName(true);

        return dataBuilder.build();
    }

//    private AdvertiseData buildScanResponseData(){
//        AdvertiseData.Builder mScanResponseData = new AdvertiseData.Builder()
//                //隐藏广播设备名称
//                .setIncludeDeviceName(false)
//                //隐藏发射功率级别
//                .setIncludeDeviceName(false)
//                //设置广播的服务`UUID`
//                .addServiceUuid(new ParcelUuid(Util.BLE_UUID_SERVICE));
//        //设置厂商数据
//        //.addManufacturerData(0x11,hexStrToByte(mData));
//
//        return mScanResponseData.build();
//    }

    private void initServices(Context context){
        if (mBluetoothManager != null){
            mBluetoothGattServer = mBluetoothManager.openGattServer(context,mBluetoothGattServerCallback);
            BluetoothGattService service = new BluetoothGattService(Util.BLE_UUID_SERVICE,BluetoothGattService.SERVICE_TYPE_PRIMARY);
            BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(Util.BLE_UUID_CHARACTERISTIC,
                    BluetoothGattCharacteristic.PROPERTY_WRITE|
                            BluetoothGattCharacteristic.PROPERTY_NOTIFY|
                            BluetoothGattCharacteristic.PROPERTY_READ,
                    BluetoothGattCharacteristic.PERMISSION_WRITE|
                            BluetoothGattCharacteristic.PERMISSION_READ);

            service.addCharacteristic(characteristic);
            boolean result = mBluetoothGattServer.addService(service);
            if (!result) {
                startBroadcastFail("on initServices");
            }
        }
    }

    private void requestBluetoothPermissions() {
        requestPermissions(new String[]{
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
        }, BLUE_PERMISSIONS_RECODE);
    }

    private void isBroadcasting(Boolean flag){
        if (mStatusView != null){
            mStatusView.setText(flag?"广播中...":"广播未启动");
        }
    }

    private void startBroadcastFail(String where){
        if (mStatusView != null){
            mStatusView.setText("启动广播失败 在: " + where);
        }
    }

    private void showToast(String text) {
        Util.showToast(BleServerActivity.this,text);
    }

    private void showLog(String text) {
        Util.showLog(TAG,text);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值