陈力
2023-06-09 cca5f79b3af36e5a908c5dfecbd30110febe3baa
增加mqtt
24个文件已修改
1个文件已删除
34个文件已添加
3481 ■■■■■ 已修改文件
app/build.gradle 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/CunCanFragment.java 87 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/MainActivity.java 154 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/OpenDoorFragment.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/SelectFragment.java 173 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/SettingFragment.java 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/TakeActivity.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/common/HttpLoggerInterceptor.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/common/HttpUrlDefine.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/common/SettingConfig.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/device/DeviceMessage.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/device/MessageType.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/device/service/CanGuiService.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/device/service/CrontrolGridModel.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/mqtt/MQTTService.java 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/mqtt/MyMQTTService.java 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/DialogOptions.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/SmileDialog.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/SmileDialogBuilder.java 535 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/SmileDialogFragment.java 409 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/TimeRunTextView.java 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/enums/SmileDialogType.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/enums/WidgetTypes.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnCancelClickListener.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnConformClickListener.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnCountDownOverListener.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnEditConformClickListener.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/SmileDialogImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/sqllitedb/DaoMaster.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/sqllitedb/DaoSession.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/sqllitedb/GridModel.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/sqllitedb/Order.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/sqllitedb/OrderDao.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/sqllitedb/SqlliteDbManage.java 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/lotaai/canguiayw/view/GridTableAdapter.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/anim/bottom_detail_in.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/anim/bottom_detail_out.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/anim/cycle_7.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/anim/shake.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/anim/smile_dialog_enter.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/anim/smile_dialog_exit.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/animator/animator_path.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/anim_error.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/anim_success.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/anim_warning.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/bg_smile_dialog.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/bg_smile_dialog_cancel_button.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/bg_smile_dialog_ok_button.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/svg_error.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/svg_success.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/svg_warning.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_smile_dialog.xml 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/framgment_cuncan.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/framgment_selectorder.xml 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/framgment_setting.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/colors.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/strings.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/styles.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle
@@ -20,7 +20,7 @@
}
android{
android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
@@ -31,7 +31,7 @@
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
greendao {
    schemaVersion 4//数据库版本号
    schemaVersion 8//数据库版本号
    daoPackage 'com.lotaai.canguiayw.sqllitedb'// 设置DaoMaster、DaoSession、Dao 包名
    targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录,请注意,这里路径用/不要用.
    generateTests false //设置为true以自动生成单元测试。
@@ -64,14 +64,18 @@
    implementation 'com.google.android.material:material:1.4.0'
    //table控件
    implementation 'com.github.huangyanbin:SmartTable:2.2.0'
   //下拉选择框控件
    //下拉选择框控件
    implementation 'com.github.arcadefire:nice-spinner:1.3.4'
    //支持MQTT协议
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
    //toasts 弹出样式
    implementation 'com.pranavpandey.android:dynamic-toasts:1.3.0'
    implementation 'com.alibaba:fastjson:1.2.59'
    implementation 'com.squareup.okhttp3:okhttp:3.12.1'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'
}
app/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <application
        android:name=".application.ActivityLifecycleApplcation"
@@ -30,6 +31,12 @@
            android:name=".device.service.CanGuiService"
            android:enabled="true"
            android:exported="true" />
        <service
            android:name=".mqtt.MyMQTTService"
            android:enabled="true"
            android:exported="true" />
        <service
            android:name="org.eclipse.paho.android.service.MqttService" />
    </application>
</manifest>
app/src/main/java/com/lotaai/canguiayw/CunCanFragment.java
@@ -13,6 +13,7 @@
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
@@ -25,8 +26,18 @@
import com.bin.david.form.data.format.draw.IDrawFormat;
import com.bin.david.form.data.style.FontStyle;
import com.bin.david.form.data.table.TableData;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.lotaai.canguiayw.device.CanguiStatus;
import com.lotaai.canguiayw.device.service.CrontrolGridModel;
import com.lotaai.canguiayw.sqllitedb.GridModel;
import com.lotaai.canguiayw.sqllitedb.Order;
import com.lotaai.canguiayw.sqllitedb.OrderDetail;
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
import com.pranavpandey.android.dynamic.toasts.DynamicToast;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.Date;
@@ -38,6 +49,8 @@
    private Context context;
    private EditText editText;
    private SmartTable orderDetailTable;
    private TextView gekouTxt;
    private TextView orderNotxt;
    @Override
    public void onCreate(Bundle savedInstanceState) {
@@ -55,8 +68,11 @@
        if (root == null) {
            root = inflater.inflate(R.layout.framgment_cuncan, container, false);
        }
        DynamicToast.Config.getInstance().setTextSize(30).apply();
        context = container.getContext();
        editText = (EditText)root.findViewById(R.id.edt_borrow_case_number);
        gekouTxt = root.findViewById(R.id.geKoueText);
        orderNotxt = root.findViewById(R.id.orderNoText);
        editText.setInputType(InputType.TYPE_NULL); // 屏蔽软键盘
        View.OnClickListener clickListener = new View.OnClickListener() {
            @Override
@@ -72,14 +88,30 @@
                    // 调用后台
                    String gridNo = editable.toString();
                    if (null == gridNo || "".equals(gridNo.trim())) {
                        Toast.makeText(context, "取餐码不能为空。", Toast.LENGTH_SHORT).show();
                        DynamicToast.makeError(context, "取餐序号不能为空。", 3).show();
                        return;
                    } else {
                        if (gridNo.length() > 5) {
                            Toast.makeText(context, "取餐码输入错误,请重试。", Toast.LENGTH_SHORT).show();
                        if (gridNo.length() !=4) {
                            editText.setText("");
                            DynamicToast.makeError(context, "取餐序号输入错误,请重试。", 3).show();
                            return;
                        }
                    }
                    //处理存餐的问题
                    //1、查询订单,并判断是否已经存过餐,如果存过
                    Order od =  SqlliteDbManage.getInstance().selectOrtderByXuhao(gridNo);
                    if (od!=null){
                        if (od.getState() == 0 || od.getState() == 1){
                            LogUtils.i("orderNo:" + od.getOrderNo() + "  state:" + od.getState());
                        }
                        initOrderDetailTableView(od.getOrderNo());
                    }else {
                        DynamicToast.makeError(context, "取餐序号输入错误,请重试。", 3).show();
                        initOrderDetailTableView("");
                    }
                    //2、分配格子
                } else {
                    Button button = (Button) v;
                    editable.insert(index, button.getText());
@@ -111,36 +143,43 @@
        view0.setOnClickListener(clickListener);
        view11.setOnClickListener(clickListener);
        view12.setOnClickListener(clickListener);
        //初始化ttable
        initOrderDetailTableView();
        initOrderDetailTableView("");
        return root;
    }
    public void initOrderDetailTableView(){
        Column<String> xuhaoCol = new Column<>("", "gridNo");
        xuhaoCol.setMinWidth(10);
        xuhaoCol.setComputeWidth(1);
        Column<String> nameCol = new Column<>("名称", "orderNo");
    public void initOrderDetailTableView(String orderNo){
        editText.setText("");
        gekouTxt.setText("");
        orderNotxt.setText("");
        Column<String> nameCol = new Column<>("名称", "itemName");
        nameCol.setComputeWidth(10);
        Column<String> numCol = new Column<>("量", "putInDate");
        Column<String> numCol = new Column<>("量", "num");
        numCol.setWidth(10);
        nameCol.setComputeWidth(1);
        List<Order> lists = new ArrayList<>();
//        for (int i = 1;i <= 20; i++) {
//            Order order = new Order();
//            order.setGridNo(Integer.toString(i));
//            order.setOrderNo("new year char grenn" );
//            Date dd = new Date();
//            order.setPutInDate(6);
//            order.setState(0);
//            order.setTakeCode("56897");
//            lists.add(order);
//        }
        List<OrderDetail>  details = new ArrayList<>();
        if (!"".equals(orderNo)) {
            details = SqlliteDbManage.getInstance().selectOrtderDetails(orderNo);
            if (details!=null && details.size()>0){
                //查找空余的格子进行分配
                GridModel model = SqlliteDbManage.getInstance().selectFreeGrid();
                gekouTxt.setText(CrontrolGridModel.getGridNoStr(model.getGuiHao(),model.getGridNo()));
                model.setState(1);
                SqlliteDbManage.getInstance().addGrid(model);
                //需要把order数据更新了
                Order od =  SqlliteDbManage.getInstance().selectOrtder(orderNo);
                od.setGridNo(CrontrolGridModel.getGridNoStr(model.getGuiHao(),model.getGridNo()));
                od.setPutInDate(TimeUtils.getNowString());
                od.setState(1);
                SqlliteDbManage.getInstance().insertOrderInfo(od);
                orderNotxt.setText(orderNo);
            }else {
                DynamicToast.makeError(context, "未查询到订单", 3).show();
            }
        }
        TableData<Order> tableData = new TableData<Order>("订单详情",lists, xuhaoCol,nameCol, numCol);
        TableData<OrderDetail> tableData = new TableData<OrderDetail>("订单详情",details,nameCol, numCol);
        //设置数据
        orderDetailTable = root.findViewById(R.id.table);
        orderDetailTable.getConfig().setShowTableTitle(true);
app/src/main/java/com/lotaai/canguiayw/MainActivity.java
@@ -8,26 +8,33 @@
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.CacheDiskUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.lotaai.canguiayw.device.CanGuiCommand;
import com.lotaai.canguiayw.device.CanguiStatus;
import com.lotaai.canguiayw.device.DeviceMessage;
import com.lotaai.canguiayw.device.DeviceType;
import com.lotaai.canguiayw.device.MessageType;
import com.lotaai.canguiayw.common.HttpLoggerInterceptor;
import com.lotaai.canguiayw.common.HttpUrlDefine;
import com.lotaai.canguiayw.common.SettingConfig;
import com.lotaai.canguiayw.device.service.CanGuiService;
import com.lotaai.canguiayw.sqllitedb.Order;
import com.lotaai.canguiayw.sqllitedb.OrderDetail;
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
import com.lotaai.canguiayw.mqtt.MyMQTTService;
import com.pranavpandey.android.dynamic.toasts.DynamicToast;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.Date;
import java.util.Random;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
    private Context context;
@@ -41,43 +48,48 @@
        context = MainActivity.this;
        Intent startIntent = new Intent(context, CanGuiService.class);
        startService(startIntent);
        Intent startMqttIntent = new Intent(context, MyMQTTService.class);
        startService(startMqttIntent);
        login();
        logoView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, AdminLoginActivity.class);
                startActivity(intent);
//                Intent intent = new Intent();
//                intent.setClass(MainActivity.this, AdminLoginActivity.class);
//                startActivity(intent);
                return true;
            }
        });
        testData();
//        testData();
    }
    public void  testData(){
        Random random = new Random();
        int rt= random.nextInt(10000-1000+1)  + 1000;
        Order order = new Order();
        order.setOrderNo("GB"+ rt);
        order.setGridNo("1");
        order.setTakeCode("526895");
        order.setState(0);
        Date time = new Date();
        order.setPutInDate(TimeUtils.date2String(time,"yyyy-MM-dd HH:mm:ss"));
        SqlliteDbManage.getInstance().insertOrderInfo(order);
        for (int p = 0; p < 3;p ++){
            OrderDetail detail = new OrderDetail();
            detail.setItemName("项目"+p);
            detail.setNum(p);
            detail.setOrderNo(order.getOrderNo());
            SqlliteDbManage.getInstance().insertOrUpdateOrderDetailInfo(detail);
        }
        LogUtils.i("插入订单数据:" + order.getOrderNo());
    }
//    public void  testData(){
//        Random random = new Random();
//        int rt= random.nextInt(10000-1000+1)  + 1000;
//        Order order = new Order();
//        order.setOrderNo("GB"+ rt);
//        order.setGridNo("1");
//        order.setTakeCode("526895");
//        order.setState(0);
//        Date time = new Date();
//        order.setPutInDate(TimeUtils.date2String(time,"yyyy-MM-dd HH:mm:ss"));
//        SqlliteDbManage.getInstance().insertOrderInfo(order);
//        for (int p = 0; p < 3;p ++){
//            OrderDetail detail = new OrderDetail();
//            detail.setItemName("项目"+p);
//            detail.setNum(p);
//            detail.setOrderNo(order.getOrderNo());
//            SqlliteDbManage.getInstance().insertOrUpdateOrderDetailInfo(detail);
//        }
//        LogUtils.i("插入订单数据:" + order.getOrderNo());
//    }
    public void gotoSetting(View view){
        Intent intent = new Intent();
        intent.setClass(MainActivity.this, AdminLoginActivity.class);
        startActivity(intent);
//        Intent intent = new Intent();
//        intent.setClass(MainActivity.this, AdminLoginActivity.class);
//        startActivity(intent);
    }
    public void take(View view){
@@ -92,4 +104,68 @@
        startActivity(intent);
    }
    public void login() {
        HttpLoggerInterceptor loggingInterceptor = new HttpLoggerInterceptor(true);
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)//响应时间,读取时间
                .readTimeout(20, TimeUnit.SECONDS)
                .callTimeout(20, TimeUnit.SECONDS)
                .addInterceptor(loggingInterceptor)//添加日志拦截器
                .build();
        RequestBody body = new FormBody.Builder()
                .add("equipmentUid", DeviceUtils.getUniqueDeviceId()).build();
        final Request request = new Request.Builder()
                .url(HttpUrlDefine.equipmentLogin)
                .addHeader("language", "zh-CN")
                .post(body)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message msg = new Message();
                msg.what = 0;
                msg.obj = "登录失败";
                showHandler.sendMessage(msg);
                LogUtils.e(e);
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                LogUtils.i("获取到的数据:"+result);
                JSONObject obj = JSONObject.parseObject(result);
                if ("0".equals(obj.getString("code"))) {
                    JSONObject dataObj = obj.getJSONObject("data");
                    String name = dataObj.getString("name");
                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = "登录成功!" + name;
                    showHandler.sendMessage(msg);
                    //equipmentCode
                    String code = dataObj.getString("equipmentCode");
                    CacheDiskUtils.getInstance().put(SettingConfig.getInstance().Cache_Device_Code, code);
                } else {
                    Message msg = new Message();
                    msg.what = 0;
                    msg.obj = "登录失败:请重新激活!" ;
                    showHandler.sendMessage(msg);
                }
            }
        });
    }
    private Handler showHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                DynamicToast.makeError(context, msg.obj.toString(), 3).show();
            } else if (msg.what == 1) {
                DynamicToast.makeSuccess(context, msg.obj.toString(), 3).show();
            } else {
                DynamicToast.makeWarning(context, msg.obj.toString(), 3).show();
            }
        }
    };
}
app/src/main/java/com/lotaai/canguiayw/OpenDoorFragment.java
@@ -68,6 +68,7 @@
        super.onDestroy();
    }
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void recvCommand(DeviceMessage mssage){
        try {
@@ -78,6 +79,7 @@
            LogUtils.e(e);
        }
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -344,9 +346,9 @@
                CanguiStatus cangui = gridStatusList.get(i);
                View item = gridtable.getChildAt(i).findViewById(R.id.gridLineLayout);
                if (checkIsSelectedAndOrRemove(cangui,true)) {
                    item.setBackgroundColor(getResources().getColor(R.color.cheng));
                } else {
                    item.setBackgroundColor(Color.GRAY);
                } else {
                    item.setBackgroundColor(getResources().getColor(R.color.cheng));
                }
            }
        });
