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);
}
}