管灌系统巡查员智能手机App
1.优化订单列表框架,升级为viewPager2,提升性能。
2.添加收到新工单后的红点提醒。
3.修复查询数据为空时报错。
4.优化修改经纬度的流程。
5.修复mqtt的CLIENT_ID一致导致的连接错误。
6.修复收到新工单后点击消息通知栏跳转详情时不更新数据的bug。
16个文件已修改
2个文件已添加
1个文件已删除
575 ■■■■■ 已修改文件
app/src/main/AndroidManifest.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/assets/js/map.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/activity/MainActivity.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/activity/OrderDetailActivity.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/adapter/TabAdapter.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/bean/net/InsectionResult.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/fragment/OrderFragment.java 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/net/ApiManager.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/net/LongTypeAdapter.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/net/MqttManager.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/net/RetrofitClient.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/tool/InspectionUtils.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/utils/CommonKeyName.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/view/MyViewPager.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/ic_red_dot.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_main.xml 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_order.xml 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/strings.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml
@@ -102,7 +102,9 @@
            android:launchMode="singleTop">
        </activity>
        <activity android:name=".activity.OrderDetailActivity" />
        <activity android:name=".activity.OrderDetailActivity"
            android:launchMode="singleTop"
            />
        <activity android:name=".activity.OrderDealActivity" />
        <activity android:name=".activity.AddIssueActivity" />
        <activity android:name=".activity.IssueListActivity" />
app/src/main/assets/js/map.js
@@ -172,6 +172,8 @@
        if (!isShowCenterPin) {
            chageMarkerIcon(data);
            showWaterIntakeDetail(id);
        }else {
            showToast("当前正在修改选中取水口的经纬度,完成或退出后才可选择其他!");
        }
    }
@@ -203,9 +205,9 @@
        map.panTo(currentMarker.getLngLat());
    }
    //调安卓原生
    function showToast() {
    function showToast(data) {
        // 调用 JavaScript 接口对象的方法
        window.Android.showToast('Hello, Android!');
        window.Android.showToast(data);
    }
    // 判断两个坐标是否一致
    function isEqualsLngLat(data1, data2) {
@@ -328,7 +330,7 @@
        isShowCenterPin = true;
        map.addEventListener("moveend", mapMoveEnd);
        window.Android.refreshCenter(map.getCenter().getLng(), map.getCenter().getLat());
       return true;
    }
    //取消修改定位
    function cancelPin() {
app/src/main/java/com/dayu/pipirrapp/activity/MainActivity.java
@@ -3,6 +3,7 @@
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
@@ -27,7 +28,9 @@
import com.jeremyliao.liveeventbus.LiveEventBus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 首页
@@ -37,6 +40,8 @@
    private List<Fragment> fragments = new ArrayList<>();
    private long mExitTime;
    MqttManager mqttManager;
    private Map<String, String> workerIddata = new HashMap<>();
    private enum Tab {
        ORDER, MAP, MY
@@ -47,7 +52,6 @@
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(LayoutInflater.from(this));
        setContentView(binding.getRoot());
        setupFragments();
        initView();
        initTab();
@@ -73,7 +77,33 @@
                }
            }
        });
        //mq传来的消息
        LiveEventBus.get(CommonKeyName.MQTTData).observeForever(new Observer<Object>() {
            @Override
            public void onChanged(Object o) {
                workerIddata.put((String) o, (String) o);
                binding.redDotImg.setVisibility(View.VISIBLE);
            }
        });
        LiveEventBus.get(CommonKeyName.RedLotRefresh).observeForever(new Observer<Object>() {
            @Override
            public void onChanged(Object o) {
                if (o instanceof Boolean) {
                    if ((boolean) o) {
                        binding.redDotImg.setVisibility(View.GONE);
                        workerIddata.clear();
                    }
                } else if (o instanceof String) {
                    workerIddata.remove(o);
                    if (workerIddata.size() == 0) {
                        binding.redDotImg.setVisibility(View.GONE);
                    }
                }
            }
        });
        registNetCallBack();
    }