app/src/main/java/com/lotaai/canguiayw/SelectFragment.java
@@ -1,5 +1,6 @@
package com.lotaai.canguiayw;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -8,9 +9,12 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ViewSwitcher;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
@@ -20,6 +24,7 @@
import com.bin.david.form.data.CellInfo;
import com.bin.david.form.data.column.Column;
import com.bin.david.form.data.format.IFormat;
import com.bin.david.form.data.format.bg.BaseCellBackgroundFormat;
import com.bin.david.form.data.format.bg.IBackgroundFormat;
import com.bin.david.form.data.format.bg.ICellBackgroundFormat;
import com.bin.david.form.data.format.selected.ISelectFormat;
@@ -28,10 +33,16 @@
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.lotaai.canguiayw.common.SettingConfig;
import com.lotaai.canguiayw.device.DeviceMessage;
import com.lotaai.canguiayw.device.MessageType;
import com.lotaai.canguiayw.sqllitedb.GridModel;
import com.lotaai.canguiayw.sqllitedb.Order;
import com.lotaai.canguiayw.sqllitedb.OrderDetail;
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.Date;
@@ -42,9 +53,20 @@
    private View root;
    private Context context;
    private SmartTable setTable;
    private SmartTable detailTable;
    private ViewSwitcher bottomDetail;
    private Button closeBtn;
    private Button takeOutBtn;
    private Order currentOrder;
    Column<String> gridNo = new Column<>("格子", "gridNo");
    Column<String> orderNo = new Column<>("订单号", "orderNo");
    Column<String> putIntime = new Column<>("放入时间", "putInDate");
    Column<String> xuhao = new Column<>("序号", "xuHao");
    @Override
    public void onCreate(Bundle savedInstanceState) {
        EventBus.getDefault().register(this);
        super.onCreate(savedInstanceState);
    }
@@ -54,33 +76,65 @@
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {
        if (root == null) {
            root = inflater.inflate(R.layout.framgment_selectorder, container, false);
        }
        context = container.getContext();
        bottomDetail = root.findViewById(R.id.bottom_detail);
        detailTable = root.findViewById(R.id.detailtable);
        closeBtn = root.findViewById(R.id.closeDetail);
        takeOutBtn = root.findViewById(R.id.takeOut);
        closeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (detailTable != null) {
                    bottomDetail.setVisibility(View.GONE);
                }
            }
        });
        takeOutBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //将格子释放  //将订单的格子号改为空
                if (currentOrder!=null && !"".equals(currentOrder.getGridNo())) {
                    GridModel model = SqlliteDbManage.getInstance().selectGridByGridNoStr(currentOrder.getGridNo());
                    model.setState(0);
                    SqlliteDbManage.getInstance().addGrid(model);
                    currentOrder.setState(3);
                    SqlliteDbManage.getInstance().insertOrderInfo(currentOrder);
                   // mHandler.sendEmptyMessage(1);
                    initTableView();
                    LogUtils.i("订单:" + currentOrder.getOrderNo());
                }else {
                    LogUtils.i("没有订单");
                }
                if (detailTable != null) {
                    bottomDetail.setVisibility(View.GONE);
                }
            }
        });
        initTableView();
        return root;
    }
    public void initTableView(){
        Column<String> gridNo = new Column<>("格子", "gridNo");
        Column<String> orderNo = new Column<>("订单号", "orderNo");
        Column<String> putIntime = new Column<>("放入时间", "putInDate");
        Column<String> takeCode = new Column<>("取餐码", "takeCode");
        List<Order> lists = SqlliteDbManage.getInstance().selectOrtdersByState(0);
        TableData<Order> tableData = new TableData<Order>("测试表格名字",lists,gridNo, orderNo, putIntime, takeCode);
    public void initTableView() {
        List<Order> lists = SqlliteDbManage.getInstance().selectOrtdersInGui();
        TableData<Order> tableData = null;
        if (lists != null) {
            tableData = new TableData<Order>("", lists, gridNo, orderNo, putIntime, xuhao);
        }else {
            tableData = new TableData<Order>("", new ArrayList<Order>(), gridNo, orderNo, putIntime, xuhao);
        }
        //设置数据
        setTable = root.findViewById(R.id.table);
        setTable.getConfig().setShowTableTitle(false);
//        // 设置表格标题名称文字样式
//        setTable.getConfig().setTableTitleStyle(new FontStyle(30, Color.GREEN));
        setTable.getConfig().setMinTableWidth(ScreenUtils.getScreenWidth()-20);
        setTable.getConfig().setMinTableWidth(ScreenUtils.getScreenWidth() - 20);
        // 设置表格标题文字样式
        setTable.getConfig().setColumnTitleStyle(new FontStyle(30,Color.WHITE));
        setTable.getConfig().setColumnTitleStyle(new FontStyle(30, Color.WHITE));
        IBackgroundFormat backgroundFormat = new IBackgroundFormat() {
            @Override
@@ -100,23 +154,24 @@
        clickDetail();
    }
    public void clickDetail(){
        if (setTable!=null){
    public void clickDetail() {
        if (setTable != null && setTable.getTableData() != null) {
            setTable.getTableData().setOnRowClickListener(new TableData.OnRowClickListener() {
                @Override
                public void onClick(Column column, Object o, int col, int row) {
                 LogUtils.i("click row "  + row);
                 final int rr = row;
                public void onClick(Column column, Object o, int col, final int row) {
                    currentOrder = (Order) setTable.getTableData().getT().get(row);
                    showDetailTable(currentOrder);
                    LogUtils.i("click row:" + row + "  col:" + col);
                    setTable.getConfig().setContentCellBackgroundFormat(new ICellBackgroundFormat<CellInfo>() {
                        @Override
                        public void drawBackground(Canvas canvas, Rect rect, CellInfo cellInfo, Paint paint) {
                            if(cellInfo.row!=rr){
                            if (cellInfo.row != row) {
                                paint.setColor(Color.GRAY);
                            } else {
                                paint.setColor(getResources().getColor(R.color.cheng));
                            }
                            else{
                                paint.setColor(Color.BLUE);
                            }
                            canvas.drawRect(rect,paint);
                            canvas.drawRect(rect, paint);
                            mHandler.sendEmptyMessageDelayed(1, 200);
                        }
                        @Override
@@ -128,4 +183,76 @@
            });
        }
    }
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mHandler.removeMessages(1);
            setTable.notifyDataChanged();
            super.handleMessage(msg);
        }
    };
    public void showDetailTable(Order order) {
        bottomDetail.setVisibility(View.VISIBLE);
        Column<String> itemName = new Column<>("餐品", "itemName");
        Column<Integer> num = new Column<>("数量", "num");
        List<OrderDetail> lists = SqlliteDbManage.getInstance().selectOrtderDetails(order.getOrderNo());
        TableData<OrderDetail> detailTableData = new TableData<OrderDetail>("", lists, itemName, num);
        detailTable.getConfig().setShowTableTitle(false);
//        // 设置表格标题名称文字样式
//        setTable.getConfig().setTableTitleStyle(new FontStyle(30, Color.GREEN));
        detailTable.getConfig().setMinTableWidth(750);
        // 设置表格标题文字样式
        detailTable.getConfig().setColumnTitleStyle(new FontStyle(30, Color.WHITE));
        IBackgroundFormat backgroundFormat = new IBackgroundFormat() {
            @Override
            public void drawBackground(Canvas canvas, Rect rect, Paint paint) {
                canvas.drawColor(getResources().getColor(R.color.DarkGray));
            }
        };
        detailTable.getConfig().setColumnTitleBackground(backgroundFormat);
        // 设置表格主体内容文字样式
        detailTable.getConfig().setContentStyle(new FontStyle(30, Color.WHITE));
        detailTable.getConfig().setShowXSequence(false);      //去掉表格顶部字母
        detailTable.getConfig().setShowYSequence(false);      //去掉左侧数字
        // 设置表格主标题
        detailTable.setTableData(detailTableData);
    }
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void recvCommand(DeviceMessage mssage) {
        try {
            if (mssage.getMessageType() == MessageType.NEWORDER.ordinal()) {
                LogUtils.i("有新的订单进来");
                String orderNo = mssage.getMsgString();
                //首先要判断订单里面是否已经有了
                boolean isFind = false;
                if (setTable.getTableData()!=null) {
                    List<Order> oldOrders = setTable.getTableData().getT();
                    if (oldOrders != null && oldOrders.size() > 0) {
                        for (int p = 0; p < oldOrders.size(); p++) {
                            Order t = oldOrders.get(p);
                            if (t.getOrderNo().equals(orderNo)) {
                                isFind = true;
                                break;
                            }
                        }
                    }
                }
                if (isFind == false) {
                    //查询订单信息
                    Order orderInfo = SqlliteDbManage.getInstance().selectOrtder(orderNo);
                    List<Order> pp = new ArrayList<>();
                    pp.add(orderInfo);
                    setTable.addData(pp, true);
                }
            }
        } catch (Exception e) {
            LogUtils.e(e);
        }
    }
}
app/src/main/java/com/lotaai/canguiayw/SettingFragment.java
@@ -16,19 +16,40 @@
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import androidx.fragment.app.Fragment;
import com.alibaba.fastjson.JSONObject;
import com.bin.david.form.core.SmartTable;
import com.blankj.utilcode.util.CacheDiskUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.KeyboardUtils;
import com.blankj.utilcode.util.LogUtils;
import com.lotaai.canguiayw.common.HttpLoggerInterceptor;
import com.lotaai.canguiayw.common.HttpUrlDefine;
import com.lotaai.canguiayw.common.SettingConfig;
import com.pranavpandey.android.dynamic.toasts.DynamicToast;
import org.angmarch.views.NiceSpinner;
import org.angmarch.views.SpinnerTextFormatter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import android_serialport_api.SerialPortFinder;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
public class SettingFragment extends Fragment {
@@ -36,6 +57,11 @@
    private Context context;
    private SmartTable setTable;
    private NiceSpinner chuanKouSpinner;
    private EditText deviceCode;
    private EditText devicePwd;
    private Button jihuoBtn;
    private Button saveBtn;
    List<String> list = new ArrayList<String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
@@ -53,6 +79,7 @@
        if (root == null) {
            root = inflater.inflate(R.layout.framgment_setting, container, false);
        }
        DynamicToast.Config.getInstance().setTextSize(30).apply();
        context = container.getContext();
        initSpinner();
@@ -64,36 +91,149 @@
        };
        // 将myTouchListener注册到分发列表
        ((ManageActivity)this.getActivity()).registerMyTouchListener(myTouchListener);
        ((ManageActivity) this.getActivity()).registerMyTouchListener(myTouchListener);
        //初始化
        deviceCode = root.findViewById(R.id.deviceCode);
        devicePwd = root.findViewById(R.id.devicePwd);
        deviceCode.setText(CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Code));
        // devicePwd.setText(CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Pwd));
        jihuoBtn = root.findViewById(R.id.jihuo);
        saveBtn = root.findViewById(R.id.save);
        jihuoBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String code = deviceCode.getText().toString().trim();
                String pwd = devicePwd.getText().toString().trim();
                if ("".equals(code) || "".equals(pwd)) {
                    DynamicToast.makeError(context, "设备号和设备秘钥必填", 3).show();
                    return;
                }
                active();
            }
        });
        saveBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DynamicToast.Config.getInstance().setTextSize(30).apply();
                String code = deviceCode.getText().toString().trim();
                String pwd = devicePwd.getText().toString().trim();
                String tty = list.get(chuanKouSpinner.getSelectedIndex());
                if ("".equals(code)) {
                    DynamicToast.makeError(context, "设备号必填", 3).show();
                } else {
                    CacheDiskUtils.getInstance().put(SettingConfig.getInstance().Cache_Device_Code, code);
//                    CacheDiskUtils.getInstance().put(SettingConfig.getInstance().Cache_Device_Pwd,pwd);
                    CacheDiskUtils.getInstance().put(SettingConfig.getInstance().Cache_Device_Tty, tty);
                    DynamicToast.makeSuccess(context, "保存成功", 3).show();
                }
            }
        });
        return root;
    }
    public void initSpinner(){
    public void active() {
        HttpLoggerInterceptor loggingInterceptor = new HttpLoggerInterceptor(true);
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)//响应时间,读取时间
                .readTimeout(20, TimeUnit.SECONDS)
                .callTimeout(20, TimeUnit.SECONDS)
                .addInterceptor(loggingInterceptor)//添加日志拦截器
                .build();
        RequestBody body = new FormBody.Builder()
                .add("equipmentCode", CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Code))
                .add("equipmentSecret", devicePwd.getText().toString())
                .add("equipmentUid", DeviceUtils.getUniqueDeviceId()).build();
        final Request request = new Request.Builder()
                .url(HttpUrlDefine.equipmentBind)
                .addHeader("language", "zh-CN")
                .post(body)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message msg = new Message();
                msg.what = 0;
                msg.obj = "激活失败";
                showHandler.sendMessage(msg);
                LogUtils.e(e);
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                LogUtils.i("获取到的数据:"+result);
                JSONObject obj = JSONObject.parseObject(result);
                if ("0".equals(obj.getString("code"))) {
                    JSONObject dataObj = obj.getJSONObject("data");
                    String name = dataObj.getString("name");
                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = "激活成功!" + name;
                    showHandler.sendMessage(msg);
                } else {
                    Message msg = new Message();
                    msg.what = 0;
                    msg.obj = "激活失败:" + obj.getString("msg");
                    showHandler.sendMessage(msg);
                }
            }
        });
    }
    private Handler showHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                DynamicToast.makeError(context, msg.obj.toString(), 3).show();
            } else if (msg.what == 1) {
                DynamicToast.makeSuccess(context, msg.obj.toString(), 3).show();
            } else {
                DynamicToast.makeWarning(context, msg.obj.toString(), 3).show();
            }
        }
    };
    public void initSpinner() {
        chuanKouSpinner = root.findViewById(R.id.chuankouhao);
        chuanKouSpinner.setBackgroundResource(R.drawable.round_editstyle);
        chuanKouSpinner.setTextSize(30);
        String ty = CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Tty);
        int select = 0;
//        SerialPortFinder finder = new SerialPortFinder();
//        String[] ttysPath = finder.getAllDevicesPath();
//        int p = 0;
//        for (String sp : ttysPath){
//            if (sp.equals(ty)){
//                select = p;
//            }
//            list.add(sp);
//            p++;
//        }
        final List<String> list = new ArrayList<String>();
        for (int i = 1; i<10 ;i++){
            list.add("ttyS" + i);
        list.clear();
        for (int pp = 0; pp < 6; pp++) {
            list.add("/dev/ttyS" + pp);
            if (ty!=null && ty.equals("/dev/ttyS" + pp)) {
                select = pp;
            }
        }
        chuanKouSpinner.attachDataSource(list);
        chuanKouSpinner.addOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               LogUtils.i(list.get(position));
                LogUtils.i(list.get(position) + "position:" + position);
            }
        });
        chuanKouSpinner.setSelectedIndex(select);
    }
    public static void HideKeyboard(View v)
    {
        InputMethodManager imm = ( InputMethodManager ) v.getContext( ).getSystemService( Context.INPUT_METHOD_SERVICE );
        if ( imm.isActive( ) ) {
            imm.hideSoftInputFromWindow( v.getApplicationWindowToken( ) , 0 );
    public static void HideKeyboard(View v) {
        InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm.isActive()) {
            imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
        }
    }
app/src/main/java/com/lotaai/canguiayw/TakeActivity.java
@@ -12,8 +12,12 @@
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.blankj.utilcode.util.CacheDiskUtils;
import com.blankj.utilcode.util.LogUtils;
import com.lotaai.canguiayw.device.DeviceMessage;
import com.lotaai.canguiayw.device.MessageType;
import com.lotaai.canguiayw.sqllitedb.Order;
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
import org.greenrobot.eventbus.EventBus;
@@ -46,10 +50,12 @@
                        Toast.makeText(context, "取餐码不能为空。", Toast.LENGTH_SHORT).show();
                        return;
                    } else {
                        if (gridNo.length() > 5) {
                        if (gridNo.length() !=6) {
                            Toast.makeText(context, "取餐码输入错误,请重试。", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        //调用判断是否可以取餐
                        takeCheckCode("");
                    }
                } else {
                    Button button = (Button) v;
@@ -90,5 +96,15 @@
        finish();
    }
    public void takeCheckCode(String code){
        Order order = SqlliteDbManage.getInstance().selectOrtderByTakeCode(code);
        if (order == null || order.getGridNo() == ""){
            //代表取餐码错误
        }else {
            //开门取餐,并弹出取餐号
        }
    }
}
app/src/main/java/com/lotaai/canguiayw/common/HttpLoggerInterceptor.java
New file
@@ -0,0 +1,37 @@
package com.lotaai.canguiayw.common;
import androidx.annotation.NonNull;
import com.blankj.utilcode.util.LogUtils;
import com.lotaai.canguiayw.BuildConfig;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class HttpLoggerInterceptor implements Interceptor {
    private static String TAG = "LoggerInterceptor";
    private boolean isDebug;
    public HttpLoggerInterceptor(boolean isDebug) {
        this(TAG, isDebug);
    }
    public HttpLoggerInterceptor(String tag, boolean isDebug) {
        this.isDebug = isDebug;
        TAG = tag;
    }
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request();
        if (BuildConfig.DEBUG || isDebug) {
            LogUtils.i(TAG, String.format("发送请求:%s on %s%n%s%n%s",
                    request.url(), chain.connection(), request.headers(), request.body()));
        }
        return chain.proceed(request);
    }
}
app/src/main/java/com/lotaai/canguiayw/common/HttpUrlDefine.java
New file
@@ -0,0 +1,8 @@
package com.lotaai.canguiayw.common;
public class HttpUrlDefine {
//    private String rootHost = "http://localhost:9081";
    private static String rootHost = "http://test.lotaai.com/";
    public static String  equipmentBind = rootHost + "/lotaai-api/api/eq/equipmentBind";
    public static String  equipmentLogin = rootHost + "/lotaai-api/api/eq/equipmentLogin";
}
app/src/main/java/com/lotaai/canguiayw/common/SettingConfig.java
@@ -14,6 +14,18 @@
    public static SettingConfig settingConfig;
    public List<CanguiStatus> statusList = new ArrayList<>();
    //MQTT的配置
    public String MQTT_IP="cy.lotaai.com";
    public String MQTT_PORT="9082";
    public String MQTT_USER="lotaaibroker";
    public String MQTT_PASSWORD="userLotaai@123";
    public String MQTT_CLIENT_HEAD="canguihead";
    //本地存储的配置
    public String Cache_Device_Code ="Cache_Device_Code";
    public String Cache_Device_Pwd ="Cache_Device_Pwd";
    public String Cache_Device_Tty ="Cache_Device_Tty";
    private SettingConfig(){
    }
app/src/main/java/com/lotaai/canguiayw/device/DeviceMessage.java
@@ -4,6 +4,15 @@
    private int messageType;
    private int deviceType;
    private byte[] messageByte;
    public String msgString;
    public String getMsgString() {
        return msgString;
    }
    public void setMsgString(String msgString) {
        this.msgString = msgString;
    }
    public int getMessageType() {
        return messageType;
app/src/main/java/com/lotaai/canguiayw/device/MessageType.java
@@ -3,5 +3,7 @@
public enum MessageType {
    SENDMESSAGE,//发送餐柜指令
    RECVMESSAGE,//接收
    FANHUI // 返回主界面
    FANHUI, // 返回主界面
    NEWORDER,//接收到新订单
    MQTT //mqtt消息
}
app/src/main/java/com/lotaai/canguiayw/device/service/CanGuiService.java
@@ -6,6 +6,7 @@
import androidx.annotation.Nullable;
import com.blankj.utilcode.util.CacheDiskUtils;
import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ThreadUtils;
@@ -14,11 +15,15 @@
import com.lotaai.canguiayw.device.CanguiStatus;
import com.lotaai.canguiayw.device.DeviceMessage;
import com.lotaai.canguiayw.device.MessageType;
import com.lotaai.canguiayw.sqllitedb.GridModel;
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
@@ -34,6 +39,7 @@
    private List<byte[]> commandQueue = new LinkedList<byte[]>();
    SerialPortUtils serialPortUtils = new SerialPortUtils();
    private HashMap<String,List<GridModel>> gridStatus = new HashMap<>();
    @Nullable
    @Override
@@ -44,7 +50,12 @@
    @Override
    public void onCreate() {
        super.onCreate();
        serialPortUtils.openSerialPort("/dev/ttyS4",4800);
//        serialPortUtils.openSerialPort("/dev/ttyS4",4800);
        String str = CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Tty);
        if (str == null || "".equals(str)){
            return;
        }
        serialPortUtils.openSerialPort(str,4800);
        registerListener();
        SettingConfig.getInstance().getExecutor().execute(selectRunnable);
        SettingConfig.getInstance().getExecutor().execute(sendRunnable);
@@ -55,6 +66,18 @@
    Runnable selectRunnable = new Runnable() {
        @Override
        public void run() {
            //开始之前先查询是不是已经有了
            for (int i = 0; i<20;i++) {
                List<GridModel> lists = SqlliteDbManage.getInstance().selectGridByGui(i);
                if (lists != null && lists.size() > 0) {
                    gridStatus.put(Integer.toString(i), lists);
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            while(true){
                try {
                    Thread.sleep(2000);
@@ -101,12 +124,31 @@
            public void onDataReceive(byte[] buffer, int size) {
                if (size >3){
                    List<CanguiStatus> statuses =  CanGuiCommand.getInstance().analysisRecvByte(buffer);
                    if (statuses!=null){
                    boolean isHas = false;
                    int gui = -1;
                    if (statuses!=null &&statuses.size()>0){
                        if (gridStatus.containsKey(Integer.toString(statuses.get(0).getGuiHao()))){
                            isHas = true;
                        }
                        for (int i = 0; i < statuses.size(); i++){
                            CanguiStatus s = statuses.get(i);
                            SettingConfig.getInstance().addStatusInList(s);
                            LogUtils.i("柜:" + s.getGuiHao(),"格:" + s.getGridNo(),"温度:" + s.getWendu(),
                                    "门:"+s.isDoorIsOpen(),"加热:"+s.isJiareIsOpen(),"灯光:" + s.isDengGuangIsOpen(),"消毒:" + s.isXiaoDuIsOpen());
                            if (!isHas) {
                                GridModel model = new GridModel();
                                model.setGuiHao(s.getGuiHao());
                                model.setGridNo(s.getGridNo());
                                model.setState(0);
                                SqlliteDbManage.getInstance().addGrid(model);
                                gui = s.getGuiHao();
                            }
//                            LogUtils.i("柜:" + s.getGuiHao(),"格:" + s.getGridNo(),"温度:" + s.getWendu(),
////                                    "门:"+s.isDoorIsOpen(),"加热:"+s.isJiareIsOpen(),"灯光:" + s.isDengGuangIsOpen(),"消毒:" + s.isXiaoDuIsOpen());
                        }
                        if (gui > -1 && !isHas){
                            List<GridModel> lists = SqlliteDbManage.getInstance().selectGridByGui(gui);
                            if (lists!=null && lists.size()>0){
                                gridStatus.put(Integer.toString(gui),lists);
                            }
                        }
                    }
                }
app/src/main/java/com/lotaai/canguiayw/device/service/CrontrolGridModel.java
New file
@@ -0,0 +1,106 @@
package com.lotaai.canguiayw.device.service;
import com.blankj.utilcode.util.StringUtils;
public class CrontrolGridModel {
    private int guiNo;
    private int gridNo;
    private int openOrNoActon = 0;
    private int wendu = 255;
    private int xiaodu = 0;
    private int dengGuang = 0;
    private int jiaRe = 0;
    private int guangDengji = 0;
    public int getGuiNo() {
        return guiNo;
    }
    public void setGuiNo(int guiNo) {
        this.guiNo = guiNo;
    }
    public int getGridNo() {
        return gridNo;
    }
    public void setGridNo(int gridNo) {
        this.gridNo = gridNo;
    }
    public int getOpenOrNoActon() {
        return openOrNoActon;
    }
    public void setOpenOrNoActon(int openOrNoActon) {
        this.openOrNoActon = openOrNoActon;
    }
    public int getWendu() {
        return wendu;
    }
    public void setWendu(int wendu) {
        this.wendu = wendu;
    }
    public int getXiaodu() {
        return xiaodu;
    }
    public void setXiaodu(int xiaodu) {
        this.xiaodu = xiaodu;
    }
    public int getDengGuang() {
        return dengGuang;
    }
    public void setDengGuang(int dengGuang) {
        this.dengGuang = dengGuang;
    }
    public int getJiaRe() {
        return jiaRe;
    }
    public void setJiaRe(int jiaRe) {
        this.jiaRe = jiaRe;
    }
    public int getGuangDengji() {
        return guangDengji;
    }
    public void setGuangDengji(int guangDengji) {
        this.guangDengji = guangDengji;
    }
    /**
     * A1转换成gui =0  grid = 1
     * @param gridNoString
     */
    public void ChangeGrid(String gridNoString){
         if (!StringUtils.isEmpty(gridNoString)){
             gridNoString = gridNoString.toUpperCase();
             char g = gridNoString.charAt(0);
             if (Character.isDigit(g)){
                 guiNo = (int)g - (int)('A');
             }
             String str = gridNoString.substring(1);
             gridNo = Integer.parseInt(str);
         }
    }
    /**
     * gui =0  grid = 1 转换成A1
     * @param gui
     * @param grid
     * @return
     */
    public static  String getGridNoStr(int gui,int grid){
        char c=(char)(gui+65);
        String result =  String.valueOf(c) + Integer.toString(grid);
        return result;
    }
}
app/src/main/java/com/lotaai/canguiayw/mqtt/MQTTService.java
File was deleted
app/src/main/java/com/lotaai/canguiayw/mqtt/MyMQTTService.java
New file
@@ -0,0 +1,305 @@
package com.lotaai.canguiayw.mqtt;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.telecom.Call;
import android.util.Log;
import androidx.annotation.Nullable;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.CacheDiskUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.JsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.StringUtils;
import com.lotaai.canguiayw.common.SettingConfig;
import com.lotaai.canguiayw.device.CanGuiCommand;
import com.lotaai.canguiayw.device.DeviceMessage;
import com.lotaai.canguiayw.device.DeviceType;
import com.lotaai.canguiayw.device.MessageType;
import com.lotaai.canguiayw.device.service.CrontrolGridModel;
import com.lotaai.canguiayw.smiledialog.TimeRunTextView;
import com.lotaai.canguiayw.sqllitedb.Order;
import com.lotaai.canguiayw.sqllitedb.OrderDetail;
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class MyMQTTService extends Service {
    public static final String TAG = MyMQTTService.class.getSimpleName();
    private static MqttAndroidClient client;
    private MqttConnectOptions conOpt;
    private static String pubTopic="cangui/device/send/";
    private static String subTopic_Order="cangui/device/recvorder/";
    private static String subTopic_Control="cangui/device/recvcontrol/";
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        init();
        return super.onStartCommand(intent, flags, startId);
    }
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public static void publish(DeviceMessage message) {
        //需要在这个地方区分是哪种指令
        //才能确定发送到哪个topic
        if (message.getMessageType() == MessageType.MQTT.ordinal()){
            String topic = pubTopic;
            Integer qos = 2;
            Boolean retained = false;
            String msg = message.getMsgString();
            try {
                client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }
    private void init() {
        // 服务器地址(协议+地址+端口号)
        String uri = "tcp://" + SettingConfig.getInstance().MQTT_IP+":"+SettingConfig.getInstance().MQTT_PORT;;
        LogUtils.i(uri);
        client = new MqttAndroidClient(this, uri, "tests233233232");
        // 设置MQTT监听并且接受消息
        client.setCallback(mqttCallback);
        conOpt = new MqttConnectOptions();
        // 清除缓存 客户端掉线后 服务器端不会清除session,当重连后可以接收之前订阅主题的消息
        conOpt.setCleanSession(false);
        // 设置超时时间,单位:秒
        conOpt.setConnectionTimeout(10);
        // 心跳包发送间隔,单位:秒
        conOpt.setKeepAliveInterval(20);
        // 用户名
        conOpt.setUserName(SettingConfig.getInstance().MQTT_USER);
        // 密码
        conOpt.setPassword(SettingConfig.getInstance().MQTT_PASSWORD.toCharArray());
        //设置自动重连
        conOpt.setAutomaticReconnect(true);
        // last will message
        boolean doConnect = true;
        String message ="";
        Integer qos = 2;
        Boolean retained = false;
        if ((!message.equals("")) || (!pubTopic.equals(""))) {
            // 最后
            try {
                conOpt.setWill(pubTopic, message.getBytes(), qos.intValue(), retained.booleanValue());
            } catch (Exception e) {
                Log.i(TAG, "Exception Occured", e);
                doConnect = false;
                iMqttActionListener.onFailure(null, e);
            }
        }
        if (doConnect) {
            doClientConnection();
        }
    }
    @Override
    public void onDestroy() {
        try {
            client.disconnect();  //服务销毁,断开连接
        } catch (MqttException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }
    /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
        Thread sysc =  new Thread() {
            @Override
            public void run() {
                while (!client.isConnected()) {
                    try {
                        Thread.sleep(5*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (isConnectIsNomarl()) {
                        try {
                            LogUtils.i("doClientConnection start");
                            client.connect(conOpt, null, iMqttActionListener);
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        SettingConfig.getInstance().getExecutor().execute(sysc);
    }
    // MQTT是否连接成功
    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken arg0) {
            LogUtils.i(TAG, "连接成功 ");
            try {
                // 订阅myTopic话题,当订阅多条频道,需要遍历逐条订阅,否则有可能订阅失败
                String gui = CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Code);
                client.subscribe(subTopic_Order+gui, 2);
                client.subscribe(subTopic_Control+gui, 2);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            LogUtils.i(TAG, "连接失败:" + arg1);
        }
    };
    // MQTT监听并且接受消息
    private MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String messageStr = new String(message.getPayload());
            String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
            LogUtils.i(TAG, "messageArrived:" + messageStr);
            LogUtils.i(TAG, str2);
            //对接收到的数据做分析
            //1、订单数据
            if (topic.startsWith(subTopic_Order)){
                Order order = new Order();
                JSONObject json = JSONObject.parseObject(messageStr);
                String orderno = json.getString("orderno");
                //判断这个订单是否已经存在
                Order checkOrder = SqlliteDbManage.getInstance().selectOrtder(orderno);
                if (checkOrder == null){
                    String seqnum = json.getString("seqnum");
                    String orderType = json.getString("orderType");
                    String bookingType = json.getString("bookingType");
                    if (json.getString("startTime")!=null) {
                        String startTime = JsonUtils.getString(messageStr, "startTime", "");
                    }
                    String createdTime = json.getString("createdTime");
                    String tableNum = JsonUtils.getString(messageStr,"tableNum","");
                    order.setOrderNo(orderno);
                    order.setState(0);
                    order.setXuHao(seqnum);
                    order.setTakeCode("");
                    order.setGridNo("");
                    order.setPutInDate("");
                    order.setCreateTime(createdTime);
                    JSONArray detailArry = json.getJSONArray("orderItems");
                    if (detailArry!=null && detailArry.size()>0){
                        for (int i = 0; i < detailArry.size(); i++) {
                            JSONObject orderGoodsDTO = detailArry.getJSONObject(i).getJSONObject("orderGoods");
                            if (orderGoodsDTO!=null){
                                OrderDetail detail = new OrderDetail();
                                String name = orderGoodsDTO.getString("name");
                                String numString  = orderGoodsDTO.getString("num");
                                int num =1;
                                if (!numString.isEmpty()){
                                    num = Integer.parseInt(numString);
                                }
                                detail.setOrderNo(orderno);
                                detail.setNum(num);
                                detail.setItemName(name);
                                SqlliteDbManage.getInstance().insertOrUpdateOrderDetailInfo(detail);
                            }
                        }
                    }
                    SqlliteDbManage.getInstance().insertOrderInfo(order);
                    DeviceMessage sendMessage = new DeviceMessage();
                    sendMessage.setMessageType(MessageType.NEWORDER.ordinal());
                    sendMessage.setMsgString(orderno);
                    EventBus.getDefault().post(sendMessage);
                }
            }
            //2、开门、开馆灯、开关消毒灯、开关加热
            if (topic.startsWith(subTopic_Control)){
                JSONObject json = JSONObject.parseObject(messageStr);
                String doorIsOpen = json.getString("doorIsOpen");
                String xiaoDuIsOpen = json.getString("xiaoDuIsOpen");
                String jiareIsOpen = json.getString("jiareIsOpen");
                String dengGuangIsOpen = json.getString("dengGuangIsOpen");
                String grid = json.getString("gridNo");
                CrontrolGridModel crontrolGridModel = new CrontrolGridModel();
                if (doorIsOpen!=null && doorIsOpen.equals("1")){
                    crontrolGridModel.setOpenOrNoActon(1);
                }
                if (xiaoDuIsOpen!=null) {
                    crontrolGridModel.setXiaodu(Integer.parseInt(xiaoDuIsOpen));
                }
                if (jiareIsOpen!=null) {
                    crontrolGridModel.setXiaodu(Integer.parseInt(jiareIsOpen));
                }
                if (dengGuangIsOpen!=null) {
                    crontrolGridModel.setXiaodu(Integer.parseInt(dengGuangIsOpen));
                }
                byte[] command = CanGuiCommand.getInstance().controlGridCommand(crontrolGridModel.getGuiNo() ,
                        crontrolGridModel.getGridNo() , crontrolGridModel.getOpenOrNoActon(),
                        crontrolGridModel.getWendu(), crontrolGridModel.getXiaodu(), crontrolGridModel.getDengGuang(),
                        crontrolGridModel.getJiaRe(), crontrolGridModel.getGuangDengji());
                DeviceMessage dvmessage = new DeviceMessage();
                dvmessage.setMessageType(MessageType.SENDMESSAGE.ordinal());
                dvmessage.setDeviceType(DeviceType.CANGUI.ordinal());
                dvmessage.setMessageByte(command);
                EventBus.getDefault().post(message);
            }
        }
        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {
        }
        @Override
        public void connectionLost(Throwable arg0) {
        }
    };
    /**
     * 判断网络是否连接
     */
    private boolean isConnectIsNomarl() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            Log.i(TAG, "MQTT当前网络名称:" + name);
            return true;
        } else {
            Log.i(TAG, "MQTT 没有可用网络");
            return false;
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/DialogOptions.java
New file
@@ -0,0 +1,52 @@
package com.lotaai.canguiayw.smiledialog;
import android.content.res.ColorStateList;
import androidx.appcompat.app.AppCompatActivity;
import com.lotaai.canguiayw.smiledialog.enums.SmileDialogType;
import com.lotaai.canguiayw.smiledialog.interfac.OnCancelClickListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnConformClickListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnCountDownOverListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnEditConformClickListener;
/**
 * Author: wangbl
 * Date: 2019/5/8 3:21 PM
 * Email:js_wangbl@hotmail.com
 * Description:Builder 的 Options
 */
class DialogOptions {
    AppCompatActivity activity;
    //标题、内容、取消按钮、确定按钮文字(String)
    CharSequence titleText, contentText, cancelText, conformText, countDownNumber, editHint;
    //确定、取消背景颜色
    ColorStateList conformBgColor, cancelBgColor;
    //标题、内容、确认按钮、取消按钮字体颜色
    ColorStateList titleTextColor, contentTextColor, conformTextColor, cancelTextColor;
    //标题隐藏、Icon隐藏
    boolean isTitleHided, isIconHided ,isHidedButton;
    //确认按钮监听
    OnConformClickListener conformClickListener;
    //倒计时结束监听
    OnCountDownOverListener countdownOverListener;
    //修改框的确定事件
    OnEditConformClickListener editConformClickListener;
    //取消按钮监听
    OnCancelClickListener cancelClickListener;
    //dialog 类型枚举
    @SmileDialogType
    int type;
    //true:dialog弹出后会点击屏幕或物理返回键,dialog不消失
    boolean cancelable = true;
    // false:dialog弹出框是否显示输入框
    boolean editable = false;
    //  点击区域外,是否消失
    boolean cancelableOnTouchOutside = true;
    //动画
    Integer windowAnimation;
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/SmileDialog.java
New file
@@ -0,0 +1,126 @@
package com.lotaai.canguiayw.smiledialog;
import android.os.Build;
import androidx.annotation.RequiresApi;
import com.lotaai.canguiayw.smiledialog.enums.WidgetTypes;
import com.lotaai.canguiayw.smiledialog.interfac.SmileDialogImpl;
public class SmileDialog implements SmileDialogImpl, SmileDialogFragment.OnFragmentCreatedListener {
    private final DialogOptions mOptions;
    private SmileDialogFragment mDialogFragment;
    SmileDialog(DialogOptions mOptions) {
        this.mOptions = mOptions;
        initView();
    }
    private void initView() {
        mDialogFragment = new SmileDialogFragment();
        mDialogFragment.addOnFragmentCreatedListener(this);
    }
    @Override
    public void show() {
        if (mDialogFragment != null) {
            mOptions.activity.getSupportFragmentManager().beginTransaction().add(mDialogFragment,"tag").commitAllowingStateLoss();
           // mDialogFragment.show(mOptions.activity.getSupportFragmentManager(), "");
        }
    }
    @Override
    public void dismiss() {
        if (mDialogFragment != null) {
            mDialogFragment.dismiss();
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    @Override
    public void onFragmentCreated() {
        //设置对话框类型
        mDialogFragment.setDialogType(mOptions.type);
        //TITLE,设置文字
        if (mOptions.titleText != null) {
            mDialogFragment.setText(WidgetTypes.TITLE, mOptions.titleText);
        }
        //CONTENT,设置文字,
        if (mOptions.contentText != null) {
            mDialogFragment.setText(WidgetTypes.CONTENT, mOptions.contentText);
        }
        //确认按钮,设置文字
        if (mOptions.conformText != null) {
            mDialogFragment.setText(WidgetTypes.CONFORM, mOptions.conformText);
        }
        //取消按钮,设置文字,null时隐藏
        if (mOptions.cancelText != null) {
            mDialogFragment.setText(WidgetTypes.CANCEL, mOptions.cancelText);
        } else {
            mDialogFragment.hideCancelButton(true);
        }
        // 倒计时
        if(mOptions.countDownNumber !=null && !mOptions.countDownNumber.equals("")){
            mDialogFragment.startCountDown(mOptions.countDownNumber);
        }else{
            mDialogFragment.hideCountDown(true);
        }
        if(mOptions.editHint !=null) {
            mDialogFragment.setEditHint(mOptions.editHint);
        }
        //设置确认按钮背景颜色
        if (mOptions.conformBgColor != null) {
            mDialogFragment.setButtonBgColor(WidgetTypes.CONFORM, mOptions.conformBgColor);
        }
        //设置取消按钮背景颜色
        if (mOptions.cancelBgColor != null) {
            mDialogFragment.setButtonBgColor(WidgetTypes.CANCEL, mOptions.cancelBgColor);
        }
        //设置标题字体颜色
        if (mOptions.titleTextColor != null) {
            mDialogFragment.setTextColor(WidgetTypes.TITLE, mOptions.titleTextColor);
        }
        //设置内容字体颜色
        if (mOptions.contentTextColor != null) {
            mDialogFragment.setTextColor(WidgetTypes.CONTENT, mOptions.contentTextColor);
        }
        //设置确认按钮字体颜色
        if (mOptions.conformTextColor != null) {
            mDialogFragment.setTextColor(WidgetTypes.CONFORM, mOptions.conformTextColor);
        }
        //设置取消按钮字体颜色
        if (mOptions.cancelTextColor != null) {
            mDialogFragment.setTextColor(WidgetTypes.CANCEL, mOptions.cancelTextColor);
        }
        //是否显示输入框
        mDialogFragment.showEdit(mOptions.editable);
        //是否隐藏button
        mDialogFragment.hideConformButton(true);
        mDialogFragment.hideConformButton(mOptions.isHidedButton);
        //标题隐藏
        mDialogFragment.hideTitle(mOptions.isTitleHided);
        //设置确认按按钮点击事件
        mDialogFragment.addOnConformClickListener(mOptions.conformClickListener);
        // 设置倒计时结束的事件
        mDialogFragment.addOnCountDownOverListener(mOptions.countdownOverListener);
        //设置输入框确认按按钮点击事件
        mDialogFragment.addOnEditConformClickListener(mOptions.editConformClickListener);
        //设置取消按钮点击事件
        mDialogFragment.addOnCancelClickListener(mOptions.cancelClickListener);
        //按返回键,是否可取消
        mDialogFragment.setCancelable(mOptions.cancelable);
        //区域外可取消
        mDialogFragment.getDialog().setCanceledOnTouchOutside(mOptions.cancelableOnTouchOutside);
        //设置窗体动画
        if (mOptions.windowAnimation != null) {
            mDialogFragment.getDialog().getWindow().setWindowAnimations(mOptions.windowAnimation);
        }
        //隐藏Icon
        mDialogFragment.hideIcon(mOptions.isIconHided);
    }
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/SmileDialogBuilder.java
New file
@@ -0,0 +1,535 @@
package com.lotaai.canguiayw.smiledialog;
import android.content.res.ColorStateList;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.lotaai.canguiayw.smiledialog.enums.SmileDialogType;
import com.lotaai.canguiayw.smiledialog.interfac.OnCancelClickListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnConformClickListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnCountDownOverListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnEditConformClickListener;
/**
 * Author: wangbl
 * Date: 2019/5/8 3:17 PM
 * Email:js_wangbl@hotmail.com
 * Description: builder类
 */
public class SmileDialogBuilder {
    private final DialogOptions mOptions;
    /**
     * 构造方法(默认对话框类型是DialogType.WARNING)
     *
     * @param activity activity
     */
    public SmileDialogBuilder(AppCompatActivity activity) {
        this(activity, SmileDialogType.WARNING);
    }
    /**
     * 构造方法
     *
     * @param activity activity
     * @param type     对话框类型
     */
    public SmileDialogBuilder(AppCompatActivity activity, @SmileDialogType int type) {
        mOptions = new DialogOptions();
        mOptions.activity = activity;
        mOptions.type = type;
    }
    /**
     * 设置title文字
     *
     * @param text 文字
     * @return this
     */
    public SmileDialogBuilder setTitleText(@NonNull CharSequence text) {
        mOptions.titleText = text;
        return this;
    }
    /**
     * 设置title文字
     *
     * @param res 文字资源
     * @return this
     */
    public SmileDialogBuilder setTitleText(@StringRes int res) {
        mOptions.titleText = mOptions.activity.getText(res);
        return this;
    }
    /**
     * 设置内容文字
     *
     * @param text 文字
     * @return this
     */
    public SmileDialogBuilder setContentText(@NonNull CharSequence text) {
        mOptions.contentText = text;
        return this;
    }
    /**
     * 设置内容文字
     *
     * @param res 文字资源
     * @return this
     */
    public SmileDialogBuilder setContentText(@StringRes int res) {
        mOptions.contentText = mOptions.activity.getText(res);
        return this;
    }
    /**
     * 设置确认监听
     *
     * @param listener 监听事件
     * @return this
     */
    public SmileDialogBuilder setOnConformClickListener(OnConformClickListener listener) {
        mOptions.conformClickListener = listener;
        return this;
    }
    /**
     * 设置倒计时结束的监听
     *
     * @param listener 监听事件
     * @return this
     */
    public SmileDialogBuilder setOnCountDownOverListener(OnCountDownOverListener listener) {
        mOptions.countdownOverListener = listener;
        return this;
    }
    /**
     * 设置确认监听
     *
     * @param listener 监听事件
     * @return this
     */
    public SmileDialogBuilder setOnEditConformClickListener(OnEditConformClickListener listener) {
        mOptions.editConformClickListener = listener;
        return this;
    }
    /**
     * 设置取消监听
     *
     * @param listener 监听
     * @return this
     */
    public SmileDialogBuilder setOnCancelClickListener(OnCancelClickListener listener) {
        mOptions.cancelClickListener = listener;
        return this;
    }
    /**
     * 设置确定按钮文字
     *
     * @param text     文字
     * @param listener 监听
     * @return this
     */
    public SmileDialogBuilder setConformButton(@NonNull CharSequence text, OnConformClickListener listener) {
        mOptions.conformText = text;
        mOptions.conformClickListener = listener;
        return this;
    }
    /**
     * 设置倒计时和倒计时监听
     *
     * @param countdown  倒计时时间(秒)
     * @return this
     */
    public SmileDialogBuilder setCountDownNumber(@NonNull CharSequence countdown) {
        mOptions.countDownNumber = countdown;
        return this;
    }
    /**
     * 设置确定按钮文字
     *
     * @param text 文字
     * @return this
     */
    public SmileDialogBuilder setConformButton(@NonNull CharSequence text) {
        mOptions.conformText = text;
        return this;
    }
    /**
     * 设置确定按钮文字
     *
     * @param res 文字资源
     * @return this
     */
    public SmileDialogBuilder setConformButton(@StringRes int res) {
        mOptions.conformText = mOptions.activity.getText(res);
        return this;
    }
    /**
     * 设置确定按钮文字
     *
     * @param res      文字资源
     * @param listener 监听
     * @return this
     */
    public SmileDialogBuilder setConformButton(@StringRes int res, OnConformClickListener listener) {
        mOptions.conformText = mOptions.activity.getText(res);
        mOptions.conformClickListener = listener;
        return this;
    }
    /**
     * 设置取消按钮文字
     *
     * @param text 文字
     * @return this
     */
    public SmileDialogBuilder setCancelButton(@NonNull CharSequence text) {
        mOptions.cancelText = text;
        return this;
    }
    /**
     * 设置取消按钮文字
     *
     * @param res 文字Resource
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelButton(@StringRes int res) {
        mOptions.cancelText = mOptions.activity.getText(res);
        return this;
    }
    /**
     * 设置取消按钮文字
     *
     * @param listener 监听
     * @param text     文字
     * @return this
     */
    public SmileDialogBuilder setCancelButton(@NonNull CharSequence text, OnCancelClickListener listener) {
        mOptions.cancelText = text;
        mOptions.cancelClickListener = listener;
        return this;
    }
    /**
     * 设置取消按钮文字
     *
     * @param res      文字Resource
     * @param listener 监听
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelButton(@StringRes int res, OnCancelClickListener listener) {
        mOptions.cancelText = mOptions.activity.getText(res);
        mOptions.cancelClickListener = listener;
        return this;
    }
    /**
     * 确定按钮背景颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setConformBgColor(@ColorInt int color) {
        mOptions.conformBgColor = ColorStateList.valueOf(color);
        return this;
    }
    /**
     * 确定按钮背景颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setConformBgColor(ColorStateList color) {
        mOptions.conformBgColor = color;
        return this;
    }
    public SmileDialogBuilder setConformBgResColor(@ColorRes int color) {
        mOptions.conformBgColor = ContextCompat.getColorStateList(mOptions.activity, color);
        return this;
    }
    /**
     * 确定按钮背景颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelBgColor(ColorStateList color) {
        mOptions.cancelBgColor = color;
        return this;
    }
    /**
     * 确定按钮背景颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelBgResColor(@ColorRes int color) {
        mOptions.cancelBgColor = ContextCompat.getColorStateList(mOptions.activity, color);
        return this;
    }
    /**
     * 确定按钮背景颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelBgColor(@ColorInt int color) {
        mOptions.cancelBgColor = ColorStateList.valueOf(color);
        return this;
    }
    /**
     * 设置标题颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setTitleTextColor(@ColorInt int color) {
        mOptions.titleTextColor = ColorStateList.valueOf(color);
        return this;
    }
    /**
     * 设置标题颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setTitleTextColor(ColorStateList color) {
        mOptions.titleTextColor = color;
        return this;
    }
    /**
     * 设置标题颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setTitleTextResColor(@ColorRes int color) {
        mOptions.titleTextColor = ContextCompat.getColorStateList(mOptions.activity, color);
        return this;
    }
    /**
     * 设置内容颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setContentTextColor(@ColorInt int color) {
        mOptions.contentTextColor = ColorStateList.valueOf(color);
        return this;
    }
    /**
     * 设置内容颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setContentTextColor(ColorStateList color) {
        mOptions.contentTextColor = color;
        return this;
    }
    /**
     * 设置内容颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setContentTextResColor(@ColorRes int color) {
        mOptions.contentTextColor = ContextCompat.getColorStateList(mOptions.activity, color);
        return this;
    }
    /**
     * 设置确认按钮颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setConformTextColor(@ColorInt int color) {
        mOptions.conformTextColor = ColorStateList.valueOf(color);
        return this;
    }
    /**
     * 设置确认按钮颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setConformTextColor(ColorStateList color) {
        mOptions.conformTextColor = color;
        return this;
    }
    /**
     * 设置确认按钮颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setConformTextResColor(@ColorRes int color) {
        mOptions.conformTextColor = ContextCompat.getColorStateList(mOptions.activity, color);
        return this;
    }
    /**
     * 设置取消按钮颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelTextColor(@ColorInt int color) {
        mOptions.cancelTextColor = ColorStateList.valueOf(color);
        return this;
    }
    /**
     * 设置取消按钮颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelTextColor(ColorStateList color) {
        mOptions.cancelTextColor = color;
        return this;
    }
    /**
     * 设置取消按钮颜色
     *
     * @param color 颜色
     * @return 当前builder
     */
    public SmileDialogBuilder setCancelTextResColor(@ColorRes int color) {
        mOptions.cancelTextColor = ContextCompat.getColorStateList(mOptions.activity, color);
        return this;
    }
    /**
     * 隐藏标题,默认false
     *
     * @param isHided 是否隐藏
     * @return this
     */
    public SmileDialogBuilder hideTitle(boolean isHided) {
        mOptions.isTitleHided = isHided;
        return this;
    }
    /**
     * dialog弹出后会点击屏幕或物理返回键,dialog不消失
     *
     * @param cancelable 是否可取消
     * @return this
     */
    public SmileDialogBuilder setCancelable(boolean cancelable) {
        mOptions.cancelable = cancelable;
        return this;
    }
    /**
     * dialog弹窗修改框
     *
     * @param editable 是否可修改
     * @return this
     */
    public SmileDialogBuilder setEditable(boolean editable) {
        mOptions.editable = editable;
        return this;
    }
    /**
     * dialog弹窗修改框提示文字
     *
     * @param hint 是否可修改
     * @return this
     */
    public SmileDialogBuilder setEditHint(@NonNull CharSequence hint){
        mOptions.editHint = hint;
        return this;
    }
    /**
     * 点击区域外是否取消
     *
     * @param cancelableOnTouchOutside 是否取消
     * @return this
     */
    public SmileDialogBuilder setCanceledOnTouchOutside(boolean cancelableOnTouchOutside) {
        mOptions.cancelableOnTouchOutside = cancelableOnTouchOutside;
        return this;
    }
    /**
     * 设置窗体动画
     *
     * @param style 动画风格
     * @return this
     */
    public SmileDialogBuilder setWindowAnimations(@StyleRes int style) {
        mOptions.windowAnimation = style;
        return this;
    }
    /**
     * 隐藏Icon
     *
     * @param isHide 是否隐藏
     * @return this
     */
    public SmileDialogBuilder hideIcon(boolean isHide) {
        mOptions.isIconHided = isHide;
        return this;
    }
    /**
     * 隐藏Icon
     *
     * @param isHide 是否隐藏所有button
     * @return this
     */
    public SmileDialogBuilder hideButton(boolean isHide) {
        mOptions.isHidedButton = isHide;
        return this;
    }
    public SmileDialog build() {
        return new SmileDialog(mOptions);
    }
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/SmileDialogFragment.java
New file
@@ -0,0 +1,409 @@
package com.lotaai.canguiayw.smiledialog;
import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.DialogFragment;
import com.lotaai.canguiayw.R;
import com.lotaai.canguiayw.smiledialog.enums.SmileDialogType;
import com.lotaai.canguiayw.smiledialog.enums.WidgetTypes;
import com.lotaai.canguiayw.smiledialog.interfac.OnCancelClickListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnConformClickListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnCountDownOverListener;
import com.lotaai.canguiayw.smiledialog.interfac.OnEditConformClickListener;
public class SmileDialogFragment extends DialogFragment {
    private OnFragmentCreatedListener mListener;
    private OnCancelClickListener mCancelClickListener;
    private OnConformClickListener mConformClickListener;
    private OnEditConformClickListener mEditConformClickListener;
    private OnCountDownOverListener mCountDownOverListener;
    ImageView mIcon;
    TextView mTitle, mContent, mEdit, mOk, mCancel;
    TimeRunTextView time;
    public SmileDialogFragment() {
        // Required empty public constructor
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, R.style.SmileDialogStyle);
    }
    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        getDialog().getWindow().setWindowAnimations(R.style.dialog_anim_style);
        View view = inflater.inflate(R.layout.fragment_smile_dialog, container, false);
        mIcon = view.findViewById(R.id.iv_icon);
        mTitle = view.findViewById(R.id.tv_title);
        mContent = view.findViewById(R.id.tv_content);
        mEdit = view.findViewById(R.id.dialog_edit);
        mOk = view.findViewById(R.id.btn_ok);
        mCancel = view.findViewById(R.id.btn_cancel);
        time = view.findViewById(R.id.countdown);
        time.setTimeViewListener(new TimeRunTextView.OnTimeViewListener() {
            @Override
            public void onTimeStart() {
            }
            @Override
            public void onTimeEnd() {
                if(mCountDownOverListener!=null){
                    mCountDownOverListener.onOverClicked();
                }
                dismiss();
            }
        });
        mOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mConformClickListener != null) {
                    mConformClickListener.onConformClicked();
                }
                if(mEditConformClickListener !=null){
                    mEditConformClickListener.onConformClicked(mEdit.getText().toString());
                }
                time.initTime();
                dismiss();
            }
        });
        mCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCancelClickListener != null) {
                    mCancelClickListener.onCancelClickListener();
                }
                time.initTime();
                dismiss();
            }
        });
        return view;
    }
    @Override
    public void dismiss() {
        time.initTime();
        super.dismiss();
    }
    /**
     * 设置对话框类型
     *
     * @param type 类型
     */
    void setDialogType(@SmileDialogType int type) {
        if (type == SmileDialogType.WARNING) {
            mIcon.setImageResource(R.drawable.anim_warning);
        }
        if (type == SmileDialogType.SUCCESS) {
            mIcon.setImageResource(R.drawable.anim_success);
        }
        if (type == SmileDialogType.ERROR) {
            mIcon.setImageResource(R.drawable.anim_error);
        }
        Drawable drawable = mIcon.getDrawable();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
            if (drawable instanceof Animatable) {
                ((Animatable) drawable).start();
            }
        }
    }
    /**
     * 添加监听事件
     *
     * @param listener
     */
    void addOnFragmentCreatedListener(OnFragmentCreatedListener listener) {
        mListener = listener;
    }
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        if (mListener != null) {
            mListener.onFragmentCreated();
        }
        this.getDialog().setOnKeyListener(new DialogInterface.OnKeyListener(){
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event){
                // pass on to be processed as normal
                return keyCode == KeyEvent.KEYCODE_ENTER; // pretend we've processed it
            }
        });
        super.onViewCreated(view, savedInstanceState);
    }
    /**
     * 添加确认按钮点击事件
     *
     * @param listener 事件
     */
    void addOnConformClickListener(OnConformClickListener listener) {
        mConformClickListener = listener;
    }
    /**
     * 添加倒计时结束事件
     *
     * @param listener 事件
     */
    void addOnCountDownOverListener(OnCountDownOverListener listener){
        mCountDownOverListener = listener;
    }
    /**
     * 添加确认按钮点击事件
     *
     * @param listener 事件
     */
    void addOnEditConformClickListener(OnEditConformClickListener listener) {
        mEditConformClickListener = listener;
    }
    /**
     * 添加取消按钮点击事件
     *
     * @param listener 事件
     */
    void addOnCancelClickListener(OnCancelClickListener listener) {
        mCancelClickListener = listener;
    }
    /**
     * 根据枚举,找到对应的TextView
     *
     * @param widgets 控件枚举
     * @return 控件
     */
    private TextView getTextViewByWidgetType(@WidgetTypes int widgets) {
        if (widgets == WidgetTypes.TITLE) {
            return mTitle;
        }
        if (widgets == WidgetTypes.CONTENT) {
            return mContent;
        }
        if (widgets == WidgetTypes.CONFORM) {
            return mOk;
        }
        if (widgets == WidgetTypes.CANCEL) {
            return mCancel;
        }
        return null;
    }
    /**
     * 设置文字
     *
     * @param widgets 控件枚举
     * @param text    文字
     */
    void setText(@WidgetTypes int widgets, CharSequence text) {
        TextView mText = getTextViewByWidgetType(widgets);
        if (mText != null) {
            mText.setText(text);
        }
    }
    /**
     * 设置提示文字
     *
     * @param text    文字
     */
    void setEditHint(CharSequence text){
        if (text != null) {
            mEdit.setHint(text);
        }
    }
    /**
     * 隐藏取消按钮,true 隐藏、false 显示
     *
     * @param isHided 是否隐藏
     */
    public void hideCancelButton(boolean isHided) {
        if (isHided) {
            mCancel.setVisibility(View.GONE);
        } else {
            mCancel.setVisibility(View.VISIBLE);
        }
    }
    /**
     * 隐藏取消按钮,true 隐藏、false 显示
     *
     * @param isHided 是否隐藏
     */
    public void hideConformButton(boolean isHided) {
        if (isHided) {
            mOk.setVisibility(View.GONE);
        } else {
            mOk.setVisibility(View.VISIBLE);
        }
    }
    /**
     * 隐藏倒计时
     *
     * @param isHided 是否隐藏
     */
    void hideCountDown(boolean isHided) {
        if (isHided) {
            time.setVisibility(View.GONE);
        } else {
            time.setVisibility(View.VISIBLE);
        }
    }
    /**
     * 开始倒计时
     * @param number
     */
    void startCountDown(CharSequence number){
        if(time!=null){
            time.startTime(Long.parseLong(number.toString()), "3");
        }
    }
    /**
     * 隐藏title
     *
     * @param isHided 是否隐藏
     */
    void hideTitle(boolean isHided) {
        if (isHided) {
            mTitle.setVisibility(View.GONE);
        }else{
            mTitle.setVisibility(View.VISIBLE);
        }
    }
    /**
     * 是否显示输入框
     * @param isShow
     */
    void showEdit(boolean isShow) {
        if(isShow){
            mEdit.setVisibility(View.VISIBLE);
        }else{
            mEdit.setVisibility(View.GONE);
        }
    }
    /**
     * 设置字体颜色
     *
     * @param widgets 控件
     * @param color   颜色
     */
    void setTextColor(@WidgetTypes int widgets, ColorStateList color) {
        TextView mText = getTextViewByWidgetType(widgets);
        if (mText != null) {
            mText.setTextColor(color);
        }
    }
    /**
     * 设置控件的背景颜色
     *
     * @param widgets 控件
     * @param color   颜色
     */
    void setButtonBgColor(@WidgetTypes int widgets, ColorStateList color) {
        TextView button = getTextViewByWidgetType(widgets);
        if (button != null) {
            setButtonColor(button, color);
        }
    }
    /**
     * 隐藏Icon
     *
     * @param isHide 是否隐藏
     */
    void hideIcon(boolean isHide) {
        if (isHide) {
            mIcon.setVisibility(View.GONE);
        } else {
            mIcon.setVisibility(View.VISIBLE);
        }
    }
    /**
     * 设置按钮背景颜色
     *
     * @param button         按钮
     * @param colorStateList 颜色
     */
    private void setButtonColor(TextView button, ColorStateList colorStateList) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            button.setBackgroundTintList(colorStateList);
            button.setBackgroundTintMode(PorterDuff.Mode.SRC);
        } else {
            ViewCompat.setBackgroundTintList(button, colorStateList);
            ViewCompat.setBackgroundTintMode(button, PorterDuff.Mode.SRC);
        }
    }
    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }
    /**
     * 监听Fragment 已创建 onViewCreated中调用
     */
    interface OnFragmentCreatedListener {
        void onFragmentCreated();
    }
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/TimeRunTextView.java
New file
@@ -0,0 +1,188 @@
package com.lotaai.canguiayw.smiledialog;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.Nullable;
import java.util.Timer;
import java.util.TimerTask;
@SuppressLint("AppCompatCustomView")
public class TimeRunTextView extends TextView {
    private long mHour;//小时
    private long mMin;//分钟
    private long mSecond;//秒
    private OnTimeViewListener timeViewListener;//时间结束
    private String MODE = "1";//时间展示模式
    private Timer timer = null;
    private TimerTask timerTask = null;
    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String getResult = (String) msg.obj;
            TimeRunTextView.this.setText(getResult);
        }
    };
    public TimeRunTextView(Context context) {
        super(context);
    }
    public TimeRunTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    public TimeRunTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public void setTimeViewListener(OnTimeViewListener timeViewListener) {
        this.timeViewListener = timeViewListener;
    }
    public void startTime(long timeCount, String mode) {
        initTime();//先清空时间的工具类
        if (!TextUtils.isEmpty(mode)) {
            this.MODE = mode;
        }
        startTime(timeCount);
    }
    public void changeTime(long timeCount){
        mHour = timeCount / (60 * 60);  //  对3600 取整  就是小时
        mMin = (timeCount % (60 * 60)) / 60;//  对3600 取余除以60 就是多出的分
        mSecond = timeCount % 60; //  对60 取余  就是多出的秒
    }
    public void startTime(long timeCount) {
        initTime();//先清空时间的工具类
        mHour = timeCount / (60 * 60);  //  对3600 取整  就是小时
        mMin = (timeCount % (60 * 60)) / 60;//  对3600 取余除以60 就是多出的分
        mSecond = timeCount % 60; //  对60 取余  就是多出的秒
        if (timer == null) {
            timer = new Timer();
        }
        if (timerTask == null) {
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    if ((mHour + mMin + mSecond) > 0) {
                        ComputeTime();//计算时分秒
                    } else {
                        stopTime();
                    }
                }
            };
        }
        timer.schedule(timerTask, 0, 1000);
        if (timeViewListener != null) {
            timeViewListener.onTimeStart();
        }
    }
    public void stopTime() {
        try {
            if (timerTask != null) {
                timerTask.cancel();
                timerTask = null;
            }
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        } catch (Exception e) {
        }
        if (timeViewListener != null) {
            timeViewListener.onTimeEnd();
        }
    }
    public void initTime() {
        try {
            if (timerTask != null) {
                timerTask.cancel();
                timerTask = null;
            }
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        } catch (Exception e) {
        }
    }
    private void ComputeTime() {
        if (mSecond == 0) {
            //  秒为0  判断min 是否为0
            if (mMin == 0) {
                //  分为0 判断hour
                if (mHour == 0) {
                    Log.e("mcy--", "时间结束"); //  秒 分 时  都为0  倒计时结束
                } else {
                    //  此处为hour 不为0 秒 分 为0  所以 hour-- 秒 分 为 59
                    mHour--;
                    mMin = 59;
                    mSecond = 59;
                }
            } else {
                //  分不为0  所以不用修改 hour  分减一即可 秒 变为 59
                mMin--;
                mSecond = 59;
            }
        } else {
            //  秒不为0  秒减一 分 和时  不变 继续循环
            mSecond--;
        }
        String strTime = "";
        switch (MODE) {
            case "1":
                strTime = mHour + "时" + mMin + "分" + mSecond + "秒";
                break;
            case "2":
                strTime = mHour + ":" + mMin + ":" + mSecond;
                break;
            case "3":
                mSecond = mHour * 3600 + mMin * 60 + mSecond;
                mHour = 0;
                mMin = 0;
                strTime = mSecond + "s";
                break;
            default:
                strTime = mHour + "时" + mMin + "分" + mSecond + "秒";
                break;
        }
        Message msg = Message.obtain();
        msg.obj = strTime;   //从这里把你想传递的数据放进去就行了
        handler.sendMessage(msg);
    }
    public interface OnTimeViewListener {
        void onTimeStart();
        void onTimeEnd();
    }
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/enums/SmileDialogType.java
New file
@@ -0,0 +1,18 @@
package com.lotaai.canguiayw.smiledialog.enums;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static com.lotaai.canguiayw.smiledialog.enums.SmileDialogType.ERROR;
import static com.lotaai.canguiayw.smiledialog.enums.SmileDialogType.SUCCESS;
import static com.lotaai.canguiayw.smiledialog.enums.SmileDialogType.WARNING;
@Retention(RetentionPolicy.SOURCE)
@IntDef({WARNING, SUCCESS, ERROR})
public @interface SmileDialogType {
    int WARNING = 0;
    int SUCCESS = 1;
    int ERROR = 2;
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/enums/WidgetTypes.java
New file
@@ -0,0 +1,23 @@
package com.lotaai.canguiayw.smiledialog.enums;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
 * Author: wangbl
 * Date: 2019-07-15 10:57
 * Email:js_wangbl@hotmail.com
 * Description:控件类型
 */
@Retention(RetentionPolicy.SOURCE)
@IntDef({WidgetTypes.TITLE, WidgetTypes.CONTENT, WidgetTypes.CONFORM, WidgetTypes.CANCEL})
public @interface WidgetTypes {
    int TITLE = 0;
    int CONTENT = 1;
    int CONFORM = 2;
    int CANCEL = 3;
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnCancelClickListener.java
New file
@@ -0,0 +1,11 @@
package com.lotaai.canguiayw.smiledialog.interfac;
/**
 * Author: wangbl
 * Date: 2019/5/9 11:33 AM
 * Email:js_wangbl@hotmail.com
 * Description:取消按钮监听
 */
public interface OnCancelClickListener {
    void onCancelClickListener();
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnConformClickListener.java
New file
@@ -0,0 +1,11 @@
package com.lotaai.canguiayw.smiledialog.interfac;
/**
 * Author: wangbl
 * Date: 2019/5/9 11:33 AM
 * Email:js_wangbl@hotmail.com
 * Description:确认按钮监听
 */
public interface OnConformClickListener {
    void onConformClicked();
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnCountDownOverListener.java
New file
@@ -0,0 +1,11 @@
package com.lotaai.canguiayw.smiledialog.interfac;
/**
 * Author: wangbl
 * Date: 2019/5/9 11:33 AM
 * Email:js_wangbl@hotmail.com
 * Description:确认按钮监听
 */
public interface OnCountDownOverListener {
    void onOverClicked();
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/OnEditConformClickListener.java
New file
@@ -0,0 +1,11 @@
package com.lotaai.canguiayw.smiledialog.interfac;
/**
 * Author: wangbl
 * Date: 2019/5/9 11:33 AM
 * Email:js_wangbl@hotmail.com
 * Description:确认按钮监听
 */
public interface OnEditConformClickListener {
    void onConformClicked(String result);
}
app/src/main/java/com/lotaai/canguiayw/smiledialog/interfac/SmileDialogImpl.java
New file
@@ -0,0 +1,16 @@
package com.lotaai.canguiayw.smiledialog.interfac;
/**
 * Author: wangbl
 * Date: 2019/5/8 4:01 PM
 * Email:js_wangbl@hotmail.com
 * Description:dialog 提供对外方法
 */
public interface SmileDialogImpl {
    void show();
    void dismiss();
}
app/src/main/java/com/lotaai/canguiayw/sqllitedb/DaoMaster.java
@@ -14,13 +14,14 @@
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
 * Master of DAO (schema version 4): knows all DAOs.
 * Master of DAO (schema version 8): knows all DAOs.
 */
public class DaoMaster extends AbstractDaoMaster {
    public static final int SCHEMA_VERSION = 4;
    public static final int SCHEMA_VERSION = 8;
    /** Creates underlying database table using DAOs. */
    public static void createAllTables(Database db, boolean ifNotExists) {
        GridModelDao.createTable(db, ifNotExists);
        OrderDao.createTable(db, ifNotExists);
        OrderDetailDao.createTable(db, ifNotExists);
        TestDao.createTable(db, ifNotExists);
@@ -28,6 +29,7 @@
    /** Drops underlying database table using DAOs. */
    public static void dropAllTables(Database db, boolean ifExists) {
        GridModelDao.dropTable(db, ifExists);
        OrderDao.dropTable(db, ifExists);
        OrderDetailDao.dropTable(db, ifExists);
        TestDao.dropTable(db, ifExists);
@@ -49,6 +51,7 @@
    public DaoMaster(Database db) {
        super(db, SCHEMA_VERSION);
        registerDaoClass(GridModelDao.class);
        registerDaoClass(OrderDao.class);
        registerDaoClass(OrderDetailDao.class);
        registerDaoClass(TestDao.class);
app/src/main/java/com/lotaai/canguiayw/sqllitedb/DaoSession.java
@@ -8,10 +8,12 @@
import org.greenrobot.greendao.identityscope.IdentityScopeType;
import org.greenrobot.greendao.internal.DaoConfig;
import com.lotaai.canguiayw.sqllitedb.GridModel;
import com.lotaai.canguiayw.sqllitedb.Order;
import com.lotaai.canguiayw.sqllitedb.OrderDetail;
import com.lotaai.canguiayw.sqllitedb.Test;
import com.lotaai.canguiayw.sqllitedb.GridModelDao;
import com.lotaai.canguiayw.sqllitedb.OrderDao;
import com.lotaai.canguiayw.sqllitedb.OrderDetailDao;
import com.lotaai.canguiayw.sqllitedb.TestDao;
@@ -25,10 +27,12 @@
 */
public class DaoSession extends AbstractDaoSession {
    private final DaoConfig gridModelDaoConfig;
    private final DaoConfig orderDaoConfig;
    private final DaoConfig orderDetailDaoConfig;
    private final DaoConfig testDaoConfig;
    private final GridModelDao gridModelDao;
    private final OrderDao orderDao;
    private final OrderDetailDao orderDetailDao;
    private final TestDao testDao;
@@ -36,6 +40,9 @@
    public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
            daoConfigMap) {
        super(db);
        gridModelDaoConfig = daoConfigMap.get(GridModelDao.class).clone();
        gridModelDaoConfig.initIdentityScope(type);
        orderDaoConfig = daoConfigMap.get(OrderDao.class).clone();
        orderDaoConfig.initIdentityScope(type);
@@ -46,21 +53,28 @@
        testDaoConfig = daoConfigMap.get(TestDao.class).clone();
        testDaoConfig.initIdentityScope(type);
        gridModelDao = new GridModelDao(gridModelDaoConfig, this);
        orderDao = new OrderDao(orderDaoConfig, this);
        orderDetailDao = new OrderDetailDao(orderDetailDaoConfig, this);
        testDao = new TestDao(testDaoConfig, this);
        registerDao(GridModel.class, gridModelDao);
        registerDao(Order.class, orderDao);
        registerDao(OrderDetail.class, orderDetailDao);
        registerDao(Test.class, testDao);
    }
    
    public void clear() {
        gridModelDaoConfig.clearIdentityScope();
        orderDaoConfig.clearIdentityScope();
        orderDetailDaoConfig.clearIdentityScope();
        testDaoConfig.clearIdentityScope();
    }
    public GridModelDao getGridModelDao() {
        return gridModelDao;
    }
    public OrderDao getOrderDao() {
        return orderDao;
    }
app/src/main/java/com/lotaai/canguiayw/sqllitedb/GridModel.java
New file
@@ -0,0 +1,62 @@
package com.lotaai.canguiayw.sqllitedb;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Generated;
@Entity
public class GridModel {
    @Id(autoincrement = true)
    private Long id;
    private int guiHao;
    private int gridNo;
    private int state;//0-空闲  1-占用  2-锁定不可用
    @Generated(hash = 298840528)
    public GridModel(Long id, int guiHao, int gridNo, int state) {
        this.id = id;
        this.guiHao = guiHao;
        this.gridNo = gridNo;
        this.state = state;
    }
    @Generated(hash = 1303993848)
    public GridModel() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public int getGuiHao() {
        return this.guiHao;
    }
    public void setGuiHao(int guiHao) {
        this.guiHao = guiHao;
    }
    public int getGridNo() {
        return this.gridNo;
    }
    public void setGridNo(int gridNo) {
        this.gridNo = gridNo;
    }
    public int getState() {
        return this.state;
    }
    public void setState(int state) {
        this.state = state;
    }
}
app/src/main/java/com/lotaai/canguiayw/sqllitedb/Order.java
@@ -15,18 +15,24 @@
    @NotNull
    private String gridNo;
    @NotNull
    private String xuHao;
    @NotNull
    private int state;//状态;0-未存餐 1-已存餐 2-已取餐 3-取消
    private String putInDate;
    private String takeCode;
    @Generated(hash = 878135649)
    public Order(Long id, String orderNo, @NotNull String gridNo, int state,
            String putInDate, String takeCode) {
    private String createTime;
    @Generated(hash = 1824136278)
    public Order(Long id, String orderNo, @NotNull String gridNo,
            @NotNull String xuHao, int state, String putInDate, String takeCode,
            String createTime) {
        this.id = id;
        this.orderNo = orderNo;
        this.gridNo = gridNo;
        this.xuHao = xuHao;
        this.state = state;
        this.putInDate = putInDate;
        this.takeCode = takeCode;
        this.createTime = createTime;
    }
    @Generated(hash = 1105174599)
    public Order() {
@@ -49,6 +55,12 @@
    public void setGridNo(String gridNo) {
        this.gridNo = gridNo;
    }
    public String getXuHao() {
        return this.xuHao;
    }
    public void setXuHao(String xuHao) {
        this.xuHao = xuHao;
    }
    public int getState() {
        return this.state;
    }
@@ -67,5 +79,10 @@
    public void setTakeCode(String takeCode) {
        this.takeCode = takeCode;
    }
    public String getCreateTime() {
        return this.createTime;
    }
    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }
    }
app/src/main/java/com/lotaai/canguiayw/sqllitedb/OrderDao.java
@@ -25,9 +25,11 @@
        public final static Property Id = new Property(0, Long.class, "id", true, "_id");
        public final static Property OrderNo = new Property(1, String.class, "orderNo", false, "ORDER_NO");
        public final static Property GridNo = new Property(2, String.class, "gridNo", false, "GRID_NO");
        public final static Property State = new Property(3, int.class, "state", false, "STATE");
        public final static Property PutInDate = new Property(4, String.class, "putInDate", false, "PUT_IN_DATE");
        public final static Property TakeCode = new Property(5, String.class, "takeCode", false, "TAKE_CODE");
        public final static Property XuHao = new Property(3, String.class, "xuHao", false, "XU_HAO");
        public final static Property State = new Property(4, int.class, "state", false, "STATE");
        public final static Property PutInDate = new Property(5, String.class, "putInDate", false, "PUT_IN_DATE");
        public final static Property TakeCode = new Property(6, String.class, "takeCode", false, "TAKE_CODE");
        public final static Property CreateTime = new Property(7, String.class, "createTime", false, "CREATE_TIME");
    }
@@ -46,9 +48,11 @@
                "\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
                "\"ORDER_NO\" TEXT UNIQUE ," + // 1: orderNo
                "\"GRID_NO\" TEXT NOT NULL ," + // 2: gridNo
                "\"STATE\" INTEGER NOT NULL ," + // 3: state
                "\"PUT_IN_DATE\" TEXT," + // 4: putInDate
                "\"TAKE_CODE\" TEXT);"); // 5: takeCode
                "\"XU_HAO\" TEXT NOT NULL ," + // 3: xuHao
                "\"STATE\" INTEGER NOT NULL ," + // 4: state
                "\"PUT_IN_DATE\" TEXT," + // 5: putInDate
                "\"TAKE_CODE\" TEXT," + // 6: takeCode
                "\"CREATE_TIME\" TEXT);"); // 7: createTime
    }
    /** Drops the underlying database table. */
@@ -71,16 +75,22 @@
            stmt.bindString(2, orderNo);
        }
        stmt.bindString(3, entity.getGridNo());
        stmt.bindLong(4, entity.getState());
        stmt.bindString(4, entity.getXuHao());
        stmt.bindLong(5, entity.getState());
 
        String putInDate = entity.getPutInDate();
        if (putInDate != null) {
            stmt.bindString(5, putInDate);
            stmt.bindString(6, putInDate);
        }
 
        String takeCode = entity.getTakeCode();
        if (takeCode != null) {
            stmt.bindString(6, takeCode);
            stmt.bindString(7, takeCode);
        }
        String createTime = entity.getCreateTime();
        if (createTime != null) {
            stmt.bindString(8, createTime);
        }
    }
@@ -98,16 +108,22 @@
            stmt.bindString(2, orderNo);
        }
        stmt.bindString(3, entity.getGridNo());
        stmt.bindLong(4, entity.getState());
        stmt.bindString(4, entity.getXuHao());
        stmt.bindLong(5, entity.getState());
 
        String putInDate = entity.getPutInDate();
        if (putInDate != null) {
            stmt.bindString(5, putInDate);
            stmt.bindString(6, putInDate);
        }
 
        String takeCode = entity.getTakeCode();
        if (takeCode != null) {
            stmt.bindString(6, takeCode);
            stmt.bindString(7, takeCode);
        }
        String createTime = entity.getCreateTime();
        if (createTime != null) {
            stmt.bindString(8, createTime);
        }
    }
@@ -122,9 +138,11 @@
            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // orderNo
            cursor.getString(offset + 2), // gridNo
            cursor.getInt(offset + 3), // state
            cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4), // putInDate
            cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5) // takeCode
            cursor.getString(offset + 3), // xuHao
            cursor.getInt(offset + 4), // state
            cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5), // putInDate
            cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6), // takeCode
            cursor.isNull(offset + 7) ? null : cursor.getString(offset + 7) // createTime
        );
        return entity;
    }
@@ -134,9 +152,11 @@
        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
        entity.setOrderNo(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));
        entity.setGridNo(cursor.getString(offset + 2));
        entity.setState(cursor.getInt(offset + 3));
        entity.setPutInDate(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4));
        entity.setTakeCode(cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5));
        entity.setXuHao(cursor.getString(offset + 3));
        entity.setState(cursor.getInt(offset + 4));
        entity.setPutInDate(cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5));
        entity.setTakeCode(cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6));
        entity.setCreateTime(cursor.isNull(offset + 7) ? null : cursor.getString(offset + 7));
     }
    
    @Override
app/src/main/java/com/lotaai/canguiayw/sqllitedb/SqlliteDbManage.java
@@ -2,6 +2,7 @@
import com.blankj.utilcode.util.LogUtils;
import com.lotaai.canguiayw.application.ActivityLifecycleApplcation;
import com.lotaai.canguiayw.device.service.CrontrolGridModel;
import org.greenrobot.greendao.query.QueryBuilder;
@@ -43,6 +44,19 @@
     */
    public void insertOrUpdateOrderDetailInfo(OrderDetail model) {
        DaoSession daoSession = getDaoSession();
        List<OrderDetail> details =  selectOrtderDetails(model.getOrderNo());
        if(details!=null && details.size()>0){
            for (int i =0; i < details.size(); i++){
                 OrderDetail d = details.get(i);
                 if (d.getItemName().trim().equals(model.getItemName())){
                     model.setId(d.getId());
                     break;
                 }
                 if (d.getItemName().trim().equals("")){
                     daoSession.delete(d);
                 }
            }
        }
        daoSession.insertOrReplace(model);
    }
@@ -54,19 +68,52 @@
     * @return
     */
    public List<Order> selectOrtdersByState(int state) {
        LogUtils.i("selectOrtdersByState:" + state);
        DaoSession daoSession = getDaoSession();
        QueryBuilder<Order> qb = daoSession.queryBuilder(Order.class);
//        QueryBuilder<Order> queryBuilder
//                = qb.where(OrderDao.Properties.State.eq(state)).orderAsc(OrderDao.Properties.OrderNo);
        QueryBuilder<Order> queryBuilder
                = qb.where(OrderDao.Properties.OrderNo.like("GB%")).orderAsc(OrderDao.Properties.OrderNo);
                = qb.where(OrderDao.Properties.State.eq(state)).orderAsc(OrderDao.Properties.TakeCode);
        List<Order> ordersList = queryBuilder.list();
        if (ordersList == null || ordersList.size() == 0) {
            return null;
        }
        return ordersList;
    }
    /**
     * 根据查询订单信息
     *
     * @return
     */
    public List<Order> selectOrtdersInGui() {
        DaoSession daoSession = getDaoSession();
        QueryBuilder<Order> qb = daoSession.queryBuilder(Order.class);
        QueryBuilder<Order> queryBuilder
                = qb.where(OrderDao.Properties.State.in(0,1)).orderAsc(OrderDao.Properties.TakeCode);
        List<Order> ordersList = queryBuilder.list();
        if (ordersList == null || ordersList.size() == 0) {
            return null;
        }
        return ordersList;
    }
    /**
     * 根据取餐码查询订单信息
     *
     * @param takeCode 取餐码
     * @return
     */
    public Order selectOrtderByTakeCode(String takeCode) {
        DaoSession daoSession = getDaoSession();
        QueryBuilder<Order> qb = daoSession.queryBuilder(Order.class);
        QueryBuilder<Order> queryBuilder
                = qb.where(OrderDao.Properties.TakeCode.eq(takeCode)).orderAsc(OrderDao.Properties.OrderNo);
        List<Order> ordersList = queryBuilder.list();
        if (ordersList == null || ordersList.size() == 0) {
            return null;
        }
        return ordersList.get(0);
    }
    /**
@@ -88,6 +135,24 @@
    }
    /**
     * 根据订单号查询订单信息
     *
     * @param xuhao
     * @return
     */
    public Order selectOrtderByXuhao(String xuhao) {
        DaoSession daoSession = getDaoSession();
        QueryBuilder<Order> qb = daoSession.queryBuilder(Order.class);
        QueryBuilder<Order> queryBuilder
                = qb.where(OrderDao.Properties.XuHao.eq(xuhao)).orderAsc(OrderDao.Properties.OrderNo);
        List<Order> ordersList = queryBuilder.list();
        if (ordersList == null || ordersList.size() == 0) {
            return null;
        }
        return ordersList.get(0);
    }
    /**
     * 根据订单号查询订单明细信息
     *
     * @param orderNo
@@ -97,7 +162,7 @@
        DaoSession daoSession = getDaoSession();
        QueryBuilder<OrderDetail> qb = daoSession.queryBuilder(OrderDetail.class);
        QueryBuilder<OrderDetail> queryBuilder
                = qb.where(OrderDetailDao.Properties.OrderNo.eq(orderNo)).orderAsc(OrderDao.Properties.OrderNo);
                = qb.where(OrderDetailDao.Properties.OrderNo.eq(orderNo)).orderAsc(OrderDetailDao.Properties.OrderNo);
        List<OrderDetail> orderDetailList = queryBuilder.list();
        if (orderDetailList == null || orderDetailList.size() == 0) {
            return null;
@@ -119,4 +184,70 @@
        }
    }
    //新增格子
    public void addGrid(GridModel model){
        DaoSession daoSession = getDaoSession();
        daoSession.insertOrReplace(model);
    }
    /**
     * 根据柜子号和格子号查询
     * @param gui
     * @param gridNo
     * @return
     */
    public GridModel selectGridByNo(int gui,int gridNo){
        DaoSession daoSession = getDaoSession();
        QueryBuilder<GridModel> qb = daoSession.queryBuilder(GridModel.class);
        QueryBuilder<GridModel> queryBuilder
                = qb.where(GridModelDao.Properties.GuiHao.eq(gui),GridModelDao.Properties.GridNo.eq(gridNo)).orderAsc(GridModelDao.Properties.Id);
        List<GridModel> gridModels = queryBuilder.list();
        if (gridModels == null || gridModels.size() == 0) {
            return null;
        }
        return gridModels.get(0);
    }
    /**
     * 根据柜子号查询
     * @param gui
     * @return
     */
    public List<GridModel> selectGridByGui(int gui){
        DaoSession daoSession = getDaoSession();
        QueryBuilder<GridModel> qb = daoSession.queryBuilder(GridModel.class);
        QueryBuilder<GridModel> queryBuilder
                = qb.where(GridModelDao.Properties.GuiHao.eq(gui)).orderAsc(GridModelDao.Properties.Id);
        List<GridModel> gridModels = queryBuilder.list();
        if (gridModels == null || gridModels.size() == 0) {
            return null;
        }
        return gridModels;
    }
    public GridModel  selectFreeGrid(){
        DaoSession daoSession = getDaoSession();
        QueryBuilder<GridModel> qb = daoSession.queryBuilder(GridModel.class);
        QueryBuilder<GridModel> queryBuilder
                = qb.where(GridModelDao.Properties.State.eq(0)).orderAsc(GridModelDao.Properties.GuiHao);
        List<GridModel> gridModels = queryBuilder.list();
        if (gridModels == null || gridModels.size() == 0) {
            return null;
        }
        return gridModels.get(0);
    }
    public GridModel  selectGridByGridNoStr(String str){
        CrontrolGridModel mode = new CrontrolGridModel();
        mode.ChangeGrid(str);
        DaoSession daoSession = getDaoSession();
        QueryBuilder<GridModel> qb = daoSession.queryBuilder(GridModel.class);
        QueryBuilder<GridModel> queryBuilder
                = qb.where(GridModelDao.Properties.GuiHao.eq(mode.getGuiNo()),GridModelDao.Properties.GridNo.eq(mode.getGridNo())).orderAsc(GridModelDao.Properties.GuiHao);
        List<GridModel> gridModels = queryBuilder.list();
        if (gridModels == null || gridModels.size() == 0) {
            return null;
        }
        return gridModels.get(0);
    }
}
app/src/main/java/com/lotaai/canguiayw/view/GridTableAdapter.java
@@ -15,6 +15,7 @@
import com.lotaai.canguiayw.R;
import com.lotaai.canguiayw.device.CanguiStatus;
import com.lotaai.canguiayw.device.service.CanGuiService;
import com.lotaai.canguiayw.device.service.CrontrolGridModel;
import java.util.List;
import java.util.Map;
@@ -67,9 +68,9 @@
        if (mData != null && mData.size() > 0) {
           CanguiStatus status  =   mData.get(position);
           if (status.getSelect()){
               vh.gridLineLayout.setBackgroundColor(Color.GRAY);
           }else {
               vh.gridLineLayout.setBackgroundColor(mContext.getResources().getColor(R.color.cheng));
           }else {
               vh.gridLineLayout.setBackgroundColor(Color.GRAY);
           }
           if (status.isJiareIsOpen()){
               vh.jiarestatus.setImageResource(R.mipmap.jiareopen);
@@ -111,7 +112,9 @@
                vh.orderNo.setText(status.getOrderNo());
            }
            vh.gridNo.setText(Integer.toString(status.getGridNo()));
            String ss = CrontrolGridModel.getGridNoStr(status.getGuiHao(),status.getGridNo());
            vh.gridNo.setText(ss);
           // vh.gridNo.setText(Integer.toString(status.getGridNo()));
        }
        return convertView;
    }
