479 lines
17 KiB
Java
479 lines
17 KiB
Java
package com.ckkj.water.index;
|
||
|
||
import android.Manifest;
|
||
import android.bluetooth.BluetoothAdapter;
|
||
import android.bluetooth.BluetoothManager;
|
||
import android.content.Context;
|
||
import android.content.Intent;
|
||
import android.content.pm.PackageManager;
|
||
import android.os.Build;
|
||
import android.os.Bundle;
|
||
import android.text.TextUtils;
|
||
import android.view.View;
|
||
|
||
import androidx.annotation.NonNull;
|
||
import androidx.annotation.Nullable;
|
||
import androidx.core.content.ContextCompat;
|
||
|
||
import com.ckkj.water.AppConfig;
|
||
import com.ckkj.water.R;
|
||
import com.ckkj.water.base.BaseFragment;
|
||
import com.ckkj.water.custom.view.CustomRefreshHeader;
|
||
import com.ckkj.water.databinding.IndexFragmentLayoutBinding;
|
||
import com.ckkj.water.ConstantUtil;
|
||
import com.ckkj.water.device.AddDeviceActivity;
|
||
import com.ckkj.water.device.DeviceControlActivity;
|
||
import com.ckkj.water.device.DeviceReNameActivity;
|
||
import com.ckkj.water.device.SelectWifiActivity;
|
||
import com.ckkj.water.index.adapter.DeviceAdapter;
|
||
import com.ckkj.water.index.entity.WaterDeviceEntity;
|
||
import com.ckkj.water.index.mvp.IndexContract;
|
||
import com.ckkj.water.index.mvp.IndexImpl;
|
||
import com.ckkj.water.index.mvp.IndexPresenter;
|
||
import com.ckkj.water.network.BaseBean;
|
||
import com.ckkj.water.permission.PermissionActivity;
|
||
import com.ckkj.water.utils.show.ToastUtil;
|
||
import com.maning.mlkitscanner.scan.MNScanManager;
|
||
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback;
|
||
import com.scwang.smart.refresh.footer.ClassicsFooter;
|
||
import com.scwang.smart.refresh.layout.api.RefreshHeader;
|
||
|
||
import org.json.JSONException;
|
||
import org.json.JSONObject;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
import pub.devrel.easypermissions.EasyPermissions;
|
||
|
||
public class IndexFragment extends BaseFragment<IndexFragmentLayoutBinding, IndexPresenter>
|
||
implements IndexContract.IndexView , EasyPermissions.PermissionCallbacks{
|
||
|
||
private DeviceAdapter deviceAdapter;
|
||
private List<WaterDeviceEntity> devList = new ArrayList<>();
|
||
private int mCurrentPage = 1;
|
||
|
||
// 扫码待配网设备
|
||
private WaterDeviceEntity pendingDeviceEntity = null;
|
||
|
||
// 蓝牙相关
|
||
private static final int REQUEST_EVENT_CODE_BLUETOOTH_PERMISSION = 10002;
|
||
private static final int REQUEST_ENABLE_BT = 10003;
|
||
private BluetoothAdapter bluetoothAdapter;
|
||
private boolean bluetoothReady = false;
|
||
|
||
@Override
|
||
protected void initArgs(Bundle bundle) {
|
||
}
|
||
|
||
@Override
|
||
protected void onResumeInitData() {
|
||
super.onResumeInitData();
|
||
if(AppConfig.USER_LOGIN){
|
||
showLoadingDialog();
|
||
mPresenter.getDevicesList(mCurrentPage);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void initData(@Nullable Bundle savedInstanceState) {
|
||
// 设置自定义刷新头
|
||
RefreshHeader header = new CustomRefreshHeader(mContext);
|
||
viewBinding.refresh.setRefreshHeader(header);
|
||
viewBinding.refresh.setRefreshFooter(new ClassicsFooter(mContext));
|
||
viewBinding.refresh.setOnRefreshListener(layout -> {
|
||
mCurrentPage = 1;
|
||
mPresenter.getDevicesList(mCurrentPage);
|
||
});
|
||
viewBinding.refresh.setOnLoadMoreListener(layout -> {
|
||
mCurrentPage++;
|
||
mPresenter.getDevicesList(mCurrentPage);
|
||
});
|
||
}
|
||
|
||
@Override
|
||
public IndexPresenter createPresenter() {
|
||
return new IndexPresenter(new IndexImpl());
|
||
}
|
||
|
||
@Override
|
||
protected void initView() {
|
||
super.initView();
|
||
setupRecyclerView();
|
||
initListener();
|
||
}
|
||
|
||
private void initListener() {
|
||
setClick(viewBinding.imgScan);
|
||
setClick(viewBinding.imgAdd);
|
||
setClick(viewBinding.includedNoresult.btnRefresh);
|
||
}
|
||
|
||
private void setClick(View view) {
|
||
view.setOnClickListener(this::onClick);
|
||
}
|
||
|
||
public void onClick(View v){
|
||
switch (v.getId()){
|
||
|
||
case R.id.img_scan:
|
||
if(checkBluetoothPermissions()){
|
||
//检测有无相机权限
|
||
String readPermission = Manifest.permission.CAMERA;
|
||
if(!hasRecordPermission(readPermission)){
|
||
getPermissionRequst(readPermission,
|
||
getString(R.string.permission_request_title),
|
||
getString(R.string.camera_permission_scan_desc),
|
||
REQUEST_EVENT_CODE_10001);
|
||
}else{
|
||
scanQrcode();
|
||
}
|
||
}else{
|
||
goTo(mContext, PermissionActivity.class,null);
|
||
}
|
||
|
||
break;
|
||
|
||
case R.id.img_add:
|
||
if(checkBluetoothPermissions()){
|
||
goTo(mContext, AddDeviceActivity.class,null);
|
||
}else{
|
||
goTo(mContext, PermissionActivity.class,null);
|
||
|
||
}
|
||
break;
|
||
|
||
case R.id.btn_refresh:
|
||
mCurrentPage = 1;
|
||
mPresenter.getDevicesList(mCurrentPage);
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void scanQrcode() {
|
||
//默认扫描
|
||
MNScanManager.startScan(mContext, new MNScanCallback() {
|
||
@Override
|
||
public void onActivityResult(int resultCode, Intent data) {
|
||
switch (resultCode) {
|
||
case MNScanManager.RESULT_SUCCESS:
|
||
ArrayList<String> results = data.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS);
|
||
|
||
if (results == null || results.isEmpty()) {
|
||
ToastUtil.showShort(mContext, "二维码内容不能为空");
|
||
return;
|
||
}
|
||
|
||
String scanContent = results.get(0);
|
||
if (TextUtils.isEmpty(scanContent)) {
|
||
ToastUtil.showShort(mContext, "二维码内容不能为空");
|
||
return;
|
||
}
|
||
|
||
JSONObject json;
|
||
try {
|
||
json = new JSONObject(scanContent);
|
||
} catch (JSONException e) {
|
||
ToastUtil.showShort(mContext, "二维码格式错误");
|
||
return;
|
||
}
|
||
try {
|
||
WaterDeviceEntity entity = new WaterDeviceEntity();
|
||
if(TextUtils.isEmpty(json.getString("mac"))
|
||
|| TextUtils.isEmpty(json.getString("name"))){
|
||
ToastUtil.showShort(mContext,"请扫描正确的二维码");
|
||
return;
|
||
}
|
||
entity.setMacAddress(json.getString("mac"));
|
||
entity.setDeviceName(json.getString("name"));
|
||
if(entity != null){
|
||
//这里拿到Mac地址,需要去服务器查询当前Mac的绑定状态
|
||
mPresenter.bindDeviceStatus(entity);
|
||
}
|
||
} catch (JSONException e) {
|
||
ToastUtil.showShort(mContext, "二维码格式错误");
|
||
return;
|
||
}
|
||
break;
|
||
case MNScanManager.RESULT_FAIL:
|
||
String resultError = data.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR);
|
||
break;
|
||
case MNScanManager.RESULT_CANCLE:
|
||
ToastUtil.showShort(mContext,"取消扫码");
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
private void setupRecyclerView() {
|
||
deviceAdapter = new DeviceAdapter(mContext,R.layout.index_device_list_item,devList);
|
||
viewBinding.rvDevices.setAdapter(deviceAdapter);
|
||
deviceAdapter.setOnItemClickListener((adapter, view, position) -> {
|
||
Bundle bundle = new Bundle();
|
||
bundle.putSerializable("device_info",devList.get(position));
|
||
goTo(mContext, DeviceControlActivity.class,bundle);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取设备列表成功
|
||
*/
|
||
@Override
|
||
public void getDeviceListSuccess(List<WaterDeviceEntity> list, int total) {
|
||
hideDialogLoading();
|
||
List<WaterDeviceEntity> pageList = list == null ? new ArrayList<>() : list;
|
||
if (mCurrentPage == 1) {
|
||
viewBinding.refresh.finishRefresh(300);
|
||
devList.clear(); // 只在刷新时清除
|
||
devList = pageList;
|
||
} else {
|
||
viewBinding.refresh.finishLoadMore(300);
|
||
devList.addAll(pageList);
|
||
}
|
||
deviceAdapter.setNewData(devList);
|
||
|
||
// 4. 判断是否还有更多数据
|
||
if (deviceAdapter.getItemCount() >= total || pageList.size() == 0) {
|
||
// 使用 post 延迟调用,避免内部状态冲突导致的循环调用
|
||
viewBinding.refresh.postDelayed(() -> viewBinding.refresh.setNoMoreData(true), 300);
|
||
viewBinding.relNoMore.setVisibility(View.VISIBLE); // 自定义底部提示"暂无更多数据"
|
||
} else {
|
||
viewBinding.refresh.setNoMoreData(false);
|
||
viewBinding.relNoMore.setVisibility(View.GONE);
|
||
}
|
||
|
||
// 5. 控制空布局和内容显示
|
||
if (deviceAdapter.getItemCount() != 0) {
|
||
viewBinding.refresh.setVisibility(View.VISIBLE);
|
||
viewBinding.relNoresult.setVisibility(View.GONE);
|
||
} else {
|
||
viewBinding.refresh.setVisibility(View.GONE);
|
||
viewBinding.relNoresult.setVisibility(View.VISIBLE);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 查询当前设备绑定状态
|
||
* @param entity
|
||
*/
|
||
@Override
|
||
public void queryDeviceBindStatusSuccess(WaterDeviceEntity entity) {
|
||
switch (entity.getBindDeviceStatus()){
|
||
|
||
case 200:
|
||
//该设备目前已经绑定了当前用户,直接跳转到设备控制页面
|
||
Bundle bundle = new Bundle();
|
||
bundle.putSerializable("device_info",entity.getBindDevice());
|
||
goTo(mContext, DeviceControlActivity.class,bundle);
|
||
break;
|
||
|
||
case 302:
|
||
// 这是一台没有在mqtt中注册的设备,需要通过蓝牙连接配网,(可理解为新设备,走蓝牙,配网)
|
||
// 先检查蓝牙权限和开启状态
|
||
|
||
|
||
checkBluetoothAndProceed();
|
||
break;
|
||
|
||
case 303:
|
||
//目前该设备,不属于该用户,需要提示解绑
|
||
showDialogtext(null,
|
||
false,
|
||
false,
|
||
getString(R.string.tip_text),
|
||
getString(R.string.device_binding_conflict_message),
|
||
"",
|
||
"",
|
||
new OnDialogClick() {
|
||
@Override
|
||
public void onCancelClick() {
|
||
}
|
||
|
||
@Override
|
||
public void onConfirmClick() {
|
||
}
|
||
});
|
||
break;
|
||
|
||
case 304:
|
||
//该设备目前在线,已经在mqtt注册,但是没有绑定用户,需要跳转到绑定页面
|
||
Bundle bundleNoBind = new Bundle();
|
||
bundleNoBind.putSerializable("ble_device_entity", entity.getBindDevice());
|
||
goTo(mContext, DeviceReNameActivity.class, bundleNoBind);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查蓝牙权限和开启状态,然后跳转配网
|
||
*/
|
||
private void checkBluetoothAndProceed() {
|
||
// 1. 检查蓝牙权限
|
||
if (!checkBluetoothPermissions()) {
|
||
return;
|
||
}
|
||
|
||
// 2. 检查蓝牙是否开启
|
||
if (!initBluetooth()) {
|
||
return;
|
||
}
|
||
|
||
// 3. 权限和状态都正常,跳转配网页面
|
||
goToDeviceProvisioning();
|
||
}
|
||
|
||
/**
|
||
* 检查蓝牙权限
|
||
*/
|
||
private boolean checkBluetoothPermissions() {
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||
String[] permissions = {
|
||
Manifest.permission.BLUETOOTH_SCAN,
|
||
Manifest.permission.BLUETOOTH_CONNECT,
|
||
Manifest.permission.ACCESS_FINE_LOCATION
|
||
};
|
||
if (!hasRecordPermission(permissions)) {
|
||
return false;
|
||
}
|
||
} else {
|
||
// Android 12 以下需要位置权限
|
||
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
|
||
!= PackageManager.PERMISSION_GRANTED) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 初始化蓝牙适配器并检查蓝牙是否开启
|
||
* @return true 表示蓝牙已开启,false 表示未开启或不支持
|
||
*/
|
||
private boolean initBluetooth() {
|
||
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
|
||
if (bluetoothManager != null) {
|
||
bluetoothAdapter = bluetoothManager.getAdapter();
|
||
}
|
||
|
||
if (bluetoothAdapter == null) {
|
||
ToastUtil.showShort(mContext, "设备不支持蓝牙");
|
||
return false;
|
||
}
|
||
|
||
if (!bluetoothAdapter.isEnabled()) {
|
||
// 蓝牙未开启,请求开启
|
||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
|
||
return false;
|
||
}
|
||
|
||
bluetoothReady = true;
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 跳转设备配网页面
|
||
*/
|
||
private void goToDeviceProvisioning() {
|
||
if (pendingDeviceEntity == null) {
|
||
ToastUtil.showShort(mContext, "设备信息异常");
|
||
return;
|
||
}
|
||
Bundle bundle = new Bundle();
|
||
bundle.putInt(ConstantUtil.ACTIVITY_NAVIGATE_FLAG, 100); // 100 = 来自扫码添加
|
||
bundle.putSerializable("ble_device_entity", pendingDeviceEntity);
|
||
goTo(mContext, SelectWifiActivity.class, bundle);
|
||
pendingDeviceEntity = null;
|
||
}
|
||
|
||
|
||
@Override
|
||
public void onDestroyView() {
|
||
super.onDestroyView();
|
||
}
|
||
|
||
@Override
|
||
public void onNetChange(int netModel) {
|
||
}
|
||
|
||
@Override
|
||
public void showError(String message) {
|
||
hideDialogLoading();
|
||
ToastUtil.showShort(mContext,message);
|
||
}
|
||
|
||
@Override
|
||
public void logOut(BaseBean bean) {
|
||
}
|
||
|
||
@Override
|
||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||
hidePermissionDialog();
|
||
// if (requestCode == REQUEST_EVENT_CODE_10001) {
|
||
// scanQrcode();
|
||
// } else if (requestCode == REQUEST_EVENT_CODE_BLUETOOTH_PERMISSION) {
|
||
// // 蓝牙权限获取成功,检查蓝牙状态
|
||
// if (initBluetooth()) {
|
||
// goToDeviceProvisioning();
|
||
// }
|
||
// }
|
||
}
|
||
|
||
@Override
|
||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||
hidePermissionDialog();
|
||
if (requestCode == REQUEST_EVENT_CODE_BLUETOOTH_PERMISSION) {
|
||
ToastUtil.showShort(mContext, "需要蓝牙权限才能添加设备");
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
|
||
hidePermissionDialog();
|
||
|
||
if (requestCode == REQUEST_EVENT_CODE_10001) {
|
||
// 相机权限回调
|
||
scanQrcode();
|
||
} else if (requestCode == REQUEST_EVENT_CODE_BLUETOOTH_PERMISSION) {
|
||
// 蓝牙权限回调
|
||
boolean allGranted = true;
|
||
for (int result : grantResults) {
|
||
if (result != PackageManager.PERMISSION_GRANTED) {
|
||
allGranted = false;
|
||
break;
|
||
}
|
||
}
|
||
if (allGranted) {
|
||
// 权限获取成功,检查蓝牙状态
|
||
if (initBluetooth()) {
|
||
goToDeviceProvisioning();
|
||
}
|
||
} else {
|
||
ToastUtil.showShort(mContext, "需要蓝牙权限才能添加设备");
|
||
}
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||
super.onActivityResult(requestCode, resultCode, data);
|
||
if (requestCode == REQUEST_ENABLE_BT) {
|
||
if (resultCode == -1) { // RESULT_OK
|
||
ToastUtil.showShort(mContext, "蓝牙已开启");
|
||
bluetoothReady = true;
|
||
if (pendingDeviceEntity != null) {
|
||
goToDeviceProvisioning();
|
||
}
|
||
} else {
|
||
ToastUtil.showShort(mContext, "请开启蓝牙以添加设备");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|