@@ -96,11 +126,11 @@
    }
    private void initTab() {
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(), fragments);
        TabAdapter adapter = new TabAdapter(this, fragments);
        binding.viewPager.setAdapter(adapter);
        binding.viewPager.setPagingEnabled(false);
        binding.viewPager.setCurrentItem(1, false); // 默认显示地图页
        binding.viewPager.setOffscreenPageLimit(fragments.size());
        binding.viewPager.setCurrentItem(1); // 默认显示地图页
    }
    @Override
app/src/main/java/com/dayu/pipirrapp/activity/OrderDetailActivity.java
@@ -1,5 +1,7 @@
package com.dayu.pipirrapp.activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
@@ -27,9 +29,11 @@
import com.dayu.pipirrapp.net.Constants;
import com.dayu.pipirrapp.net.subscribers.SubscriberListener;
import com.dayu.pipirrapp.tool.FullyGridLayoutManager;
import com.dayu.pipirrapp.utils.CommonKeyName;
import com.dayu.pipirrapp.utils.ToastUtil;
import com.dayu.pipirrapp.view.ConfirmDialog;
import com.dayu.pipirrapp.view.TitleBar;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.luck.picture.lib.decoration.GridSpacingItemDecoration;
import com.luck.picture.lib.utils.DensityUtil;
@@ -72,13 +76,22 @@
        super.onCreate(savedInstanceState);
        binding = ActivityOrderDetailBinding.inflate(LayoutInflater.from(this));
        setContentView(binding.getRoot());
        new TitleBar(this).setTitleText("工单详情").setLeftIco().setLeftIcoListening(v -> OrderDetailActivity.this.finish());
        initView();
        getData(this.getIntent());
    }
    void initView() {
        workOrderId = this.getIntent().getStringExtra("workOrderId");
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        getData(intent);
    }
    private void getData(Intent intent) {
        workOrderId = intent.getStringExtra("workOrderId");
        NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(workOrderId.hashCode());
        if (this.getIntent().hasExtra("proResultId")) {
            binding.orderDealLL.setVisibility(View.VISIBLE);
            proResultId = this.getIntent().getStringExtra("proResultId");
@@ -92,10 +105,11 @@
            this.finish();
            ToastUtil.showToastLong(this, "当前workOrderId为空");
        }
    }
    void initView() {
        binding.setItemclidk(OrderDetailActivity.this);
        mRecyclerView = binding.recyclerView;
        FullyGridLayoutManager manager = new FullyGridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false);
        mRecyclerView.setLayoutManager(manager);
@@ -122,58 +136,56 @@
            @Override
            public void onNext(BaseResponse<OrderDetailResult> t) {
                if (t.isSuccess()) {
                    if (t.isSuccess()) {
                        if (t.getContent() != null) {
                            OrderDetailResult orderDetailResult = t.getContent();
                            binding.setData(orderDetailResult);
                            if (!TextUtils.isEmpty(t.getContent().getProResultId()) && TextUtils.isEmpty(proResultId)) {
                                getHandleData(orderDetailResult.getProResultId());
                            }
                            ProResultStateId = orderDetailResult.getProResultStateId();
                            switch (ProResultStateId) {
                                case 0://未上报
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.black, null));
                                    binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_no_bg, null));
                                    binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color, null));
                                    binding.dealButton.setVisibility(View.VISIBLE);
                                    break;
                                case 1://已上报
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white, null));
                                    binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_wait_bg, null));
                                    binding.dealButton.setBackgroundColor(getResources().getColor(R.color.delete_color, null));
                                    binding.dealButton.setVisibility(View.VISIBLE);
                                    binding.dealButton.setText("删除处理结果");
                                    break;
                                case 2://已完成
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white, null));
                                    binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_finish_bg, null));
                                    binding.dealButton.setVisibility(View.GONE);
                                    break;
                                case 3://被驳回
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white, null));
                                    binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_reject_bg, null));
                                    binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color));
                                    binding.dealButton.setVisibility(View.VISIBLE);
                                    break;
                            }
                        } else {
                            ToastUtil.showToast(OrderDetailActivity.this, t.getMsg());
                    LiveEventBus.get(CommonKeyName.RedLotRefresh).post(workOrderId);
                    if (t.getContent() != null) {
                        OrderDetailResult orderDetailResult = t.getContent();
                        binding.setData(orderDetailResult);
                        if (!TextUtils.isEmpty(t.getContent().getProResultId()) && TextUtils.isEmpty(proResultId)) {
                            getHandleData(orderDetailResult.getProResultId());
                        }
                    } else if (t.DATA_NULL.equals(t.getCode())) {
                        //工单已被删除
                        ToastUtil.showToast(OrderDetailActivity.this, "订单已被删除!");
                        setResult(OrderFragment.RESULT_REFRESH);
                        OrderDetailActivity.this.finish();
                        ProResultStateId = orderDetailResult.getProResultStateId();
                        switch (ProResultStateId) {
                            case 0://未上报
                                binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.black, null));
                                binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_no_bg, null));
                                binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color, null));
                                binding.dealButton.setVisibility(View.VISIBLE);
                                break;
                            case 1://已上报
                                binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white, null));
                                binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_wait_bg, null));
                                binding.dealButton.setBackgroundColor(getResources().getColor(R.color.delete_color, null));
                                binding.dealButton.setVisibility(View.VISIBLE);
                                binding.dealButton.setText("删除处理结果");
                                break;
                            case 2://已完成
                                binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white, null));
                                binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_finish_bg, null));
                                binding.dealButton.setVisibility(View.GONE);
                                break;
                            case 3://被驳回
                                binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white, null));
                                binding.stateText.setBackground(ResourcesCompat.getDrawable(OrderDetailActivity.this.getResources(), R.drawable.order_state_reject_bg, null));
                                binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color));
                                binding.dealButton.setVisibility(View.VISIBLE);
                                break;
                        }
                    } else {
                        ToastUtil.showToast(OrderDetailActivity.this, t.getMsg());
                        OrderDetailActivity.this.finish();
                    }
                } else if (t.DATA_NULL.equals(t.getCode())) {
                    //工单已被删除
                    ToastUtil.showToast(OrderDetailActivity.this, "订单已被删除!");
                    setResult(OrderFragment.RESULT_REFRESH);
                    OrderDetailActivity.this.finish();
                } else {
                    ToastUtil.showToast(OrderDetailActivity.this, t.getMsg());
                    OrderDetailActivity.this.finish();
                }
            }
            @Override
app/src/main/java/com/dayu/pipirrapp/adapter/TabAdapter.java
@@ -1,8 +1,9 @@
package com.dayu.pipirrapp.adapter;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.List;
@@ -12,45 +13,25 @@
 * Time: 17:53
 * 备注:
 */
public class TabAdapter extends FragmentPagerAdapter {
public class TabAdapter extends FragmentStateAdapter {
    List<Fragment> mFragments;
    public TabAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
    public TabAdapter(FragmentActivity fragmentActivity, List<Fragment> fragments) {
        super(fragmentActivity);
        mFragments = fragments;
    }
    @NonNull
    @Override
    public Fragment getItem(int position) {
        // 返回与特定位置相关联的 Fragment
        // 在这里实例化和返回你的片段
    public Fragment createFragment(int position) {
        return mFragments.get(position);
    }
    @Override
    public int getCount() {
        // 返回片段的总数
        return 3; // 假设有三个标签
    }
    @Override
    public CharSequence getPageTitle(int position) {
        String text = "";
        switch (position) {
            case 0:
                text = "首页";
                break;
            case 1:
                text = "地图";
                break;
            case 2:
                text = "我的";
                break;
        }
        // 返回标签的标题
        return text;
    public int getItemCount() {
        return mFragments.size();
    }
}
app/src/main/java/com/dayu/pipirrapp/bean/net/InsectionResult.java
@@ -9,23 +9,24 @@
 */
public class InsectionResult {
    String inspectId;//巡检id
    String inspectorId;//巡检员id
    long inspectId;//巡检id
    long inspectorId;//巡检员id
    public long getInspectId() {
    public String getInspectId() {
        return inspectId;
    }
    public void setInspectId(long inspectId) {
    public void setInspectId(String inspectId) {
        this.inspectId = inspectId;
    }
    public long getInspectorId() {
    public String getInspectorId() {
        return inspectorId;
    }
    public void setInspectorId(long inspectorId) {
    public void setInspectorId(String inspectorId) {
        this.inspectorId = inspectorId;
    }
}
app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
@@ -17,7 +17,6 @@
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -38,7 +37,6 @@
import com.dayu.pipirrapp.bean.net.MarkerResult;
import com.dayu.pipirrapp.dao.DaoSingleton;
import com.dayu.pipirrapp.databinding.FragmentMapBinding;
import com.dayu.pipirrapp.tool.MyWebViewInterface;
import com.dayu.pipirrapp.net.ApiManager;
import com.dayu.pipirrapp.net.BaseResponse;
import com.dayu.pipirrapp.net.Constants;
@@ -46,6 +44,7 @@
import com.dayu.pipirrapp.observer.MapFragmenObserver;
import com.dayu.pipirrapp.tool.InspectionUtils;
import com.dayu.pipirrapp.tool.MarkerUtils;
import com.dayu.pipirrapp.tool.MyWebViewInterface;
import com.dayu.pipirrapp.utils.CommonData;
import com.dayu.pipirrapp.utils.CommonKeyName;
import com.dayu.pipirrapp.utils.DateUtils;
@@ -339,7 +338,6 @@
        MyLog.i(data);
        MarkerBean markerBean = markerBeanSet.get(data);
        if (markerBean != null) {
            setWebViewParams(false);
            getInstakeDetail(markerBean);
        }
@@ -398,6 +396,7 @@
                try {
                    if (t.isSuccess()) {
                        if (t.getContent() != null) {
                            MyLog.d("InspectId:" + String.valueOf(t.getContent().get(0).getInspectId()));
                            mInspectionBean.setInspectId(String.valueOf(t.getContent().get(0).getInspectId()));
                            InspectionUtils.upataInspectionData(MapFragment.this.getContext(), mInspectionBean);
                        }
@@ -429,6 +428,7 @@
                    lastLatLonBean = latLonBean;
                    Log.i("chageInspecState", "lat:" + latLonBean.getLatitude() + ",log:" + latLonBean.getLongitude());
                    InspectionLocationBean inspectionLocationBean = InspectionUtils.createInspectionLocation(latLonBean, mInspectionBean);
                    //添加巡检记录坐标
                    InspectionUtils.addInspectionLocationData(MapFragment.this.getContext(), inspectionLocationBean);
                    //更新到地图
                    mWebView.evaluateJavascript("javascript:updateInspectionLocation(\"" + latLonBean.getLongitude() + "\",\"" + latLonBean.getLatitude() + "\")", value -> {
@@ -577,7 +577,7 @@
     */
    private void startLocation() {
        //获取定位服务传过来的坐标点
        LiveEventBus.get(CommonKeyName.locationData).observeForever(locationObserver);
        LiveEventBus.get(CommonKeyName.locationData).observe(this, locationObserver);
        binding.inspectRL.setVisibility(View.VISIBLE);
        binding.inspectButton.setVisibility(View.GONE);
        binding.inspectPause.setText("暂停");
@@ -726,17 +726,20 @@
        binding.lng.setText(markerBean.getLng());
        //修改经纬度
        binding.editePoint.setOnClickListener(v -> {
            mWebView.evaluateJavascript("javascript:showPin(\"" + markerBean.getLng() + "\",\"" + markerBean.getLat() + "\")", value -> {
                binding.pointRL.setVisibility(View.VISIBLE);
                binding.pointCenterImg.setVisibility(View.VISIBLE);
                MyLog.d("showPin>>" + value);
            });
            binding.pointRL.setVisibility(View.VISIBLE);
            binding.pointCenterImg.setVisibility(View.VISIBLE);
            setWebViewParams(true);
        });
        //取消修改经纬度
        binding.pointCancel.setOnClickListener(v -> {
                    binding.pointCenterImg.setVisibility(View.GONE);
                    binding.pointRL.setVisibility(View.GONE);
                    mWebView.evaluateJavascript("javascript:cancelPin()", value -> {
                    });
                }
        );
@@ -750,14 +753,11 @@
        });
    }
    private void setWebViewParams(boolean isAbove) {
        RelativeLayout.LayoutParams paramsAnotherView = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT);
        if (isAbove) {
            paramsAnotherView.addRule(RelativeLayout.ABOVE, binding.bottomLL.getId());
        }
        binding.webViewRL.setLayoutParams(paramsAnotherView);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        LiveEventBus.get(CommonKeyName.locationData).removeObserver(locationObserver);
    }
}
app/src/main/java/com/dayu/pipirrapp/fragment/OrderFragment.java
@@ -1,7 +1,13 @@
package com.dayu.pipirrapp.fragment;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -12,6 +18,7 @@
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -19,6 +26,7 @@
import com.dayu.pipirrapp.R;
import com.dayu.pipirrapp.activity.OrderDetailActivity;
import com.dayu.pipirrapp.adapter.OrderAdapter;
import com.dayu.pipirrapp.bean.net.OrderDetailResult;
import com.dayu.pipirrapp.bean.net.OrderListResult;
import com.dayu.pipirrapp.databinding.FragmentOrderBinding;
import com.dayu.pipirrapp.net.ApiManager;
@@ -26,6 +34,7 @@
import com.dayu.pipirrapp.net.Constants;
import com.dayu.pipirrapp.net.subscribers.SubscriberListener;
import com.dayu.pipirrapp.utils.CommonKeyName;
import com.dayu.pipirrapp.utils.MyLog;
import com.dayu.pipirrapp.utils.ToastUtil;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.scwang.smart.refresh.footer.ClassicsFooter;
@@ -33,6 +42,7 @@
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -45,7 +55,7 @@
 */
public class OrderFragment extends BaseFragment {
    public static final int RESULT_REFRESH = 1001;
    private static final String CHANNEL_ID = "order_channel";
    private final int STATE_DONE = 2;
    private final int STATE_UNDONE = 1;
@@ -58,6 +68,11 @@
    List<OrderListResult.Data> recordsListDone = new ArrayList<>();
    List<OrderListResult.Data> recordsList = new ArrayList<>();
    RefreshLayout myRefreshLayout;
    //最后刷新的时间
    long lastRefreshDate;
    //显示红点的时间
    long showRedlotDate;
    private ActivityResultLauncher<Intent> activityResultLauncher =
            registerForActivityResult(
@@ -98,7 +113,9 @@
        LiveEventBus.get(CommonKeyName.MQTTData).observeForever(new Observer<Object>() {
            @Override
            public void onChanged(Object o) {
                showRedlotDate = new Date().getTime();
                binding.redDotImg.setVisibility(View.VISIBLE);
                getMarkerData((String) o);
            }
        });
        return binding.getRoot();
@@ -124,6 +141,12 @@
        myRefreshLayout.setOnRefreshListener(refreshlayout -> {
//                refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败
            lastRefreshDate = new Date().getTime();
            if (lastRefreshDate > showRedlotDate) {
                //消除红点
                LiveEventBus.get(CommonKeyName.RedLotRefresh).post(true);
                binding.redDotImg.setVisibility(View.GONE);
            }
            recordsList.clear();
            page = 0;
            getMarkerData(refreshlayout, true, STATE_UNDONE);
@@ -161,8 +184,20 @@
    @Override
    public void onStart() {
        super.onStart();
    public void onResume() {
        super.onResume();
        MyLog.d("OrderFragment>>onResume");
        if (showRedlotDate > lastRefreshDate) {
            binding.redDotImg.setVisibility(View.VISIBLE);
        } else {
            binding.redDotImg.setVisibility(View.GONE);
        }
    }
    @Override
    public void onPause() {
        super.onPause();
        MyLog.d("OrderFragment>>onPause");
    }
    /**
@@ -239,20 +274,20 @@
    void chooseStateView(boolean state) {
        if (state) {
            binding.manageStateProgress.setTextColor(getResources().getColor(R.color.title_color,null));
            binding.manageStateProgress.setBackground(getResources().getDrawable(R.drawable.ic_choose_bg_whit,null));
            binding.manageStateProgress.setTextColor(getResources().getColor(R.color.title_color, null));
            binding.manageStateProgress.setBackground(getResources().getDrawable(R.drawable.ic_choose_bg_whit, null));
            binding.manageStateProgress.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
            binding.manageStateFinish.setTextColor(getResources().getColor(R.color.black,null));
            binding.manageStateFinish.setBackground(getResources().getDrawable(R.color.title_choose_bg,null));
            binding.manageStateFinish.setTextColor(getResources().getColor(R.color.black, null));
            binding.manageStateFinish.setBackground(getResources().getDrawable(R.color.title_choose_bg, null));
            binding.manageStateFinish.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
            binding.refreshLayout.setVisibility(View.VISIBLE);
            binding.refreshLayoutDone.setVisibility(View.GONE);
        } else {
            binding.manageStateFinish.setTextColor(getResources().getColor(R.color.title_color,null));
            binding.manageStateFinish.setBackground(getResources().getDrawable(R.drawable.ic_choose_bg_whit,null));
            binding.manageStateFinish.setTextColor(getResources().getColor(R.color.title_color, null));
            binding.manageStateFinish.setBackground(getResources().getDrawable(R.drawable.ic_choose_bg_whit, null));
            binding.manageStateFinish.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
            binding.manageStateProgress.setTextColor(getResources().getColor(R.color.black,null));
            binding.manageStateProgress.setBackground(getResources().getDrawable(R.color.title_choose_bg,null));
            binding.manageStateProgress.setTextColor(getResources().getColor(R.color.black, null));
            binding.manageStateProgress.setBackground(getResources().getDrawable(R.color.title_choose_bg, null));
            binding.manageStateProgress.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
            binding.refreshLayout.setVisibility(View.GONE);
            binding.refreshLayoutDone.setVisibility(View.VISIBLE);
@@ -260,4 +295,57 @@
    }
    /**
     * 创建工单提示通知
     *
     * @param notifucId
     * @param data
     */
    private void creatOrderNotification(int notifucId, String data, String workOrderId) {
        NotificationManager notificationManager = (NotificationManager) requireContext().getSystemService(Context.NOTIFICATION_SERVICE);
        // 创建NotificationChannel(仅针对Android O及以上版本)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            // 注册通道
            notificationManager.createNotificationChannel(channel);
        }
        Intent notificationIntent = new Intent(this.getContext(), OrderDetailActivity.class);
        notificationIntent.putExtra("workOrderId", workOrderId);
        int requestCode = workOrderId.hashCode(); // 使用workOrderId的哈希码作为requestCode
        PendingIntent pendingIntent = PendingIntent.getActivity(this.getContext(), requestCode, notificationIntent, PendingIntent.FLAG_MUTABLE);
        Notification notification = new NotificationCompat.Builder(this.getContext(), CHANNEL_ID)
                .setContentTitle("新工单")
                .setContentText(data)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true) // 点击通知后自动消失
                .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)// 使用默认的音效和震动
                .build();
        notificationManager.notify(notifucId, notification);
    }
    /**
     * 获取工单详情
     */
    private void getMarkerData(String workOrderId) {
        Map<String, Object> params = new HashMap<>();
        params.put("workOrderId", workOrderId);
        ApiManager.getInstance().requestGetHideLoading(this.getContext(), Constants.BASE_URL + "/app/workOrder/getOneWorkOrder", OrderDetailResult.class, params, new SubscriberListener<BaseResponse<OrderDetailResult>>() {
            @Override
            public void onNext(BaseResponse<OrderDetailResult> t) {
                if (t.isSuccess()) {
                    if (t.isSuccess()) {
                        creatOrderNotification(workOrderId.hashCode(), t.getContent().getTaskType(), workOrderId);
                    }
                }
            }
        });
    }
}
app/src/main/java/com/dayu/pipirrapp/net/ApiManager.java
@@ -190,6 +190,8 @@
        }
    }
    /**
     * 获取天气
     *
app/src/main/java/com/dayu/pipirrapp/net/LongTypeAdapter.java
New file
@@ -0,0 +1,33 @@
package com.dayu.pipirrapp.net;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import java.lang.reflect.Type;
/**
 * LongTypeAdapter -
 *
 * @author zuoxiao
 * @version 1.0
 * @since 2024-12-19
 */
public class LongTypeAdapter implements JsonDeserializer<String> {
    @Override
    public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json.isJsonPrimitive()) {
            JsonPrimitive primitive = json.getAsJsonPrimitive();
            // 如果是长数字则手动转为 Long
            if (primitive.isNumber()) {
                String numberStr = primitive.getAsString();
                return Long.parseLong(numberStr) + "";  // 强制转换为 long 类型
            }
        }
        return null;
    }
}
app/src/main/java/com/dayu/pipirrapp/net/MqttManager.java
@@ -1,6 +1,8 @@
package com.dayu.pipirrapp.net;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import androidx.lifecycle.LifecycleOwner;
@@ -22,6 +24,7 @@
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -36,7 +39,7 @@
    //    private static final String MQTT_BROKER_URL = "tcp://115.236.153.170:30764"; // 修改为你的 broker 地址
    private static final String MQTT_BROKER_URL = "tcp://192.168.10.52:1883";
    private static final String CLIENT_ID = "mqttx_a7a9fe73";
    private String CLIENT_ID = "mqttx_a7a9fe73";
    private static final String TOPIC = "workOrder"; // 订阅的主题
    private MqttClient mqttClient;
@@ -44,10 +47,18 @@
    boolean isHasNet = true;
    //是否连接成功过一次,没有的话联网后重连
    boolean isConnet = false;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();
    private final ExecutorService executorService = Executors.newSingleThreadExecutor();
    public MqttManager(Context context, LifecycleOwner lifecycleOwner) {
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo info = null;
            try {
                info = manager.getPackageInfo(context.getPackageName(), 0);
            } catch (PackageManager.NameNotFoundException e) {
                throw new RuntimeException(e);
            }
            CLIENT_ID = context.getPackageName() + UUID.randomUUID().toString().replace("-", "") + "_" + info;
            mqttClient = new MqttClient(MQTT_BROKER_URL, CLIENT_ID, new MemoryPersistence());
            connectOptions = new MqttConnectOptions();
            connectOptions.setUserName("mqtt_yjy");
@@ -142,10 +153,10 @@
                // 在子线程收到消息时的处理逻辑
                Log.d("MqttManager", "subscribe收到消息:" + new String(message.getPayload()));
                //传递MQ收到的信息
                HashMap<String, Object> data= MyJsonParser.getMapFromJson(new String(message.getPayload()));
                HashMap<String, Object> data = MyJsonParser.getMapFromJson(new String(message.getPayload()));
                //判断是否是当前用户
                if (data.get("inspectorId").equals(MyApplication.myApplication.userId)){
                    LiveEventBus.get(CommonKeyName.MQTTData).post(message.getPayload());
                if (data.get("inspectorId").equals(MyApplication.myApplication.userId)) {
                    LiveEventBus.get(CommonKeyName.MQTTData).post(data.get("workOrderId"));
                }
            });
app/src/main/java/com/dayu/pipirrapp/net/RetrofitClient.java
@@ -1,7 +1,6 @@
package com.dayu.pipirrapp.net;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
@@ -37,11 +36,17 @@
        //添加日志拦截器
        //添加数据请求统一处理拦截器
//        if (BuildConfig.DEBUG) {
            builder.addInterceptor(loggingInterceptor);
        builder.addInterceptor(loggingInterceptor);
//        }
        OkHttpClient client = builder.build();
//        // 创建GsonBuilder并设置长整型序列化策略为字符串
//        GsonBuilder gsonBuilder = new GsonBuilder();
//        gsonBuilder.registerTypeAdapter(String.class, new LongTypeAdapter());
//        gsonBuilder.registerTypeAdapter(long.class, new LongTypeAdapter());  // 如果是 long 类型的基本数据类型,也需要注册
//        gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING);
////         创建Gson实例
//        Gson gson = gsonBuilder.create();
        retrofit = new Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
app/src/main/java/com/dayu/pipirrapp/tool/InspectionUtils.java
@@ -142,19 +142,21 @@
                .subscribe(strings -> {
                    //循环查询所有id
                    for (String data : strings) {
                        DaoSingleton.getAsynchInstance(context).inspectionDao().findBymInspectId(data)
                                .subscribeOn(Schedulers.io())
                                .observeOn(Schedulers.io())
                                .subscribe(inspectionBeans -> {
                                    DaoSingleton.getAsynchInstance(context).inspectionLocationDao().findByNoPostAndInspectId(data)
                                            .subscribeOn(Schedulers.io())
                                            .observeOn(Schedulers.io())
                                            .subscribe(inspectionLocationBeans -> {
                                                if (inspectionLocationBeans != null && inspectionLocationBeans.size() > 0) {
                                                    postInspectionData(context, inspectionBeans, inspectionLocationBeans);
                                                }
                                            });
                                });
                        if (!TextUtils.isEmpty(data)) {
                            DaoSingleton.getAsynchInstance(context).inspectionDao().findBymInspectId(data)
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(Schedulers.io())
                                    .subscribe(inspectionBeans -> {
                                        DaoSingleton.getAsynchInstance(context).inspectionLocationDao().findByNoPostAndInspectId(data)
                                                .subscribeOn(Schedulers.io())
                                                .observeOn(Schedulers.io())
                                                .subscribe(inspectionLocationBeans -> {
                                                    if (inspectionLocationBeans != null && inspectionLocationBeans.size() > 0) {
                                                        postInspectionData(context, inspectionBeans, inspectionLocationBeans);
                                                    }
                                                });
                                    });
                        }
                    }
                });
app/src/main/java/com/dayu/pipirrapp/utils/CommonKeyName.java
@@ -23,4 +23,7 @@
    public final static String NetworkCallback = "NetworkCallback";
    //刷新新工单小红点
    public final static String RedLotRefresh="RedLotRefresh";
}
app/src/main/java/com/dayu/pipirrapp/view/MyViewPager.java
File was deleted
app/src/main/res/drawable/ic_red_dot.xml
New file
@@ -0,0 +1,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#FF0000" />
    <size
        android:width="5dp"
        android:height="5dp" />
</shape>
app/src/main/res/layout/activity_main.xml
@@ -7,7 +7,7 @@
    tools:context="com.dayu.pipirrapp.activity.MainActivity">
    <com.dayu.pipirrapp.view.MyViewPager
    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
@@ -33,12 +33,27 @@
            android:gravity="center"
            android:orientation="vertical">
            <ImageView
                android:id="@+id/orderImg"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:layout_marginTop="8dp"
                android:src="@drawable/bottom_order_black" />
            <RelativeLayout
                android:layout_width="25dp"
                android:layout_height="33dp">
                <ImageView
                    android:id="@+id/orderImg"
                    android:layout_width="wrap_content"
                    android:layout_height="25dp"
                    android:layout_marginTop="8dp"
                    android:src="@drawable/bottom_order_black" />
                <ImageView
                    android:id="@+id/red_dot_img"
                    android:layout_width="9dp"
                    android:layout_height="9dp"
                    android:layout_alignParentRight="true"
                    android:layout_marginTop="8dp"
                    android:src="@drawable/ic_red_dot"
                    android:visibility="gone" />
            </RelativeLayout>
            <TextView
                android:id="@+id/orderText"
app/src/main/res/layout/fragment_order.xml
@@ -148,22 +148,40 @@
            android:background="@drawable/top_state_bg"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/manage_state_progress"
                android:layout_width="wrap_content"
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/ic_choose_bg_whit"
                android:gravity="center"
                android:text="未完成"
                android:textColor="@color/title_color"
                android:textSize="@dimen/top_state_text_size"
                android:textStyle="bold" />
                android:background="@drawable/ic_choose_bg_whit">
                <TextView
                    android:id="@+id/manage_state_progress"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:layout_centerVertical="true"
                    android:gravity="center"
                    android:text="未完成"
                    android:textColor="@color/title_color"
                    android:textSize="@dimen/top_state_text_size"
                    android:textStyle="bold" />
                <ImageView
                    android:id="@+id/red_dot_img"
                    android:layout_width="9dp"
                    android:layout_height="9dp"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="5dp"
                    android:layout_toEndOf="@+id/manage_state_progress"
                    android:src="@drawable/ic_red_dot"
                    android:visibility="gone" />
            </RelativeLayout>
            <TextView
                android:id="@+id/manage_state_finish"
                android:layout_width="wrap_content"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:layout_weight="1"
app/src/main/res/values/strings.xml
@@ -1,3 +1,5 @@
<resources>
    <string name="app_name">巡检系统</string>
    <string name="channel_name">消息</string>
    <string name="channel_description">工单提醒</string>
</resources>