app/src/main/res/anim/bottom_detail_in.xml
New file
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="300"
        android:fromYDelta="100%"
        android:toYDelta="0"
        android:fillBefore="true"  />
</set>
app/src/main/res/anim/bottom_detail_out.xml
New file
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="300"
        android:fromYDelta="0"
        android:toYDelta="100%"
        android:fillBefore="true"  />
</set>
app/src/main/res/anim/cycle_7.xml
New file
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:cycles="7"/>
app/src/main/res/anim/shake.xml
New file
@@ -0,0 +1,5 @@
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0"
    android:interpolator="@anim/cycle_7"
    android:toXDelta="10"/>
app/src/main/res/anim/smile_dialog_enter.xml
New file
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--从下部进入到中间-->
    <translate
        android:duration="400"
        android:fromYDelta="100%"
        android:toYDelta="0"/>
    <!--淡入-->
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="400"/>
</set>
app/src/main/res/anim/smile_dialog_exit.xml
New file
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--从中间到底部退出-->
    <translate
        android:duration="400"
        android:fromYDelta="0"
        android:toYDelta="100%"/>
    <!--淡出-->
    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration="400"/>
</set>
app/src/main/res/animator/animator_path.xml
New file
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:interpolator="@android:interpolator/decelerate_cubic"
    android:propertyName="trimPathStart"
    android:repeatCount="0"
    android:repeatMode="reverse"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType"></objectAnimator>
