From 2f676cdd1cef3a793f41cf05f5e5d17a774b7a81 Mon Sep 17 00:00:00 2001 From: wenfei Date: Thu, 20 Nov 2025 17:01:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=93=9D=E7=89=99=E6=9C=8D=E5=8A=A1=E5=AE=8C?= =?UTF-8?q?=E6=88=90=EF=BC=8C=E5=90=91=E4=BC=A0=E6=84=9F=E5=99=A8=E5=86=99?= =?UTF-8?q?=E5=85=A5=E6=95=B0=E6=8D=AE=E5=AE=8C=E6=88=90=EF=BC=8C=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E8=93=9D=E7=89=99=E9=80=9A=E7=9F=A5=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- .../dywoa/bleUtil/BlueTestInfoActivity.java | 4 +- .../bleUtil/BlueToothDeviceActivity.java | 16 +- .../bleUtil/BlueToothDeviceSdkActivity.java | 546 +++++++++++++++++ .../dywoa/bleUtil/BluetoothLeService.java | 244 ++++---- .../rehome/dywoa/ui/activity/HomeActivity.kt | 88 ++- .../sbxdjgl/BlueToothDeviceSdkActivity.java | 560 ------------------ .../dywoa/ui/fragment/HomeFragment.java | 7 +- .../res/layout/activity_bluetoothlist.xml | 88 ++- app/src/main/res/layout/listitem_device.xml | 7 +- app/src/main/res/values/strings.xml | 4 +- 11 files changed, 842 insertions(+), 724 deletions(-) create mode 100644 app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceSdkActivity.java delete mode 100644 app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/BlueToothDeviceSdkActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3750330..8be45b4 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -350,7 +350,7 @@ android:configChanges="keyboardHidden|orientation|screenSize" android:screenOrientation="portrait" /> diff --git a/app/src/main/java/com/rehome/dywoa/bleUtil/BlueTestInfoActivity.java b/app/src/main/java/com/rehome/dywoa/bleUtil/BlueTestInfoActivity.java index 447ef06..e7e8b9f 100755 --- a/app/src/main/java/com/rehome/dywoa/bleUtil/BlueTestInfoActivity.java +++ b/app/src/main/java/com/rehome/dywoa/bleUtil/BlueTestInfoActivity.java @@ -76,8 +76,8 @@ public class BlueTestInfoActivity extends BaseActivity { } }); lv = findViewById(R.id.lv); - txData = findViewById(R.id.tx_data); - ztData = findViewById(R.id.zt_data); +// txData = findViewById(R.id.tx_data); +// ztData = findViewById(R.id.zt_data); } @Override diff --git a/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceActivity.java b/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceActivity.java index c639eed..609d72d 100644 --- a/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceActivity.java +++ b/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceActivity.java @@ -131,17 +131,8 @@ public class BlueToothDeviceActivity extends BaseActivity { if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (ActivityCompat.checkSelfPermission(BlueToothDeviceActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. return; } - //showLog("扫描发现设备" + device.getName() + "," + device.getAddress()); - //String deviceName = device.getName(); if (device !=null && device.getName() != null && device.getName().startsWith("W3")){ showLog(new Gson().toJson(device)); mLeDeviceListAdapter.addDevice(device); @@ -155,7 +146,6 @@ public class BlueToothDeviceActivity extends BaseActivity { showLog("连接"); mLeDeviceListAdapter.setSelectItem(selectItem); mLeDeviceListAdapter.notifyDataSetChanged(); - BluetoothDevice device = mLeDeviceListAdapter.getDevice(selectItem); SPUtils.put(context, Contans.KEY_BLUE_TOOTH,new Gson().toJson(device)); String deviceName = device.getName(); @@ -215,10 +205,10 @@ public class BlueToothDeviceActivity extends BaseActivity { } }); - initToolbar("蓝牙数据管理", "扫描蓝牙", new View.OnClickListener() { + initToolbar("蓝牙传感器管理", "扫描蓝牙", new View.OnClickListener() { @Override public void onClick(View v) { - showLog("蓝牙数据管理"); + showLog("扫描蓝牙设备"); blueScan(); } }); @@ -292,7 +282,7 @@ public class BlueToothDeviceActivity extends BaseActivity { @Override protected void onDestroy() { super.onDestroy(); - //ble.disconnect(); + ble.disconnect(); ble.free(); // if(BleManager.getInstance().getScanSate()== BleScanState.STATE_SCANNING){ // BleManager.getInstance().cancelScan(); diff --git a/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceSdkActivity.java b/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceSdkActivity.java new file mode 100644 index 0000000..5e63009 --- /dev/null +++ b/app/src/main/java/com/rehome/dywoa/bleUtil/BlueToothDeviceSdkActivity.java @@ -0,0 +1,546 @@ +package com.rehome.dywoa.bleUtil; + + +import android.Manifest; +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanResult; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.os.Build; +import android.os.Handler; +import android.os.IBinder; +import android.text.TextUtils; +import android.util.Log; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.gson.Gson; +import com.rehome.dywoa.Contans; +import com.rehome.dywoa.R; +import com.rehome.dywoa.base.BaseActivity; +import com.rehome.dywoa.utils.SPUtils; +import com.rehome.dywoa.weiget.AuditDialog; +import com.rehome.dywoa.weiget.ConfirmDialog; +import com.rehome.dywoa.weiget.WaitDialog; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + + +public class BlueToothDeviceSdkActivity extends BaseActivity { + + ListView lv; + TextView tvNodata; + TextView ble_status; + TextView ble_dianlang; + // TextView txData; + // TextView ztData; + private String cmd = ""; + + private LeDeviceListAdapter mLeDeviceListAdapter; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothLeScanner bluetoothLeScanner; + private boolean mScanning; + private Handler mHandler; + private static final int REQUEST_ENABLE_BT = 1; + private static final long SCAN_PERIOD = 10000; + private static final int REQUEST_CODE_ACCESS_COARSE_LOCATION = 123; + private boolean initconn = false; + private String mDeviceAddress; + private String mBleName; + + private String deviceNameSave; + private String deviceAddressSave; + private BluetoothLeService mBluetoothLeService; + private boolean mConnected = false; + private ArrayList mPermissionList = new ArrayList(); + + private WaitDialog dialog; + + private Timer timer; + + @Override + public int getContentViewID() { + return R.layout.activity_bluetoothlist; + } + + @Override + public void initView() { + initToolbar("蓝牙传感器管理", "扫描蓝牙", new View.OnClickListener() { + @Override + public void onClick(View v) { + showLog("扫描蓝牙设备"); + reConnectBle(); + } + }); + lv = findViewById(R.id.lv); + tvNodata = findViewById(R.id.tv_nodata); + ble_status = findViewById(R.id.ble_status); + ble_dianlang = findViewById(R.id.ble_dianlang); + + dialog = new WaitDialog(context, "正在扫描蓝牙传感器..."); + dialog.setCancelable(true); + + tvNodata.setVisibility(View.GONE); + lv.setVisibility(View.VISIBLE); + mHandler = new Handler(); + deviceAddressSave = (String) SPUtils.get(context, Contans.KEY_BLUE_TOOTH_ADDRESS,""); + showLog("-------deviceAddressSave-------"); + showLog(deviceAddressSave); + deviceNameSave = (String) SPUtils.get(context, Contans.KEY_BLUE_TOOTH_NAME,""); + showLog("-------deviceNameSave-------"); + showLog(mBleName); + } + + @Override + public void initData() { + initPermission(); + if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { + Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); + //finish(); + return; + } + setAdapter(); + LocalBroadcastManager.getInstance(this).registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); + mHandler.postDelayed(this::reConnectBle, 1000); + } + + private void reConnectBle(){ + mLeDeviceListAdapter.clear(); + mLeDeviceListAdapter.notifyDataSetChanged(); + mLeDeviceListAdapter.setSelectItem(-1); + // 注销广播接收器 + LocalBroadcastManager.getInstance(this).unregisterReceiver(mGattUpdateReceiver); + if(mBluetoothLeService!=null){ + mBluetoothLeService.disconnect(); + mBluetoothLeService.close(); + unbindService(mServiceConnection); + } + Intent intent = new Intent(this, BluetoothLeService.class); + stopService(intent); + + initPermission(); + if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { + Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); + //finish(); + return; + } + setAdapter(); + LocalBroadcastManager.getInstance(this).registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); + } + + // todo 蓝牙动态申请权限 + private void initPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // Android 版本大于等于 Android12 时 + // 只包括蓝牙这部分的权限,其余的需要什么权限自己添加 + mPermissionList.add(Manifest.permission.BLUETOOTH_SCAN); + mPermissionList.add(Manifest.permission.BLUETOOTH_ADVERTISE); + mPermissionList.add(Manifest.permission.BLUETOOTH_CONNECT); + } else { + // Android 版本小于 Android12 及以下版本 + mPermissionList.add(Manifest.permission.ACCESS_COARSE_LOCATION); + mPermissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); + } + showLog(new Gson().toJson(mPermissionList.toArray(new String[0]))); + ActivityCompat.requestPermissions(this, mPermissionList.toArray(new String[0]), 1001); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + Log.i("app", "onRequestPermissionsResult"); + Log.i("app", String.valueOf(grantResults.length)); + Log.i("app", new Gson().toJson(grantResults)); + boolean hasGrant = true; + for (int grantResult : grantResults) { + if (grantResult != 0) { + //未授权 + hasGrant = false; + break; + } + } + if (hasGrant) { + BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + mBluetoothAdapter = bluetoothManager.getAdapter(); + if (mBluetoothAdapter == null) { + Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); + return; + } + bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); +// setAdapter(); + Intent gattServiceIntent = new Intent(BlueToothDeviceSdkActivity.this, BluetoothLeService.class); + bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE); + initconn = true; + + //已授权 + scanLeDevice(true); + } else { + showToast("您未授权开启蓝牙连接到Blue设备,请先开启权限"); + } + } + + @Override + protected void onResume() { + super.onResume(); + if (mBluetoothAdapter != null && (!mBluetoothAdapter.isEnabled())) { + Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + return; + } + startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); + } + if(timer==null){ + try { + timer = new Timer(); + timer.schedule(new TimerTask() { + public void run() { + if(mBluetoothLeService!=null){ + //mBluetoothLeService.writeString("BV"); + } + } + }, 6000, 6000); + // 设定指定的时间time,此处为10000毫秒 + } catch (Exception e) { + showLog("timer is nnull"); + } + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) { + finish(); + return; + } + super.onActivityResult(requestCode, resultCode, data); + } + + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + finish(); + return true; + } + return super.onKeyDown(keyCode, event); + } + + private void scanLeDevice(final boolean enable) { + if (enable) { + dialog.show(); + mHandler.postDelayed(() -> { + mScanning = false; + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { + return; + } + //mBluetoothAdapter.stopLeScan(mLeScanCallback); + bluetoothLeScanner.stopScan(leScanCallback); + }, SCAN_PERIOD); + mScanning = true; + //mBluetoothAdapter.startLeScan(mLeScanCallback); + bluetoothLeScanner.startScan(leScanCallback); + } else { + mScanning = false; + //mBluetoothAdapter.stopLeScan(mLeScanCallback); + bluetoothLeScanner.stopScan(leScanCallback); + } + } + + //扫描到每台设备后调用回调函数callback. +// private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { +// @Override +// public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { +// runOnUiThread(() -> { +// mLeDeviceListAdapter.addDevice(device); +// mLeDeviceListAdapter.notifyDataSetChanged(); +// }); +// } +// }; + + private ScanCallback leScanCallback = new ScanCallback() { + @Override + public void onScanResult(int callbackType, ScanResult result) { + super.onScanResult(callbackType, result); + BluetoothDevice device = result.getDevice(); + showLog("发现新设备啦"); + showLog(new Gson().toJson(device)); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + return; + } + String bleName = device.getName(); + String bleAddress = device.getAddress(); + showLog(bleName); + showLog(bleAddress); + if (bleName != null && bleName.startsWith("W3")) { + dialog.dismiss(); + mLeDeviceListAdapter.addDevice(device); + mLeDeviceListAdapter.notifyDataSetChanged(); + if(!TextUtils.isEmpty(deviceNameSave) && !TextUtils.isEmpty(deviceAddressSave) && deviceAddressSave.equals(bleAddress) && deviceNameSave.equals(bleName)){ + int count = mLeDeviceListAdapter.getCount(); + confirmConnect(count-1); + //mBluetoothLeService.connect(deviceAddressSave); + } + } + } + }; + + private void setAdapter() { + mLeDeviceListAdapter = new LeDeviceListAdapter(); + lv.setAdapter(mLeDeviceListAdapter); + lv.setOnItemClickListener((parent, view, position, id) -> { + AuditDialog confirmDialog = new AuditDialog(context, "您确定要绑定当前蓝牙传感器吗", new AuditDialog.AuditDialogListener() { + @Override + public void confirm() { + confirmConnect(position); + } + + @Override + public void cancel() { + + } + }); + confirmDialog.setCancelable(true); + confirmDialog.show(); + }); + } + + private void confirmConnect(int position) { + final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position); + if (device == null) return; + if (mScanning) { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { + return; + } + //mBluetoothAdapter.stopLeScan(mLeScanCallback); + bluetoothLeScanner.stopScan(leScanCallback); + mScanning = false; + } + + mDeviceAddress = device.getAddress(); + mBleName = device.getName(); + mLeDeviceListAdapter.setSelectItem(position);//记载当前点击选中的节点position,为了变色 + mLeDeviceListAdapter.notifyDataSetChanged(); + + if (initconn) { + if (!mConnected) mBluetoothLeService.connect(mDeviceAddress); + } else { + Intent gattServiceIntent = new Intent(BlueToothDeviceSdkActivity.this, BluetoothLeService.class); + bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE); + initconn = true; + } + } + + private class LeDeviceListAdapter extends BaseAdapter { + private class ViewHolder { + TextView deviceName; + TextView deviceStatus; + } + + private ArrayList mLeDevices; + private LayoutInflater mInflator; + + public LeDeviceListAdapter() { + super(); + mLeDevices = new ArrayList(); + mInflator = BlueToothDeviceSdkActivity.this.getLayoutInflater(); + } + + public void addDevice(BluetoothDevice device) { + if (!mLeDevices.contains(device)) { + mLeDevices.add(device); + } + } + + public BluetoothDevice getDevice(int position) { + return mLeDevices.get(position); + } + + public void clear() { + mLeDevices.clear(); + } + + @Override + public int getCount() { + return mLeDevices.size(); + } + + @Override + public Object getItem(int i) { + return mLeDevices.get(i); + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + ViewHolder viewHolder; + if (view == null) { + view = mInflator.inflate(R.layout.listitem_device, null); + viewHolder = new ViewHolder(); + viewHolder.deviceName = view.findViewById(R.id.device_name); + viewHolder.deviceStatus = view.findViewById(R.id.device_status); + view.setTag(viewHolder); + } else { + viewHolder = (ViewHolder) view.getTag(); + } + + BluetoothDevice device = mLeDevices.get(i); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + return null; + } + final String deviceName = device.getName(); + if (deviceName != null && deviceName.length() > 0) + viewHolder.deviceName.setText(deviceName); + else + viewHolder.deviceName.setText(R.string.unknown_device); + //当前点击选中的变色 + if (i == selectItem) { + viewHolder.deviceStatus.getPaint().setFakeBoldText(true); + viewHolder.deviceStatus.setTextColor(Color.parseColor("#00FF7F"));//连接之后的颜色 + viewHolder.deviceStatus.setText("已绑定"); + } else { + viewHolder.deviceStatus.getPaint().setFakeBoldText(false); + viewHolder.deviceStatus.setTextColor(Color.parseColor("#000000")); + viewHolder.deviceStatus.setText("未绑定"); + } + return view; + } + + public void setSelectItem(int selectItem) { + this.selectItem = selectItem; + } + + private int selectItem = -1; + } + + + private final ServiceConnection mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName componentName, IBinder service) { + mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService(); + if (!mBluetoothLeService.initialize()) { + finish(); + } + mBluetoothLeService.connect(mDeviceAddress); + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + mBluetoothLeService = null; + } + }; + private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { + mConnected = true; + //ztData.setText("蓝牙状态:已连接"); + ble_status.setText("已连接"); + ble_status.setTextColor(Color.parseColor("#00FF7F"));//连接之后的颜色 + SPUtils.put(context, Contans.KEY_BLUE_TOOTH_ADDRESS, mDeviceAddress); + SPUtils.put(context, Contans.KEY_BLUE_TOOTH_NAME, mBleName); + + } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { + mConnected = false; + //ztData.setText("蓝牙状态:已断开"); + ble_status.setText("已断开"); + ble_status.setTextColor(Color.parseColor("#ff0000"));//连接之后的颜色 + } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { + //ztData.setText("蓝牙状态:已连接,仪器准备就绪"); + showLog("数据传输通道准备就绪,可以发送数据了。"); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mBluetoothLeService.writeString("BV"); + } + },2000); + } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { + //String Data = ""; + String resultReceive = intent.getStringExtra(BluetoothLeService.EXTRA_DATA); +// String type = BleData.substring(0, 1); +// if (type.equals("T")) { +// Data = "温度:" + BleData.substring(2, 6); +// } else { +// Data = "震动:" + BleData.substring(2, 6); +// } + + if(!TextUtils.isEmpty(resultReceive)){ + List listDianLiang = stringToListBlank(resultReceive); + if(!listDianLiang.isEmpty()){ + showLog(listDianLiang.get(0)); + showLog(listDianLiang.get(1)); + List strDianLiang = stringToList(listDianLiang.get(0)); + if(!strDianLiang.isEmpty()){ + ble_dianlang.setText(strDianLiang.get(1)+strDianLiang.get(0)); + } + } + } + showLog(resultReceive); + + + //txData.setText(Data); + } + } + }; + + + static IntentFilter makeGattUpdateIntentFilter() { + final IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); + intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); + intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); + intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); + return intentFilter; + } + + private List stringToList(String strs) { + String str[] = strs.split(":"); + return Arrays.asList(str); + } + private List stringToListBlank(String strs) { + String str[] = strs.split("\n"); + return Arrays.asList(str); + } + + @Override + protected void onDestroy() { + scanLeDevice(false); + mLeDeviceListAdapter.clear(); + unbindService(mServiceConnection); + // 注销广播接收器 + LocalBroadcastManager.getInstance(this).unregisterReceiver(mGattUpdateReceiver); + if(timer!=null){ + timer.cancel(); + } + super.onDestroy(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/rehome/dywoa/bleUtil/BluetoothLeService.java b/app/src/main/java/com/rehome/dywoa/bleUtil/BluetoothLeService.java index 440398d..a723d05 100755 --- a/app/src/main/java/com/rehome/dywoa/bleUtil/BluetoothLeService.java +++ b/app/src/main/java/com/rehome/dywoa/bleUtil/BluetoothLeService.java @@ -7,6 +7,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; @@ -14,19 +15,22 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.util.Log; import androidx.core.app.ActivityCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.UUID; public class BluetoothLeService extends Service { - private final static String TAG = BluetoothLeService.class.getSimpleName(); + private final static String TAG = "app"; private BluetoothManager mBluetoothManager; private BluetoothAdapter mBluetoothAdapter; @@ -49,6 +53,14 @@ public class BluetoothLeService extends Service { public final static String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA"; + public BluetoothGattCharacteristic characteristicWrite = null; + public BluetoothGattCharacteristic characteristicRead = null; + + // 替换为你的服务和特征UUID + private static final UUID SERVICE_UUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");//服务uuid + private static final UUID CHARACTERISTIC_UUID_READ = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");//读取蓝牙uuid + private static final UUID CHARACTERISTIC_UUID_WRITE = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");//蓝牙写入数据uuid + private static final UUID CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");//开启蓝牙通知配置,固定写死 // Implements callback methods for GATT events that the app cares about. For example, @@ -58,25 +70,20 @@ public class BluetoothLeService extends Service { public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if (newState == BluetoothProfile.STATE_CONNECTED) { + // 连接成功,开始发现服务 intentAction = ACTION_GATT_CONNECTED; mConnectionState = STATE_CONNECTED; broadcastUpdate(intentAction); Log.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. if (ActivityCompat.checkSelfPermission(BluetoothLeService.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. return; } - Log.i(TAG, "Attempting to start service discovery:" + - mBluetoothGatt.discoverServices()); + boolean isDiscovery = mBluetoothGatt.discoverServices(); + Log.i(TAG, "Attempting to start service discovery:" + isDiscovery); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + mBluetoothGatt.close(); intentAction = ACTION_GATT_DISCONNECTED; mConnectionState = STATE_DISCONNECTED; Log.i(TAG, "Disconnected from GATT server."); @@ -86,34 +93,68 @@ public class BluetoothLeService extends Service { @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { + super.onServicesDiscovered(gatt, status); if (status == BluetoothGatt.GATT_SUCCESS) { - broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); - ////tsp默认选择一个地址 - BluetoothGattCharacteristic characteristic1= - gatt.getService(UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb")).getCharacteristic(UUID.fromString("0000ffe4-0000-1000-8000-00805f9b34fb")); - setCharacteristicNotification(characteristic1,true); + BluetoothGattService service = gatt.getService(SERVICE_UUID); + if (service != null) { + BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID_READ); + if (characteristic != null) { + // 启用通知 + enableCharacteristicNotification(gatt, characteristic); + broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); + } + } } else { - Log.w(TAG, "onServicesDiscovered received: " + status); + Log.i(TAG, "onServicesDiscovered received: " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + super.onCharacteristicRead(gatt, characteristic, status); if (status == BluetoothGatt.GATT_SUCCESS) { + //普通读取蓝牙设备数据,有些设备会用到,当前蓝牙传感器没用这个 + byte[] data = characteristic.getValue(); + String receivedData = new String(data); + Log.i(TAG, "读取数据: " + receivedData); broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + super.onCharacteristicChanged(gatt, characteristic); + // 收到通知数据 + byte[] data = characteristic.getValue(); + String receivedData = new String(data); + Log.i(TAG, "收到通知数据: " + receivedData); broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } - @Override - public void onCharacteristicWrite (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){ + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + super.onCharacteristicWrite(gatt, characteristic, status); + if (status == BluetoothGatt.GATT_SUCCESS) { + Log.i(TAG, "Data written successfully"); + } else { + Log.e(TAG, "Failed to write data: " + status); + } } }; + private void enableCharacteristicNotification(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + return; + } + gatt.setCharacteristicNotification(characteristic, true); + + BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG); + if (descriptor != null) { + descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + gatt.writeDescriptor(descriptor); + } + } + private void broadcastUpdate(final String action) { final Intent intent = new Intent(action); LocalBroadcastManager.getInstance(BluetoothLeService.this).sendBroadcast(intent); @@ -123,13 +164,18 @@ public class BluetoothLeService extends Service { private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) { final Intent intent = new Intent(action); // For all other profiles, writes the data formatted in HEX. - final byte[] data = characteristic.getValue(); - if (data != null && data.length > 0) { - final StringBuilder stringBuilder = new StringBuilder(data.length); - for(byte byteChar : data) - stringBuilder.append(String.format("%02X ", byteChar)); - intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString()); - } +// final byte[] data = characteristic.getValue(); + // 收到通知数据 + byte[] data = characteristic.getValue(); + String receivedData = new String(data, StandardCharsets.UTF_8); + //Log.i(TAG, "收到通知数据: " + receivedData); +// if (data != null && data.length > 0) { +// final StringBuilder stringBuilder = new StringBuilder(data.length); +// for (byte byteChar : data) +// stringBuilder.append(String.format("%02X ", byteChar)); +// intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString()); +// } + intent.putExtra(EXTRA_DATA, receivedData); LocalBroadcastManager.getInstance(BluetoothLeService.this).sendBroadcast(intent); } @@ -184,11 +230,10 @@ public class BluetoothLeService extends Service { * Connects to the GATT server hosted on the Bluetooth LE device. * * @param address The device address of the destination device. - * * @return Return true if the connection is initiated successfully. The connection result - * is reported asynchronously through the - * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} - * callback. + * is reported asynchronously through the + * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} + * callback. */ public boolean connect(final String address) {//连接设备 if (mBluetoothAdapter == null || address == null) { @@ -197,16 +242,9 @@ public class BluetoothLeService extends Service { } // Previously connected device. Try to reconnect. - if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)&& mBluetoothGatt != null) { + if (address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. return false; } if (mBluetoothGatt.connect()) { @@ -224,13 +262,36 @@ public class BluetoothLeService extends Service { } // We want to directly connect to the device, so we are setting the autoConnect // parameter to false. - mBluetoothGatt = device.connectGatt(this, false, mGattCallback); + //mBluetoothGatt = device.connectGatt(this, false, mGattCallback); + mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE); Log.d(TAG, "Trying to create a new connection."); mBluetoothDeviceAddress = address; mConnectionState = STATE_CONNECTING; return true; } + public boolean checkBleConnect(final String address) { + if (mBluetoothAdapter == null || address == null) { + return false; + } + if (address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { + Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + return false; + } + if (mBluetoothGatt.connect()) { + return true; + } else { + return false; + } + } + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); + if (device == null) { + return false; + } + return false; + } + /** * Disconnects an existing connection or cancel a pending connection. The disconnection result * is reported asynchronously through the @@ -243,16 +304,11 @@ public class BluetoothLeService extends Service { return; } if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. return; } mBluetoothGatt.disconnect(); + mBluetoothGatt.close(); + mBluetoothGatt = null; } /** @@ -277,70 +333,54 @@ public class BluetoothLeService extends Service { mBluetoothGatt = null; } - /** - * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported - * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)} - * callback. - * - * @param characteristic The characteristic to read from. - */ - public void readCharacteristic(BluetoothGattCharacteristic characteristic) { - if (mBluetoothAdapter == null || mBluetoothGatt == null) { - Log.w(TAG, "BluetoothAdapter not initialized"); - return; + public boolean writeData(byte[] data) { + if (mBluetoothGatt == null) { + Log.e("TAG", "BluetoothGatt is null"); + return false; } - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return; + + BluetoothGattService service = mBluetoothGatt.getService(SERVICE_UUID); + if (service == null) { + Log.e("TAG", "Service not found"); + return false; } - mBluetoothGatt.readCharacteristic(characteristic); - } - public void writeCharacteristic(BluetoothGattCharacteristic characteristic) { - if (mBluetoothAdapter == null || mBluetoothGatt == null) { - Log.w(TAG, "BluetoothAdapter not initialized"); - return; + + BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID_WRITE); + if (characteristic == null) { + Log.e("TAG", "Characteristic not found"); + return false; + } + + // 设置写入类型 + int properties = characteristic.getProperties(); + if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) { + characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + } else if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) { + characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); } + + characteristic.setValue(data); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return; + return false; } - mBluetoothGatt.writeCharacteristic(characteristic); + return mBluetoothGatt.writeCharacteristic(characteristic); } - /** - * Enables or disables notification on a give characteristic. - * - * @param characteristic Characteristic to act on. - * @param enabled If true, enable notification. False otherwise. - */ - //选择地址 - public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { - if (mBluetoothAdapter == null || mBluetoothGatt == null) { - Log.w(TAG, "BluetoothAdapter not initialized"); - return; - } - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return; + + // 写入字符串数据 + public boolean writeString(String message) { + byte[] data = message.getBytes(StandardCharsets.UTF_8); + return writeData(data); + } + + // 写入16进制数据 + public boolean writeHex(String hexString) { + int len = hexString.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + + Character.digit(hexString.charAt(i + 1), 16)); } - mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); + return writeData(data); } public List getSupportedGattServices() { diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/HomeActivity.kt b/app/src/main/java/com/rehome/dywoa/ui/activity/HomeActivity.kt index da8e8ca..842ddf2 100755 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/HomeActivity.kt +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/HomeActivity.kt @@ -2,13 +2,16 @@ package com.rehome.dywoa.ui.activity +import android.content.ComponentName import android.content.ContentValues import android.content.Context import android.content.Intent +import android.content.ServiceConnection import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.graphics.Color import android.os.Build +import android.os.IBinder import android.text.TextUtils import android.util.Log import android.view.Gravity @@ -59,6 +62,7 @@ import com.rehome.dywoa.bean.ScxjjhBean import com.rehome.dywoa.bean.StatusInfo import com.rehome.dywoa.bean.StatusInfoSingleTask import com.rehome.dywoa.bean.WaitForBean +import com.rehome.dywoa.bleUtil.BluetoothLeService import com.rehome.dywoa.databinding.ActivityHomeBinding import com.rehome.dywoa.entity.ScDjjhInfo import com.rehome.dywoa.ui.fragment.HomeFragment @@ -81,6 +85,7 @@ import com.yolanda.nohttp.rest.Response import org.litepal.crud.DataSupport import java.io.File import java.text.SimpleDateFormat +import java.util.Arrays import java.util.Calendar import java.util.Timer import java.util.TimerTask @@ -118,6 +123,15 @@ class HomeActivity : BaseActivityOaToolbarViewBinding() { private var manager: DownloadManager? = null +// private lateinit var ble: BleManager +// +// private var cmd: String = "" +// private var str: String = "" +// private var deviceNameSave: String = "" +// private var deviceAddressSave: String = "" + + private var mBluetoothLeService: BluetoothLeService?=null + override fun getViewBinding() = ActivityHomeBinding.inflate(layoutInflater) override fun getToolbar() = binding.toolbarView.toolbar @@ -137,6 +151,8 @@ class HomeActivity : BaseActivityOaToolbarViewBinding() { initMqtt() } + + initToolbar("首页") binding.toolbarView.topLl.visibility = View.GONE StatusBarUtil.setColor(this, ContextCompat.getColor(context, R.color.app_status_bar)) @@ -250,6 +266,20 @@ class HomeActivity : BaseActivityOaToolbarViewBinding() { getXjZhTjDropDown("lx"); } + private val mServiceConnection: ServiceConnection = object : ServiceConnection { + + override fun onServiceConnected(componentName: ComponentName, service: IBinder) { + // 服务连接成功时调用 + val binder = service as BluetoothLeService.LocalBinder + mBluetoothLeService = binder.service + } + + override fun onServiceDisconnected(componentName: ComponentName) { + mBluetoothLeService=null + } + } + + private fun initMqtt() { ////开启MQTT推送服务 mqttPublishServer = MqttSSLPublishServer(context) @@ -460,19 +490,7 @@ class HomeActivity : BaseActivityOaToolbarViewBinding() { checkConnectServer() } - override fun onDestroy() { - super.onDestroy() - if (timerCheckServerConnectStatus != null) { - timerCheckServerConnectStatus?.cancel() - } - if (mqttPublishServer != null) { - mqttPublishServer!!.destroyAll() - mqttPublishServer = null - } - if (timer != null) { - timer!!.cancel() - } - } + override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) { @@ -1225,4 +1243,48 @@ class HomeActivity : BaseActivityOaToolbarViewBinding() { } }) } + + private fun stringToList(strs: String): List { + val str = strs.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + return Arrays.asList(*str) + } + + private fun stringToListBlank(strs: String): List { + val str = strs.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + return Arrays.asList(*str) + } + + override fun onStart() { + super.onStart() + val gattServiceIntent = Intent(this, BluetoothLeService::class.java) + bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE) + } + + override fun onStop() { + super.onStop() + if(mBluetoothLeService!=null){ + unbindService(mServiceConnection) + } + } + + override fun onDestroy() { + super.onDestroy() + if (timerCheckServerConnectStatus != null) { + timerCheckServerConnectStatus?.cancel() + } + if (mqttPublishServer != null) { + mqttPublishServer!!.destroyAll() + mqttPublishServer = null + } + if (timer != null) { + timer!!.cancel() + } + mBluetoothLeService?.disconnect() + mBluetoothLeService?.close() + if(mBluetoothLeService!=null){ + unbindService(mServiceConnection) + } + val intent = Intent(this, BluetoothLeService::class.java) + stopService(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/BlueToothDeviceSdkActivity.java b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/BlueToothDeviceSdkActivity.java deleted file mode 100644 index d89c31a..0000000 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/BlueToothDeviceSdkActivity.java +++ /dev/null @@ -1,560 +0,0 @@ -package com.rehome.dywoa.ui.activity.sbxdjgl; - - -import android.Manifest; -import android.annotation.SuppressLint; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothManager; -import android.bluetooth.le.BluetoothLeScanner; -import android.bluetooth.le.ScanCallback; -import android.bluetooth.le.ScanResult; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.graphics.Color; -import android.os.Build; -import com.bjzc.blemanager.BluetoothLeService; -import android.os.Handler; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.activity.EdgeToEdge; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.graphics.Insets; -import androidx.core.view.ViewCompat; -import androidx.core.view.WindowInsetsCompat; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; - -//import com.clj.fastble.BleManager; -import com.bjzc.blemanager.BleManager; -import com.clj.fastble.callback.BleScanCallback; -import com.clj.fastble.data.BleDevice; -import com.clj.fastble.data.BleScanState; -import com.clj.fastble.scan.BleScanRuleConfig; -import com.google.gson.Gson; -import com.rehome.dywoa.Contans; -import com.rehome.dywoa.R; -import com.rehome.dywoa.adapter.XzjhAdapter; -import com.rehome.dywoa.base.BaseActivity; -import com.rehome.dywoa.utils.SPUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * 蓝牙扫描 - * https://developer.android.google.cn/develop/connectivity/bluetooth/ble/find-ble-devices?hl=zh-cn - */ -public class BlueToothDeviceSdkActivity extends BaseActivity { - - ListView lv; - TextView ble_status; - TextView ble_dianlang; - - private BluetoothAdapter mBluetoothAdapter; - private ArrayList mPermissionList = new ArrayList(); - private BluetoothLeScanner bluetoothLeScanner; - private boolean scanning=false; - private Handler handler = new Handler(); - - // Stops scanning after 10 seconds. - private static final long SCAN_PERIOD = 10000; - - //private LeDeviceListAdapter leDeviceListAdapter = new LeDeviceListAdapter(); - private LeDeviceListAdapter mLeDeviceListAdapter; - - private BleManager ble; - private int selectItem = -1; - private String cmd = ""; - private String str = ""; - - @Override - public int getContentViewID() { - return R.layout.activity_blue_tooth_device_sdk; - } - - @Override - public void initView() { - lv = findViewById(R.id.lv); - ble_status = findViewById(R.id.ble_status); - ble_dianlang = findViewById(R.id.ble_dianlang); - ble = BleManager.getInstance(); - str = ble.init(BlueToothDeviceSdkActivity.this); - showLog(str); - - ble.setOnReceiveListener(new BleManager.OnReceiveListener() { - @SuppressLint("SetTextI18n") - @Override - public void onShowMessage(Context context, Intent intent) { - final String action = intent.getAction(); - if (BluetoothDevice.ACTION_FOUND.equals(action)) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (ActivityCompat.checkSelfPermission(BlueToothDeviceSdkActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return; - } - showLog("扫描发现设备" + device.getName() + "," + device.getAddress()); - String deviceName = device.getName(); - if (deviceName != null && !deviceName.isEmpty()&&deviceName.startsWith("W3")){ - //showLog(new Gson().toJson(device)); - mLeDeviceListAdapter.addDevice(device); - mLeDeviceListAdapter.notifyDataSetChanged(); - } - } else if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { - showLog("连接"); - mLeDeviceListAdapter.setSelectItem(selectItem); - mLeDeviceListAdapter.notifyDataSetChanged(); - - BluetoothDevice device = mLeDeviceListAdapter.getDevice(selectItem); - String deviceName = device.getName(); - if (deviceName != null && !deviceName.isEmpty()){ - SPUtils.put(context, Contans.KEY_BLUE_TOOTH,device.getAddress()); - } - } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { - showLog("断开"); - } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { - showLog("数据传输通道准备就绪,可以发送数据了。"); - ble.write("BV", false); - cmd="BV"; - ble_status.setText("已连接"); - ble_status.setTextColor(Color.parseColor("#00FF7F"));//连接之后的颜色 - } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { - byte[] data= intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA); - String resultReceive = new String(data); - showLog("收到传感器数据" + resultReceive); - showLog(cmd); -// if("BV".equals(cmd)){ -// //showLog(resultReceive); -// ble_dianlang.setText(resultReceive+"%"); -// } - } - } - }); - - initToolbar("蓝牙传感器管理", "扫描蓝牙", new View.OnClickListener() { - @Override - public void onClick(View v) { - showLog("蓝牙数据管理"); - bleScan(); - } - }); - //BleManager.getInstance().init(getApplication()); - - - - - mLeDeviceListAdapter = new LeDeviceListAdapter(new LeDeviceListAdapter.CallBackBlueToothBind() { - - @Override - public void Click(int position) { - showLog(String.valueOf(position)); - BluetoothDevice device = mLeDeviceListAdapter.getDevice(position); - if (ActivityCompat.checkSelfPermission(BlueToothDeviceSdkActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return; - } - selectItem=position; - ble.connect(device.getAddress(),device.getName()); - } - }, new LeDeviceListAdapter.CallBackBlueToothSendData() { - @Override - public void Click(int position) { - //ble.write(String cmd, Boolean ishex) - //读固件版本号 - //ble.write("VR", false); - //读电量 - ble.write("BV", false); - cmd="BV"; - //温度测量 - //ble.write("0B0B6300", true); - //距离测量 - //ble.write("4453", true); - //转速测量 - //ble.write("0F3101", true); - //cmd="0F3101"; - //加速度测量 - //ble.write("1F11", true); - //速度测量。 - //ble.write("1F12", true); - //位移测量 - //ble.write("1F13", true); - - } - }); - lv.setAdapter(mLeDeviceListAdapter); - } - - private void bleScan(){ - mLeDeviceListAdapter.clear(); - mLeDeviceListAdapter.notifyDataSetChanged(); - selectItem = -1; - ble.disconnect(); - if("BLE is not supported".equals(str)){ - showToast("当前设备不支持低功耗蓝牙,无法连接传感器采集数据"); - } - if("Bluetooth not supported".equals(str)){ - showToast("当前设备不支持蓝牙功能"); - } - if("Bluetooth not enabled".equals(str)){ - showToast("蓝牙功能没有开启"); - } - if("ACCESS_COARSE_LOCATION permission denied".equals(str)){ - showToast("您未授权开启蓝牙扫描附近的设备,请先开启蓝牙权限"); - } - if("context is no Activity".equals(str)){ - showToast("Init(context)方法的参数必须是 Activity"); - } - if("OK".equals(str)){ - ble.scan(); - } - } - - @Override - public void initData() { - bleScan(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - ble.disconnect(); -// if(BleManager.getInstance().getScanSate()== BleScanState.STATE_SCANNING){ -// BleManager.getInstance().cancelScan(); -// } -// BleManager.getInstance().disconnectAllDevice(); -// BleManager.getInstance().destroy(); - } - - - private void initPermission(){ - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){ - // Android 版本大于等于 Android12 时 - // 只包括蓝牙这部分的权限,其余的需要什么权限自己添加 - mPermissionList.add(Manifest.permission.BLUETOOTH_SCAN); - mPermissionList.add(Manifest.permission.BLUETOOTH_ADVERTISE); - mPermissionList.add(Manifest.permission.BLUETOOTH_CONNECT); - } else { - // Android 版本小于 Android12 及以下版本 - mPermissionList.add(Manifest.permission.ACCESS_COARSE_LOCATION); - mPermissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); - } - showLog(new Gson().toJson(mPermissionList.toArray(new String[0]))); - ActivityCompat.requestPermissions(this,mPermissionList.toArray(new String[0]),1001); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - Log.i("app","onRequestPermissionsResult"); - Log.i("app",String.valueOf(grantResults.length)); - Log.i("app",new Gson().toJson(grantResults)); - boolean hasGrant = true; - for (int grantResult : grantResults) { - if (grantResult != 0) { - //未授权 - hasGrant = false; - break; - } - } - if(hasGrant){ - //已授权 - showToast("已授权低功耗蓝牙"); - BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); - mBluetoothAdapter = bluetoothManager.getAdapter(); - if (mBluetoothAdapter == null) { - Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); - }else{ - //可以开始扫描啦 - showLog("可以开始扫描啦"); - bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); - scanLeDevice(); - } - //scanLeDevice(true); - }else{ - showToast("您未授权开启蓝牙连接到Blue设备,请先开启权限"); - } - } - - - public void initBlueTooth() { -// boolean bluetoothAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); -// if(bluetoothAvailable){ -// showLog("传统蓝牙可用"); -// }else{ -// showLog("传统蓝牙不可用"); -// } - boolean bluetoothLEAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); - - if(bluetoothLEAvailable){ - showLog("低功耗蓝牙可用"); - initPermission(); - }else{ - showLog("低功耗蓝牙不可用"); - showToast("传感器必须使用低功耗蓝牙,当前设备不支持低功耗蓝牙"); - } - } - -// public void initBlueToothFastBle() { -// if(BleManager.getInstance().getScanSate()== BleScanState.STATE_SCANNING){ -// BleManager.getInstance().cancelScan(); -// } -// BleManager.getInstance() -// .enableLog(true) -// .setReConnectCount(1, 5000) -// .setSplitWriteNum(20) -// .setConnectOverTime(10000) -// .setOperateTimeout(5000); -// -// BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder() -// .setAutoConnect(true) -// .setScanTimeOut(10000) -// .build(); -// BleManager.getInstance().initScanRule(scanRuleConfig); -// -// BleManager.getInstance().scan(new BleScanCallback() { -// @Override -// public void onScanStarted(boolean success) { -// showToast("开始蓝牙扫描"); -// } -// -// @Override -// public void onScanning(BleDevice bleDevice) { - //// if (context != null && !BlueToothDeviceActivity.this.isFinishing() && !BlueToothDeviceActivity.this.isDestroyed()) { - //// showToast("发现设备"); - //// } -// BluetoothDevice device = bleDevice.getDevice(); -// if(device!=null){ -// if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { -// // TODO: Consider calling -// // ActivityCompat#requestPermissions -// // here to request the missing permissions, and then overriding -// // public void onRequestPermissionsResult(int requestCode, String[] permissions, -// // int[] grantResults) -// // to handle the case where the user grants the permission. See the documentation -// // for ActivityCompat#requestPermissions for more details. -// return; -// } -// String deviceName = device.getName(); -// if (deviceName != null && !deviceName.isEmpty()){ -// showLog(new Gson().toJson(device)); -// mLeDeviceListAdapter.addDevice(bleDevice.getDevice()); -// mLeDeviceListAdapter.notifyDataSetChanged(); -// } -// } -// } -// -// @Override -// public void onScanFinished(List scanResultList) { -// if (context != null && !BlueToothDeviceActivity.this.isFinishing() && !BlueToothDeviceActivity.this.isDestroyed()) { -// showToast("蓝牙扫描结束"); -// } -// showLog(String.valueOf(mLeDeviceListAdapter.getCount())); -// showLog(new Gson().toJson(scanResultList)); -// } -// }); -// } - - private void scanLeDevice() { - if (!scanning) { - // Stops scanning after a predefined scan period. - handler.postDelayed(new Runnable() { - @Override - public void run() { - scanning = false; - if (ActivityCompat.checkSelfPermission(BlueToothDeviceSdkActivity.this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - showToast("蓝牙扫描未授权"); - return; - } - bluetoothLeScanner.stopScan(leScanCallback); - } - }, SCAN_PERIOD); - scanning = true; - if (ActivityCompat.checkSelfPermission(BlueToothDeviceSdkActivity.this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - showToast("您未授权开启蓝牙连接到Blue设备,请先开启权限"); - return; - } - bluetoothLeScanner.startScan(leScanCallback); - } else { - scanning = false; - bluetoothLeScanner.stopScan(leScanCallback); - } - } - - private ScanCallback leScanCallback = new ScanCallback() { - @Override - public void onScanResult(int callbackType, ScanResult result) { - super.onScanResult(callbackType, result); - showToast("发现新设备啦"); - mLeDeviceListAdapter.addDevice(result.getDevice()); - mLeDeviceListAdapter.notifyDataSetChanged(); - } - }; - - private class LeDeviceListAdapter extends BaseAdapter { - private class ViewHolder { - TextView deviceName; - TextView deviceStatus; - TextView deviceBind; - TextView deviceDeBind; - TextView sendData; - } - - private ArrayList mLeDevices; - private LayoutInflater mInflator; - private LeDeviceListAdapter.CallBackBlueToothBind callBackBlueToothBind; - private LeDeviceListAdapter.CallBackBlueToothSendData callBackBlueToothSendData; - - public LeDeviceListAdapter(LeDeviceListAdapter.CallBackBlueToothBind callBackBlueToothBind, - LeDeviceListAdapter.CallBackBlueToothSendData callBackBlueToothSendData) { - super(); - mLeDevices = new ArrayList(); - mInflator = BlueToothDeviceSdkActivity.this.getLayoutInflater(); - this.callBackBlueToothBind=callBackBlueToothBind; - this.callBackBlueToothSendData=callBackBlueToothSendData; - } - - public interface CallBackBlueToothBind { - void Click(int position); - } - - public interface CallBackBlueToothSendData { - void Click(int position); - } - - public void addDevice(BluetoothDevice device) { - if (!mLeDevices.contains(device)) { - mLeDevices.add(device); - } - } - - public BluetoothDevice getDevice(int position) { - return mLeDevices.get(position); - } - - public void clear() { - mLeDevices.clear(); - } - - @Override - public int getCount() { - return mLeDevices.size(); - } - - @Override - public Object getItem(int i) { - return mLeDevices.get(i); - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public View getView(int i, View view, ViewGroup viewGroup) { - LeDeviceListAdapter.ViewHolder viewHolder; - if (view == null) { - view = mInflator.inflate(R.layout.listitem_device, null); - viewHolder = new LeDeviceListAdapter.ViewHolder(); - viewHolder.deviceName = view.findViewById(R.id.device_name); - viewHolder.deviceStatus = view.findViewById(R.id.device_status); - viewHolder.deviceBind = view.findViewById(R.id.device_bind); - viewHolder.sendData = view.findViewById(R.id.send_data); - view.setTag(viewHolder); - } else { - viewHolder = (LeDeviceListAdapter.ViewHolder) view.getTag(); - } - - BluetoothDevice device = mLeDevices.get(i); - if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return null; - } - String deviceName = device.getName(); - if (deviceName != null && !deviceName.isEmpty()) - viewHolder.deviceName.setText(deviceName); - else{ - viewHolder.deviceName.setText(R.string.unknown_device); - } - //当前点击选中的变色 - if (i == selectItem) { - viewHolder.deviceName.getPaint().setFakeBoldText(true); - //viewHolder.deviceName.setTextColor(Color.parseColor("#00FF7F"));//连接之后的颜色 - viewHolder.deviceStatus.setTextColor(Color.parseColor("#00FF7F"));//连接之后的颜色 - viewHolder.deviceStatus.setText("已连接"); - } else { - viewHolder.deviceName.getPaint().setFakeBoldText(false); - //viewHolder.deviceName.setTextColor(Color.parseColor("#00FF7F"));//连接之后的颜色 - viewHolder.deviceStatus.setTextColor(Color.parseColor("#000000")); - viewHolder.deviceStatus.setText("未绑定"); - } - viewHolder.deviceBind.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if(callBackBlueToothBind!=null){ - callBackBlueToothBind.Click(i); - } - } - }); - viewHolder.sendData.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if(callBackBlueToothSendData!=null){ - callBackBlueToothSendData.Click(i); - } - } - }); - - - - return view; - } - - public void setSelectItem(int selectItem) { - this.selectItem = selectItem; - } - - private int selectItem = -1; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java b/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java index eab9d62..4956dc0 100755 --- a/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java +++ b/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java @@ -38,6 +38,7 @@ import com.rehome.dywoa.bean.GridItem; import com.rehome.dywoa.bean.WaitForBean; import com.rehome.dywoa.bleUtil.BlueTestInfoActivity; import com.rehome.dywoa.bleUtil.BlueToothDeviceActivity; +import com.rehome.dywoa.bleUtil.BlueToothDeviceSdkActivity; import com.rehome.dywoa.ui.activity.BiShowActivity; import com.rehome.dywoa.ui.activity.EveryDateRiskControllerListActivity; import com.rehome.dywoa.ui.activity.FaceRecognitionAppActivity; @@ -477,7 +478,11 @@ public class HomeFragment extends BaseFragment { // intentBlueTestInfo.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); // startActivity(intentBlueTestInfo); - Intent intentBlueToothDevice = new Intent(mActivity, BlueToothDeviceActivity.class); +// Intent intentBlueToothDevice = new Intent(mActivity, BlueToothDeviceActivity.class); +// intentBlueToothDevice.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); +// startActivity(intentBlueToothDevice); + + Intent intentBlueToothDevice = new Intent(mActivity, BlueToothDeviceSdkActivity.class); intentBlueToothDevice.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intentBlueToothDevice); diff --git a/app/src/main/res/layout/activity_bluetoothlist.xml b/app/src/main/res/layout/activity_bluetoothlist.xml index ebf309d..b67b4d8 100644 --- a/app/src/main/res/layout/activity_bluetoothlist.xml +++ b/app/src/main/res/layout/activity_bluetoothlist.xml @@ -8,46 +8,80 @@ + android:gravity="center_vertical" + android:orientation="horizontal"> + android:gravity="center|start" + android:text="蓝牙传感器状态:" + android:textColor="#000000" + android:textSize="18sp" /> + android:gravity="center|start" + android:text="未连接" + android:layout_marginStart="10dp" + android:textColor="#ff0000" + android:textSize="15sp" /> + + + + android:gravity="center|start" + android:textColor="#000000" + android:text="蓝牙传感器电量:" + android:textSize="18sp" /> + - + android:layout_height="match_parent"> + + + + + diff --git a/app/src/main/res/layout/listitem_device.xml b/app/src/main/res/layout/listitem_device.xml index f19a911..2fdee18 100644 --- a/app/src/main/res/layout/listitem_device.xml +++ b/app/src/main/res/layout/listitem_device.xml @@ -84,7 +84,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:baselineAligned="false" - android:gravity="center_vertical" + android:gravity="center_vertical|end" android:minHeight="30dp" android:orientation="horizontal"> + android:textSize="15sp" /> 上一条 下一条 数据出错 - BLE is not supported - Bluetooth not supported. + 当前设备不支持低功耗蓝牙 + 当前设备不支持低功耗蓝牙或未开启蓝牙功能 不能识别的设备 检查内容[测温]: 检查内容[测振]: