package com.weishitechsub.kdcxqwb.fragment.home;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.hfd.common.base.BaseActivity;
import com.weishitechsub.kdcxqwb.R;
import com.weishitechsub.kdcxqwb.bean.DeliverySearchResultBean;
import com.weishitechsub.kdcxqwb.bean.ListBean;
import com.weishitechsub.kdcxqwb.fragment.Adapter.MyCourierAdapter;
import com.weishitechsub.kdcxqwb.utils.JsonUtils;
import com.weishitechsub.kdcxqwb.utils.OnMultiClickListener;
import com.weishitechsub.kdcxqwb.utils.ReminderManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class MyCourierActivity extends BaseActivity {
TextView tv_back;
RecyclerView rv;
private MyCourierAdapter myCourierAdapter;
private List<ListBean> listBeans;
private List<DeliverySearchResultBean.DataDTO> deliveryList;
private String state;
@Override
protected int setLayout() {
return R.layout.activity_my_courier;
}
@Override
protected void setView() {
rv = fvbi(R.id.rv);
tv_back = fvbi(R.id.tv_back);
}
@Override
protected void setData() {
Bundle intent = getIntent().getExtras();
if (intent != null) {
String com = intent.getString("com");
String num = intent.getString("num");
String context = intent.getString("context");
state = intent.getString("state");
String type = intent.getString("type");
deliveryList = (List<DeliverySearchResultBean.DataDTO>) intent.getSerializable("deliveryList");
Log.i("deliveryList","======"+deliveryList.get(0).context);
listBeans = new ArrayList<>();
listBeans.add(new ListBean(com,num,context, state,type));
}
myCourierAdapter = new MyCourierAdapter(listBeans,MyCourierActivity.this);
myCourierAdapter.setTrackList(parseCourierJson());
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(myCourierAdapter);
rv.setNestedScrollingEnabled(false);
myCourierAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
Bundle bundle = new Bundle();
bundle.putSerializable("deliveryList", (Serializable) deliveryList);
// bundle.putString("state",state);
toClass(QueryResultsActivity.class,bundle);
}
});
ReminderManager.getInstance(this).setCurrentCourierList(listBeans);
// 启动时从 SP 恢复提醒开关状态
myCourierAdapter.loadSavedStates();
}
@Override
protected void setClick() {
tv_back.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
finish();
}
});
}
private List<ListBean> parseCourierJson() {
String jsonString = JsonUtils.loadJSONFromAsset(mContext.getAssets(), "delivery_list.json");
List<ListBean> couriers = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(jsonString);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
String title = item.getString("title");
String des = item.getString("des");
String value = item.getString("value");
couriers.add(new ListBean(title,value,"","",""));
}
} catch (JSONException e) {
e.printStackTrace();
}
return couriers;
}
@Override
protected void onPause() {
super.onPause();
// 退出前保存当前所有提醒状态
// myCourierAdapter.saveAllStates();
}
public List<ListBean> getCurrentCourierList() {
return listBeans;
}
public MyCourierAdapter getMainCourierAdapter() {
return myCourierAdapter;
}
}package com.weishitechsub.kdcxqwb.fragment.Adapter;
import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.weishitechsub.kdcxqwb.R;
import com.weishitechsub.kdcxqwb.bean.ListBean;
import com.weishitechsub.kdcxqwb.utils.PackageNotificationSender;
import com.weishitechsub.kdcxqwb.utils.ReminderManager;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class MyCourierAdapter extends BaseQuickAdapter<ListBean, BaseViewHolder> {
private static final String TAG = "MyCourierAdapter";
private List<ListBean> mTrackList;
private Context context;
// 存储:用户手动开启了提醒的单号
private final Set<String> remindedEnabled = ConcurrentHashMap.newKeySet();
// 存储:每个单号最后一次被提醒到的状态(用于去重)
private final Map<String, String> remindedStates = new ConcurrentHashMap<>();
private Handler mainHandler = new Handler(Looper.getMainLooper());
private static final String PREF_NAME = "courier_reminder";
// 缓存当前列表数据,用于根据单号查找最新状态
private List<ListBean> currentList;
public MyCourierAdapter(List<ListBean> list, Context context) {
super(R.layout.my_courier_adapter, list);
this.context = context;
ReminderManager.getInstance(context); // 初始化单例
}
@Override
protected void convert(@NonNull BaseViewHolder baseViewHolder, ListBean dataBean) {
String number = dataBean.getNum();
baseViewHolder.setText(R.id.tv_number, number);
baseViewHolder.setText(R.id.tv_address, dataBean.getContext());
// 设置快递公司信息和图标
if (dataBean.getType() != null) {
String trackName = getTrackName(dataBean.getType());
baseViewHolder.setText(R.id.tv_type, trackName);
ImageView logo = baseViewHolder.getView(R.id.iv_logo);
LinearLayout line = baseViewHolder.getView(R.id.line);
setCompanyLogo(trackName, logo, line);
}
// ===== 核心逻辑:状态变更检测 + 条件性通知 =====
String state = dataBean.getState();
if (state != null) {
baseViewHolder.setText(R.id.tv_state, getStateText(state));
// === 如果是终止状态,自动关闭提醒并记录最终状态 ===
if ("3".equals(state) || "4".equals(state) || "6".equals(state)) {
remindedEnabled.remove(number);
remindedStates.put(number, state);
}
// 只有在【用户开启了提醒】的前提下才进行通知
if (remindedEnabled.contains(number)) {
String oldState = remindedStates.get(number);
// 状态变化时发送通知(排除首次)
if (oldState != null && !state.equals(oldState)) {
String company = getTrackName(dataBean.getType());
sendStatusNotification(number, company, getStateText(state), getNotifyContent(state));
}
// 更新最后提醒状态
remindedStates.put(number, state);
}
}
ImageView ivRemind = baseViewHolder.getView(R.id.iv_remind);
// 每次绑定时刷新图标(根据最新状态)
boolean isCurrentlyReminded = ReminderManager.getInstance(context).isReminded(number);
refreshRemindIcon(ivRemind, isCurrentlyReminded);
// 终止状态不可操作
if ("3".equals(state) || "4".equals(state) || "6".equals(state)) {
ivRemind.setOnClickListener(v -> {
String tip = "3".equals(state) ? "该快递已签收,无需提醒。"
: "4".equals(state) ? "该快递已拒签,订单结束。"
: "该快递已被退回。";
Toast.makeText(context, tip, Toast.LENGTH_SHORT).show();
});
ivRemind.setEnabled(false);
ivRemind.setAlpha(0.5f);
} else {
ivRemind.setEnabled(true);
ivRemind.setAlpha(1.0f);
// 不要用外部变量 isReminded!每次点击都查一遍
ivRemind.setOnClickListener(v -> {
boolean nowEnabled = ReminderManager.getInstance(context).isReminded(number);
if (nowEnabled) {
// 当前已开启 → 执行关闭
ReminderManager.getInstance(context).disableReminder(number);
Toast.makeText(context, "已关闭提醒: " + number, Toast.LENGTH_SHORT).show();
} else {
// 当前已关闭 → 尝试开启(权限检查 + 提醒)
enableReminderWithPermissionCheck(dataBean);
}
// 强制刷新图标
refreshRemindIcon(ivRemind, !nowEnabled);
// 可选:通知数据变化,防止列表错乱
// notifyItemChanged(getDataSource().indexOf(dataBean));
});
}
}
// 检查权限后开启提醒,并发送“当前状态”的通知
private void enableReminderWithPermissionCheck(ListBean dataBean) {
String number = dataBean.getNum();
String state = dataBean.getState();
String type = dataBean.getType();
// 权限检查...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
showNotificationPermissionDialog();
return;
}
}
// 启用提醒(自动保存到 SP)
ReminderManager.getInstance(context).enableReminder(number);
Toast.makeText(context, "已开启提醒: " + number, Toast.LENGTH_SHORT).show();
// 发送欢迎通知
String companyName = getTrackName(type);
sendStatusNotification(number, companyName, getStateText(state), getNotifyContent(state));
}
// 刷新提醒按钮图标
private void refreshRemindIcon(ImageView ivRemind, boolean isEnabled) {
if (isEnabled) {
ivRemind.setImageResource(R.mipmap.button_on); // 🔔
} else {
ivRemind.setImageResource(R.mipmap.button_off); // 🔕
}
}
// 获取状态中文文本
private String getStateText(String state) {
switch (state) {
case "0": return "在途";
case "5": return "派件";
case "3": return "签收";
case "6": return "退回";
case "4": return "退签";
case "1": return "揽收";
case "7": return "转投";
case "2": return "疑难";
case "8": return "清关";
case "10": return "待清关";
case "11": return "清关中";
case "12": return "已清关";
case "13": return "清关异常";
default: return "";
}
}
// 获取对应状态的通知内容
private String getNotifyContent(String state) {
switch (state) {
case "0": return "您的快递已在运输途中,正在路上~";
case "5": return "快递员正在为您派送,请注意查收!";
case "3": return "您的快递已签收,感谢使用!";
case "6": return "很遗憾,您的快递因故被退回。";
case "4": return "您已拒签该快递,订单已完成。";
default: return "快递因地址问题已转投其他网点。";
}
}
// 发送状态变更通知
private void sendStatusNotification(String number, String company, String titleSuffix, String content) {
PackageNotificationSender sender = new PackageNotificationSender(context);
int id = ("status_" + number).hashCode() & Integer.MAX_VALUE;
id = (id % 1_000_000) + 2000; // 控制 ID 范围,避免冲突
sender.sendCustomNotification(id, "📌 快递" + titleSuffix, content, number, company);
}
// 根据 type 查找快递公司名称
private String getTrackName(String type) {
if (mTrackList != null) {
for (ListBean item : mTrackList) {
if (item.getNum() != null && type != null && TextUtils.equals(item.getNum(), type)) {
return item.getCom();
}
}
}
return "";
}
// 设置外部数据源
public void setTrackList(List<ListBean> list) {
this.mTrackList = list;
}
// 缓存当前列表(供开启提醒时查询状态)
@Override
public void setNewInstance(List<ListBean> list) {
super.setNewInstance(list);
this.currentList = list;
}
// 可选:暴露方法供外部查询某单号是否开启提醒
public boolean isReminderEnabled(String number) {
return remindedEnabled.contains(number);
}
/**
* 根据快递公司名称设置对应的 Logo 图标
*/
private void setCompanyLogo(String name, ImageView logo, LinearLayout line) {
if (name == null || name.isEmpty()) {
logo.setVisibility(View.GONE);
line.setVisibility(View.VISIBLE);
return;
}
switch (name) {
case "邮政快递包裹":
logo.setImageResource(R.mipmap.img_yz_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "京东物流":
logo.setImageResource(R.mipmap.img_jd_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "圆通快递":
logo.setImageResource(R.mipmap.img_yt_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "中通快递":
logo.setImageResource(R.mipmap.img_zt_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "顺丰速运":
logo.setImageResource(R.mipmap.img_sf_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "韵达快递":
logo.setImageResource(R.mipmap.img_yd_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "申通快递":
logo.setImageResource(R.mipmap.img_st_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
case "EMS":
logo.setImageResource(R.mipmap.img_ems_bg);
logo.setVisibility(View.VISIBLE);
line.setVisibility(View.GONE);
break;
default:
logo.setVisibility(View.GONE);
line.setVisibility(View.VISIBLE);
break;
}
}
public void loadSavedStates() {
// 如果 ReminderManager 已经负责加载,则不需要此方法
// 或者你可以让它触发一次同步
ReminderManager manager = ReminderManager.getInstance(context);
// manager.loadFromSP(); // 如果不是自动加载,手动调用
}
// MyCourierAdapter.java 中新增
public List<ListBean> getRemindedItems() {
List<ListBean> result = new ArrayList<>();
if (currentList == null) return result;
Set<String> remindedNumbers = ReminderManager.getInstance(context).getRemindedNumbers();
for (ListBean bean : currentList) {
if (remindedNumbers.contains(bean.getNum())) {
result.add(bean);
}
}
return result;
}
private void showNotificationPermissionDialog() {
if (context == null) return;
new AlertDialog.Builder(context)
.setTitle("需要通知权限")
.setMessage("请允许本应用发送快递状态提醒通知。\n\n进入【设置】→【通知】中开启权限。")
.setPositiveButton("去开启", (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 防止在非 Activity 上下文中启动失败
context.startActivity(intent);
})
.setNegativeButton("取消", (dialog, which) -> {
Toast.makeText(context, "未授予通知权限,无法开启提醒", Toast.LENGTH_SHORT).show();
})
.create()
.show();
}
}
package com.weishitechsub.kdcxqwb.fragment.remind;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.hfd.common.base.BaseFragment;
import com.weishitechsub.kdcxqwb.R;
import com.weishitechsub.kdcxqwb.bean.ListBean;
import com.weishitechsub.kdcxqwb.fragment.Adapter.MyCourierAdapter;
import com.weishitechsub.kdcxqwb.fragment.Adapter.RemindListAdapter;
import com.weishitechsub.kdcxqwb.fragment.home.MyCourierActivity;
import com.weishitechsub.kdcxqwb.utils.JsonUtils;
import com.weishitechsub.kdcxqwb.utils.ReminderManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class RemindFragment extends BaseFragment {
private RecyclerView rv;
private RemindListAdapter adapter;
private List<ListBean> fullDataList;
@Override
protected int setLayout() {
return R.layout.fragment_remind;
}
@Override
protected void initView() {
rv = fvbi(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new RemindListAdapter(getContext());
adapter.setTrackList(parseCourierJson());
rv.setAdapter(adapter);
}
@Override
protected void initData() {
refreshRemindedList(); // 直接刷新
}
@Override
public void onResume() {
super.onResume();
refreshRemindedList(); // 页面可见时重新加载
}
// RemindFragment.java
private void refreshRemindedList() {
Context context = getContext();
if (context == null) return;
// ✅ 直接从 ReminderManager 获取已提醒的条目
List<ListBean> remindedList = ReminderManager.getInstance(context).getRemindedItems();
adapter.setNewInstance(remindedList);
if (remindedList.isEmpty()) {
Toast.makeText(context, "暂无提醒中的快递", Toast.LENGTH_SHORT).show();
} else {
Log.d("RemindFragment", "显示 " + remindedList.size() + " 个提醒项");
}
}
@Override
public void onStart() {
super.onStart();
ReminderManager.getInstance(getContext()).setOnReminderChangeListener(() -> {
new Handler(Looper.getMainLooper()).post(this::refreshRemindedList);
});
}
@Override
public void onStop() {
super.onStop();
ReminderManager.getInstance(getContext()).removeListener();
}
private List<ListBean> getDataFromSomewhere() {
MyCourierActivity activity = (MyCourierActivity) getActivity();
if (activity != null) {
List<ListBean> data = activity.getCurrentCourierList();
return data != null ? new ArrayList<>(data) : new ArrayList<>();
}
return new ArrayList<>();
}
@Override
protected void initClick() {}
private List<ListBean> parseCourierJson() {
String jsonString = JsonUtils.loadJSONFromAsset(mContext.getAssets(), "delivery_list.json");
List<ListBean> couriers = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(jsonString);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
String title = item.getString("title");
String des = item.getString("des");
String value = item.getString("value");
couriers.add(new ListBean(title,value,"","",""));
}
} catch (JSONException e) {
e.printStackTrace();
}
return couriers;
}
}
package com.weishitechsub.kdcxqwb.fragment.Adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.weishitechsub.kdcxqwb.R;
import com.weishitechsub.kdcxqwb.bean.ListBean;
import java.util.List;
public class RemindListAdapter extends BaseQuickAdapter<ListBean, BaseViewHolder> {
private Context context;
private List<ListBean> mTrackList;
public RemindListAdapter(Context context) {
super(R.layout.my_courier_adapter, null);
this.context = context;
}
@Override
protected void convert(@NonNull BaseViewHolder holder, ListBean dataBean) {
String number = dataBean.getNum();
holder.setText(R.id.tv_number, number);
holder.setText(R.id.tv_address, dataBean.getContext());
holder.setText(R.id.tv_state, getStateText(dataBean.getState()));
// 设置公司图标
String trackName = getTrackName(dataBean.getType());
holder.setText(R.id.tv_type, trackName);
ImageView logo = holder.getView(R.id.iv_logo);
LinearLayout line = holder.getView(R.id.line);
setCompanyLogo(trackName, logo, line);
// 禁用提醒按钮
// holder.getView(R.id.iv_remind).setVisibility(android.view.View.GONE);
}
private String getStateText(String state) {
switch (state) {
case "0": return "在途";
case "5": return "派件";
case "3": return "签收";
case "6": return "退回";
case "4": return "退签";
case "1": return "揽收";
case "7": return "转投";
case "2": return "疑难";
case "8": return "清关";
case "10": return "待清关";
case "11": return "清关中";
case "12": return "已清关";
case "13": return "清关异常";
default: return "";
}
}
// private String getTrackName(String type) {
// // 可以传入 mTrackList 查询,此处简化处理
// return type != null ? type : "";
// }
private void setCompanyLogo(String name, ImageView logo, LinearLayout line) {
if (name == null || name.isEmpty()) {
logo.setVisibility(View.INVISIBLE);
line.setVisibility(android.view.View.VISIBLE);
return;
}
int resId = 0;
switch (name) {
case "邮政快递包裹":
resId = R.mipmap.img_yz_bg; break;
case "京东物流":
resId = R.mipmap.img_jd_bg; break;
case "圆通快递":
resId = R.mipmap.img_yt_bg; break;
case "中通快递":
resId = R.mipmap.img_zt_bg; break;
case "顺丰速运":
resId = R.mipmap.img_sf_bg; break;
case "韵达快递":
resId = R.mipmap.img_yd_bg; break;
case "申通快递":
resId = R.mipmap.img_st_bg; break;
case "EMS":
resId = R.mipmap.img_ems_bg; break;
default:
break;
}
if (resId != 0) {
logo.setImageResource(resId);
logo.setVisibility(android.view.View.VISIBLE);
line.setVisibility(android.view.View.GONE);
} else {
logo.setVisibility(android.view.View.GONE);
line.setVisibility(android.view.View.VISIBLE);
}
}
// 根据 type 查找快递公司名称
private String getTrackName(String type) {
if (mTrackList != null) {
for (ListBean item : mTrackList) {
if (item.getNum() != null && type != null && TextUtils.equals(item.getNum(), type)) {
return item.getCom();
}
}
}
return "";
}
// 设置外部数据源
public void setTrackList(List<ListBean> list) {
this.mTrackList = list;
}
}
现在有两个问题1、我要把按钮的状态也在RemindFragment显示,2、RemindFragment页面展示的提醒数据在杀死应用之后会消失我想让他持久展示,除非关闭提醒了再删除
最新发布