app/src/main/res/drawable/anim_error.xml
New file
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/svg_error"
    tools:targetApi="lollipop">
    <target
        android:name="ic_err_0"
        android:animation="@animator/animator_path" />
    <target
        android:name="ic_err_1"
        android:animation="@animator/animator_path" />
    <target
        android:name="ic_round"
        android:animation="@animator/animator_path" />
</animated-vector>
app/src/main/res/drawable/anim_success.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/svg_success"
    tools:targetApi="lollipop">
    <target
        android:name="ic_gou"
        android:animation="@animator/animator_path" />
    <target
        android:name="ic_round"
        android:animation="@animator/animator_path" />
</animated-vector>
app/src/main/res/drawable/anim_warning.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/svg_warning"
    tools:targetApi="lollipop">
    <target
        android:name="ic_warn"
        android:animation="@animator/animator_path" />
    <target
        android:name="ic_round"
        android:animation="@animator/animator_path" />
</animated-vector>
app/src/main/res/drawable/bg_smile_dialog.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="16dp" />
    <solid android:color="@android:color/white" />
</shape>
app/src/main/res/drawable/bg_smile_dialog_cancel_button.xml
New file
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <corners android:radius="50dp" />
    <stroke android:width="1dp" android:color="#666666" />
    <!--    <gradient-->
    <!--        android:angle="90"-->
    <!--        android:endColor="#BABCBD"-->
    <!--        android:startColor="#929394" />-->
    <!--    <corners android:radius="6dp" />-->
</shape>
app/src/main/res/drawable/bg_smile_dialog_ok_button.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="50dp" />
    <gradient
        android:angle="90"
        android:endColor="#03A9F4"
        android:startColor="#2196F3" />
    <!--    <corners android:radius="6dp" />-->
</shape>
app/src/main/res/drawable/svg_error.xml
New file
@@ -0,0 +1,25 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="50dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <path
        android:name="ic_err_0"
        android:pathData="M30,70 L70,30"
        android:strokeWidth="5"
        android:strokeColor="@android:color/holo_red_dark"
        android:strokeLineCap="round" />
    <path
        android:name="ic_err_1"
        android:pathData="M70,70 L30,30"
        android:strokeWidth="5"
        android:strokeColor="@android:color/holo_red_dark"
        android:strokeLineCap="round" />
    <path
        android:name="ic_round"
        android:pathData="M50,2a48,48 0,1 0,48,48A48,48 0,0 0,50,2z"
        android:strokeWidth="3"
        android:strokeColor="@android:color/holo_red_dark" />
</vector>
app/src/main/res/drawable/svg_success.xml
New file
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="50dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <path
        android:name="ic_gou"
        android:pathData="M80,35 L41,69 Q40,70 39,69 L20,50"
        android:strokeWidth="5"
        android:strokeColor="@android:color/holo_green_dark"
        android:strokeLineCap="round" />
    <path
        android:name="ic_round"
        android:pathData="M50,2a48,48 0,1 0,48,48A48,48 0,0 0,50,2z"
        android:strokeWidth="3"
        android:strokeColor="@android:color/holo_green_dark" />
</vector>
app/src/main/res/drawable/svg_warning.xml
New file
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="50dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <path
        android:name="ic_warn"
        android:pathData="M50,70 L50,20 M50,80 L50,80.2"
        android:strokeWidth="5"
        android:strokeColor="@android:color/holo_orange_light"
        android:strokeLineCap="round" />
    <path
        android:name="ic_round"
        android:pathData="M50,2a48,48 0,1 0,48,48A48,48 0,0 0,50,2z"
        android:strokeWidth="3"
        android:strokeColor="@android:color/holo_orange_light" />
</vector>
app/src/main/res/layout/fragment_smile_dialog.xml
New file
@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:background="@drawable/bg_smile_dialog"
        android:gravity="center"
        android:minHeight="300dp"
        android:minWidth="450dp"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context=".SmileDialogFragment">
        <ImageView
            android:id="@+id/iv_icon"
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:layout_marginTop="10dp"
            app:srcCompat="@drawable/anim_warning" />
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ellipsize="middle"
            android:gravity="center"
            android:maxLength="16"
            android:paddingTop="20dp"
            android:text="@string/smile_dialog_title"
            android:textColor="#333333"
            android:textSize="30sp" />
        <TextView
            android:id="@+id/tv_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:gravity="center"
            android:text="@string/smile_dialog_content"
            android:textColor="#666666"
            android:textSize="25sp" />
        <com.lotaai.canguiayw.smiledialog.TimeRunTextView
            android:id="@+id/countdown"
            android:layout_width="80dp"
            android:layout_height="60dp"
            android:textAlignment="center"
            android:gravity="center"
            android:layout_centerHorizontal="true"
            android:text="30S"
            android:textColor="@color/xui_config_color_red"
            android:textSize="30dp" />
        <EditText
            android:id="@+id/dialog_edit"
            android:layout_width="300dp"
            android:layout_height="50dp"
            android:gravity="center"
            android:background="@drawable/bg_edit_1"
            android:hint="内容"
            android:layout_marginBottom="15dp"
            android:inputType="textNoSuggestions"
            android:textColorHint="@color/bg_color_box_btn_disable"
            android:textAlignment="center"
            android:textColor="@color/xui_config_color_pure_black"
            android:maxLength="30"
            android:visibility="gone"
            android:textSize="30sp"/>
        <LinearLayout
            android:id="@+id/btn_line"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">
            <Button
                android:id="@+id/btn_cancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/bg_smile_dialog_cancel_button"
                android:gravity="center"
                android:minWidth="120dp"
                android:padding="8dp"
                android:text="@string/smile_dialog_cancel"
                android:textColor="#666666"
                android:textSize="21sp" />
            <Button
                android:id="@+id/btn_ok"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/bg_smile_dialog_ok_button"
                android:gravity="center"
                android:minWidth="120dp"
                android:padding="8dp"
                android:text="@string/smile_dialog_ok"
                android:textColor="@color/smile_dialog_btn_ok"
                android:textSize="21sp" />
        </LinearLayout>
    </LinearLayout>
</FrameLayout>
app/src/main/res/layout/framgment_cuncan.xml
@@ -33,7 +33,7 @@
                        android:layout_height="80dp"
                        android:gravity="center"
                        android:background="@drawable/round_editstyle"
                        android:hint="单号后四位"
                        android:hint="取餐序号"
                        android:textColorHint="@color/white"
                        android:textAlignment="center"
                        android:textColor="@color/white"
@@ -192,12 +192,13 @@
                    android:textSize="30dp"
                    android:text="格口:"/>
                <TextView
                    android:id="@+id/geKoueText"
                    android:layout_width="150dp"
                    android:layout_height="match_parent"
                    android:textColor="@color/cheng"
                    android:gravity="center"
                    android:textSize="50dp"
                    android:text="15"/>
                    android:text=""/>
                <TextView
                    android:layout_width="100dp"
                    android:layout_height="match_parent"
@@ -206,12 +207,13 @@
                    android:gravity="right|center_vertical"
                    android:text="订单:"/>
                <TextView
                    android:id="@+id/orderNoText"
                    android:layout_width="300dp"
                    android:layout_height="match_parent"
                    android:textColor="@color/white"
                    android:textSize="30dp"
                    android:gravity="center"
                    android:text="20230568458912"/>
                    android:text=""/>
            </LinearLayout>
        </LinearLayout>
app/src/main/res/layout/framgment_selectorder.xml
@@ -4,14 +4,78 @@
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:gravity="center"
    android:background="@color/bgcolor"
    android:orientation="vertical" >
    android:gravity="center"
    android:orientation="vertical">
    <com.bin.david.form.core.SmartTable
        android:id="@+id/table"
        android:layout_margin="10dp"
        android:layout_marginTop="1dp"
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
        android:layout_height="match_parent">
        <com.bin.david.form.core.SmartTable
            android:id="@+id/table"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:layout_marginTop="1dp" />
        <ViewSwitcher
            android:id="@+id/bottom_detail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:background="@color/black"
            android:clickable="true"
            android:focusable="true"
            android:inAnimation="@anim/bottom_detail_in"
            android:outAnimation="@anim/bottom_detail_out"
            android:persistentDrawingCache="animation"
            android:visibility="gone">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <com.bin.david.form.core.SmartTable
                    android:id="@+id/detailtable"
                    android:layout_width="wrap_content"
                    android:layout_height="400dp"
                    android:layout_margin="10dp" />
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:gravity="center"
                    android:orientation="horizontal">
                    <Button
                        android:id="@+id/closeDetail"
                        android:layout_width="250dp"
                        android:layout_height="80dp"
                        android:layout_below="@+id/bottom_detail"
                        android:layout_gravity="center"
                        android:layout_margin="10dp"
                        android:layout_marginTop="20dp"
                        android:background="@drawable/circular_button_blue"
                        android:gravity="center"
                        android:text="关闭"
                        android:textSize="30dp" />
                    <Button
                        android:id="@+id/takeOut"
                        android:layout_width="250dp"
                        android:layout_height="80dp"
                        android:layout_below="@+id/bottom_detail"
                        android:layout_gravity="center"
                        android:layout_margin="10dp"
                        android:layout_marginTop="20dp"
                        android:background="@drawable/circular_button"
                        android:gravity="center"
                        android:text="取出"
                        android:textSize="30dp" />
                </LinearLayout>
            </LinearLayout>
        </ViewSwitcher>
    </RelativeLayout>
</LinearLayout>
app/src/main/res/layout/framgment_setting.xml
@@ -20,6 +20,7 @@
            android:textColor="@color/white"
            android:textSize="30dp" />
        <EditText
            android:id="@+id/deviceCode"
            android:layout_width="300dp"
            android:layout_height="80dp"
            android:layout_margin="10dp"
@@ -40,12 +41,14 @@
            android:textColor="@color/white"
            android:textSize="30dp" />
        <EditText
            android:id="@+id/devicePwd"
            android:layout_width="300dp"
            android:layout_height="80dp"
            android:layout_margin="10dp"
            android:gravity="center"
            android:background="@drawable/round_editstyle"
            android:hint="设备秘钥"
            android:inputType="textPassword"
            android:textColorHint="@color/white"
            android:textAlignment="center"
            android:textColor="@color/white"
@@ -74,6 +77,7 @@
            android:layout_width="150dp"
            android:layout_height="80dp"
            android:layout_margin="10dp"
            android:visibility="invisible"
            android:gravity="right|center_vertical"
            android:text="副柜数量:"
            android:textColor="@color/white"
@@ -82,6 +86,7 @@
            android:layout_width="300dp"
            android:layout_height="80dp"
            android:layout_margin="10dp"
            android:visibility="invisible"
            android:gravity="center"
            android:background="@drawable/round_editstyle"
            android:hint=""
app/src/main/res/values/colors.xml
@@ -11,4 +11,13 @@
    <color name="DarkGray">#696969</color>
    <color name="lessBlack">#67524d</color>
    <color name="blue">#0066ff</color>
    <color name="smile_dialog_btn_ok">#FFFFFF</color>
    <color name="smile_dialog_btn_cancel">#FFFFFF</color>
    <color name="xui_config_color_red">#DC143C</color>
    <color name="xui_config_color_pure_black">#696969</color>
    <color name="bg_color_box_btn_normal">#ff0000ff</color>
    <color name="bg_color_box_btn_pressed">#ffffff00</color>
    <color name="bg_color_box_btn_occupy">#ffff0000</color>
    <color name="bg_color_box_btn_unlocked">#ffff8800</color>
    <color name="bg_color_box_btn_disable">#ff888888</color>
</resources>
app/src/main/res/values/strings.xml
@@ -1,3 +1,7 @@
<resources>
    <string name="app_name">canguiayw</string>
    <string name="smile_dialog_title" translatable="false">提示</string>
    <string name="smile_dialog_content" translatable="false">这是一条提示内容信息!</string>
    <string name="smile_dialog_cancel" translatable="false">取消</string>
    <string name="smile_dialog_ok" translatable="false">确定</string>
</resources>
app/src/main/res/values/styles.xml
@@ -14,4 +14,11 @@
        <item name="android:windowIsTranslucent">true</item>
    </style>
    <style name="SmileDialogStyle" parent="Theme.AppCompat.Dialog.Alert"></style>
    <style name="dialog_anim_style" parent="android:Animation">
        <!--进入时的动画-->
        <item name="android:windowEnterAnimation">@anim/smile_dialog_enter</item>
        <!--退出时的动画-->
        <item name="android:windowExitAnimation">@anim/smile_dialog_exit</item>
    </style>
</resources>