From b40382d2c2a3acfc0d1099fe923ada14bf27097b Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Thu, 4 Mar 2021 11:42:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E5=90=88=E6=9D=A5=E8=87=AAxiaoyuanhos?= =?UTF-8?q?t/TranspondSms=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v3.6.1 1,添加多重规则。 2,添加规则测试按钮。 3,转发规则发送方列表页面支持长按删除。 4,整合逻辑 --- .../idormy/sms/forwarder/RuleActivity.java | 197 ++++++-- .../idormy/sms/forwarder/SenderActivity.java | 32 ++ .../idormy/sms/forwarder/model/RuleModel.java | 182 +++++--- .../idormy/sms/forwarder/utils/RuleLine.java | 423 ++++++++++++++++++ .../sms/forwarder/utils/RuleLineUtils.java | 134 ++++++ .../idormy/sms/forwarder/utils/SendUtil.java | 137 ++---- .../sms/forwarder/utils/SettingUtil.java | 5 +- .../activity_alter_dialog_setview_rule.xml | 36 +- ...ctivity_alter_dialog_setview_rule_test.xml | 60 +++ app/src/main/res/layout/activity_rule.xml | 9 + app/src/main/res/layout/activity_sender.xml | 37 +- app/src/main/res/values/strings.xml | 2 + 12 files changed, 1047 insertions(+), 207 deletions(-) create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/RuleLineUtils.java create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_rule_test.xml diff --git a/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java b/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java index fccb6baa..5bee327e 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java +++ b/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java @@ -2,13 +2,15 @@ package com.idormy.sms.forwarder; import android.content.DialogInterface; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; -import android.widget.LinearLayout; import android.widget.ListView; +import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; @@ -19,13 +21,18 @@ import androidx.appcompat.app.AppCompatActivity; import com.idormy.sms.forwarder.adapter.RuleAdapter; import com.idormy.sms.forwarder.model.RuleModel; import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.model.vo.SmsVo; import com.idormy.sms.forwarder.utils.RuleUtil; +import com.idormy.sms.forwarder.utils.SendUtil; import com.idormy.sms.forwarder.utils.SenderUtil; import com.umeng.analytics.MobclickAgent; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import static com.idormy.sms.forwarder.SenderActivity.NOTIFY; + public class RuleActivity extends AppCompatActivity { private String TAG = "RuleActivity"; @@ -35,11 +42,23 @@ public class RuleActivity extends AppCompatActivity { private Long selectSenderId = 0l; private String selectSenderName = ""; + //消息处理者,创建一个Handler的子类对象,目的是重写Handler的处理消息的方法(handleMessage()) + private Handler handler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NOTIFY: + Toast.makeText(RuleActivity.this, msg.getData().getString("DATA"), Toast.LENGTH_LONG).show(); + break; + } + } + }; + @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "oncreate"); super.onCreate(savedInstanceState); - setContentView(R.layout.activity_sender); + setContentView(R.layout.activity_rule); RuleUtil.init(RuleActivity.this); SenderUtil.init(RuleActivity.this); @@ -48,7 +67,7 @@ public class RuleActivity extends AppCompatActivity { adapter = new RuleAdapter(RuleActivity.this, R.layout.rule_item, ruleModels); // 将适配器上的数据传递给listView - ListView listView = findViewById(R.id.list_view_sender); + ListView listView = findViewById(R.id.list_view_rule); listView.setAdapter(adapter); // 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法 @@ -61,7 +80,39 @@ public class RuleActivity extends AppCompatActivity { setRule(ruleModel); } }); + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { + //定义AlertDialog.Builder对象,当长按列表项的时候弹出确认删除对话框 + AlertDialog.Builder builder = new AlertDialog.Builder(RuleActivity.this); + builder.setMessage("确定删除?"); + builder.setTitle("提示"); + + //添加AlertDialog.Builder对象的setPositiveButton()方法 + builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + RuleUtil.delRule(ruleModels.get(position).getId()); + initRules(); + adapter.del(ruleModels); + Toast.makeText(getBaseContext(), "删除列表项", Toast.LENGTH_SHORT).show(); + } + }); + + //添加AlertDialog.Builder对象的setNegativeButton()方法 + builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + + } + }); + + builder.create().show(); + return true; + } + }); } // 初始化数据 @@ -69,49 +120,21 @@ public class RuleActivity extends AppCompatActivity { ruleModels = RuleUtil.getRule(null, null); } - public void addSender(View view) { + public void addRule(View view) { setRule(null); } - private void setRule(final RuleModel ruleModel) { final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(RuleActivity.this); final View view1 = View.inflate(RuleActivity.this, R.layout.activity_alter_dialog_setview_rule, null); final RadioGroup radioGroupRuleFiled = (RadioGroup) view1.findViewById(R.id.radioGroupRuleFiled); - final LinearLayout matchTypeLayout = (LinearLayout) view1.findViewById(R.id.matchTypeLayout); - final LinearLayout matchValueLayout = (LinearLayout) view1.findViewById(R.id.matchValueLayout); - if (ruleModel != null) { - int id = ruleModel.getRuleFiledCheckId(); - radioGroupRuleFiled.check(id); - if (id != 0) { - matchTypeLayout.setVisibility(View.GONE); - matchValueLayout.setVisibility(View.GONE); - } else { - matchTypeLayout.setVisibility(View.VISIBLE); - matchValueLayout.setVisibility(View.VISIBLE); - } - } - radioGroupRuleFiled.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(RadioGroup group, int checkedId) { - //Toast.makeText(RuleActivity.this, "Checked:" + checkedId, Toast.LENGTH_LONG).show(); - switch (checkedId) { - case R.id.btnTranspondAll: - matchTypeLayout.setVisibility(View.GONE); - matchValueLayout.setVisibility(View.GONE); - break; - default: - matchTypeLayout.setVisibility(View.VISIBLE); - matchValueLayout.setVisibility(View.VISIBLE); - break; - } - } - }); + if (ruleModel != null) radioGroupRuleFiled.check(ruleModel.getRuleFiledCheckId()); final RadioGroup radioGroupRuleCheck = (RadioGroup) view1.findViewById(R.id.radioGroupRuleCheck); if (ruleModel != null) radioGroupRuleCheck.check(ruleModel.getRuleCheckCheckId()); + final TextView tv_mu_rule_tips = (TextView) view1.findViewById(R.id.tv_mu_rule_tips); final TextView ruleSenderTv = (TextView) view1.findViewById(R.id.ruleSenderTv); if (ruleModel != null && ruleModel.getSenderId() != null) { List getSeners = SenderUtil.getSender(ruleModel.getSenderId(), null); @@ -124,7 +147,7 @@ public class RuleActivity extends AppCompatActivity { btSetRuleSender.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - //Toast.makeText(RuleActivity.this, "selectSender", Toast.LENGTH_LONG).show(); + Toast.makeText(RuleActivity.this, "selectSender", Toast.LENGTH_LONG).show(); selectSender(ruleSenderTv); } }); @@ -133,8 +156,12 @@ public class RuleActivity extends AppCompatActivity { if (ruleModel != null) editTextRuleValue.setText(ruleModel.getValue()); + //当更新选择的字段的时候,更新之下各个选项的状态 + refreshSelectRadioGroupRuleFiled(radioGroupRuleFiled, radioGroupRuleCheck, editTextRuleValue, tv_mu_rule_tips); + Button buttonruleok = view1.findViewById(R.id.buttonruleok); Button buttonruledel = view1.findViewById(R.id.buttonruledel); + Button buttonruletest = view1.findViewById(R.id.buttonruletest); alertDialog71 .setTitle(R.string.setrule) .setView(view1) @@ -183,6 +210,78 @@ public class RuleActivity extends AppCompatActivity { show.dismiss(); } }); + buttonruletest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Object senderId = ruleSenderTv.getTag(); + if (senderId == null) { + Toast.makeText(RuleActivity.this, "请先创建选择发送方", Toast.LENGTH_LONG).show(); + } else { + if (ruleModel == null) { + RuleModel newRuleModel = new RuleModel(); + newRuleModel.setFiled(RuleModel.getRuleFiledFromCheckId(radioGroupRuleFiled.getCheckedRadioButtonId())); + newRuleModel.setCheck(RuleModel.getRuleCheckFromCheckId(radioGroupRuleCheck.getCheckedRadioButtonId())); + newRuleModel.setValue(editTextRuleValue.getText().toString()); + newRuleModel.setSenderId(Long.valueOf(senderId.toString())); + + testRule(newRuleModel, Long.valueOf(senderId.toString())); + + } else { + ruleModel.setFiled(RuleModel.getRuleFiledFromCheckId(radioGroupRuleFiled.getCheckedRadioButtonId())); + ruleModel.setCheck(RuleModel.getRuleCheckFromCheckId(radioGroupRuleCheck.getCheckedRadioButtonId())); + ruleModel.setValue(editTextRuleValue.getText().toString()); + ruleModel.setSenderId(Long.valueOf(senderId.toString())); + + testRule(ruleModel, Long.valueOf(senderId.toString())); + + } + + + } + + } + }); + + } + + //当更新选择的字段的时候,更新之下各个选项的状态 + // 如果设置了转发全部,禁用选择模式和匹配值输入 + // 如果设置了多重规则,选择模式置为是 + private void refreshSelectRadioGroupRuleFiled(RadioGroup radioGroupRuleFiled, final RadioGroup radioGroupRuleCheck, final EditText editTextRuleValue, final TextView tv_mu_rule_tips) { + refreshSelectRadioGroupRuleFiledAction(radioGroupRuleFiled.getCheckedRadioButtonId(), radioGroupRuleCheck, editTextRuleValue, tv_mu_rule_tips); + + radioGroupRuleFiled.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + refreshSelectRadioGroupRuleFiledAction(checkedId, radioGroupRuleCheck, editTextRuleValue, tv_mu_rule_tips); + } + }); + } + + private void refreshSelectRadioGroupRuleFiledAction(int checkedRuleFiledId, final RadioGroup radioGroupRuleCheck, final EditText editTextRuleValue, final TextView tv_mu_rule_tips) { + tv_mu_rule_tips.setVisibility(View.GONE); + + switch (checkedRuleFiledId) { + case R.id.btnTranspondAll: + for (int i = 0; i < radioGroupRuleCheck.getChildCount(); i++) { + ((RadioButton) radioGroupRuleCheck.getChildAt(i)).setEnabled(false); + } + editTextRuleValue.setEnabled(false); + break; + case R.id.btnMultiMatch: + for (int i = 0; i < radioGroupRuleCheck.getChildCount(); i++) { + ((RadioButton) radioGroupRuleCheck.getChildAt(i)).setEnabled(false); + } + editTextRuleValue.setEnabled(true); + tv_mu_rule_tips.setVisibility(View.VISIBLE); + break; + default: + for (int i = 0; i < radioGroupRuleCheck.getChildCount(); i++) { + ((RadioButton) radioGroupRuleCheck.getChildAt(i)).setEnabled(true); + } + editTextRuleValue.setEnabled(true); + break; + } } public void selectSender(final TextView showTv) { @@ -208,13 +307,39 @@ public class RuleActivity extends AppCompatActivity { builder.show(); } + public void testRule(final RuleModel ruleModel, final Long senderId) { + final View view = View.inflate(RuleActivity.this, R.layout.activity_alter_dialog_setview_rule_test, null); + final EditText editTextTestPhone = (EditText) view.findViewById(R.id.editTextTestPhone); + final EditText editTextTestMsgContent = (EditText) view.findViewById(R.id.editTextTestMsgContent); + Button buttonruletest = view.findViewById(R.id.buttonruletest); + AlertDialog.Builder ad1 = new AlertDialog.Builder(RuleActivity.this); + ad1.setTitle("测试规则"); + ad1.setIcon(android.R.drawable.ic_dialog_info); + ad1.setView(view); + buttonruletest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + Log.i("editTextTestPhone", editTextTestPhone.getText().toString()); + Log.i("editTextTestMsgContent", editTextTestMsgContent.getText().toString()); + + try { + SmsVo testSmsVo = new SmsVo(editTextTestPhone.getText().toString(), editTextTestMsgContent.getText().toString(), new Date(), editTextTestPhone.getText().toString()); + SendUtil.sendMsgByRuleModelSenderId(handler, ruleModel, testSmsVo, senderId); + } catch (Exception e) { + Toast.makeText(RuleActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); + } + } + }); + ad1.show();// 显示对话框 + } + @Override protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); } - @Override protected void onResume() { super.onResume(); diff --git a/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java index d773815b..91f45001 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java +++ b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java @@ -115,7 +115,39 @@ public class SenderActivity extends AppCompatActivity { } }); + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { + //定义AlertDialog.Builder对象,当长按列表项的时候弹出确认删除对话框 + AlertDialog.Builder builder = new AlertDialog.Builder(SenderActivity.this); + builder.setMessage("确定删除?"); + builder.setTitle("提示"); + + //添加AlertDialog.Builder对象的setPositiveButton()方法 + builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SenderUtil.delSender(senderModels.get(position).getId()); + initSenders(); + adapter.del(senderModels); + Toast.makeText(getBaseContext(), "删除列表项", Toast.LENGTH_SHORT).show(); + } + }); + + //添加AlertDialog.Builder对象的setNegativeButton()方法 + builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + + } + }); + + builder.create().show(); + return true; + } + }); } // 初始化数据 diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java index 6887d6b8..3311fbd2 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java +++ b/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java @@ -1,15 +1,30 @@ package com.idormy.sms.forwarder.model; +import android.util.Log; + import com.idormy.sms.forwarder.R; +import com.idormy.sms.forwarder.model.vo.SmsVo; +import com.idormy.sms.forwarder.utils.RuleLineUtils; import java.util.HashMap; import java.util.Map; public class RuleModel { + private String TAG = "RuleModel"; + private Long id; public static final String FILED_TRANSPOND_ALL = "transpond_all"; public static final String FILED_PHONE_NUM = "phone_num"; public static final String FILED_MSG_CONTENT = "msg_content"; + public static final String FILED_MULTI_MATCH="multi_match"; public static final Map FILED_MAP = new HashMap(); + static{ + FILED_MAP.put("transpond_all", "转发全部"); + FILED_MAP.put("phone_num", "手机号"); + FILED_MAP.put("msg_content", "内容"); + FILED_MAP.put("multi_match", "多重匹配"); + } + private String filed; + public static final String CHECK_IS = "is"; public static final String CHECK_CONTAIN = "contain"; public static final String CHECK_START_WITH = "startwith"; @@ -17,12 +32,6 @@ public class RuleModel { public static final String CHECK_NOT_IS = "notis"; public static final Map CHECK_MAP = new HashMap(); - static { - FILED_MAP.put("transpond_all", "全部"); - FILED_MAP.put("phone_num", "手机号"); - FILED_MAP.put("msg_content", "内容"); - } - static { CHECK_MAP.put("is", "是"); CHECK_MAP.put("contain", "包含"); @@ -30,9 +39,6 @@ public class RuleModel { CHECK_MAP.put("endwith", "结尾是"); CHECK_MAP.put("notis", "不是"); } - - private Long id; - private String filed; private String check; private String value; @@ -40,6 +46,83 @@ public class RuleModel { private Long senderId; private Long time; + //字段分支 + public boolean checkMsg(SmsVo msg) throws Exception { + + //检查这一行和上一行合并的结果是否命中 + boolean mixChecked=false; + if(msg!=null){ + //先检查规则是否命中 + switch (this.filed){ + case FILED_TRANSPOND_ALL: + mixChecked= true; + break; + case FILED_PHONE_NUM: + mixChecked= checkValue(msg.getMobile()); + break; + case FILED_MSG_CONTENT: + mixChecked= checkValue(msg.getContent()); + break; + case FILED_MULTI_MATCH: + mixChecked= RuleLineUtils.checkRuleLines(msg,this.value); + break; + default: + break; + + } + } + + + Log.i(TAG, "rule:"+this+" checkMsg:"+msg+" checked:"+mixChecked); + return mixChecked; + + } + + //内容分支 + public boolean checkValue(String msgValue){ + boolean checked=false; + + if(this.value!=null){ + switch (this.check){ + case CHECK_IS: + checked=this.value.equals(msgValue); + break; + case CHECK_CONTAIN: + if(msgValue!=null){ + checked=msgValue.contains(this.value); + } + break; + case CHECK_START_WITH: + if(msgValue!=null){ + checked=msgValue.startsWith(this.value); + } + break; + case CHECK_END_WITH: + if(msgValue!=null){ + checked=msgValue.endsWith(this.value); + } + break; + default: + break; + } + } + + Log.i(TAG, "checkValue "+msgValue+" "+this.check+" "+this.value+" checked:"+checked); + + return checked; + + } + + + public String getRuleMatch() { + switch (filed){ + case FILED_TRANSPOND_ALL: + return "全部转发到 "; + default: + return "当 "+FILED_MAP.get(filed)+" "+CHECK_MAP.get(check)+" "+value+" 转发到 "; + } + + } public static String getRuleMatch(String filed, String check, String value) { switch (filed) { case FILED_TRANSPOND_ALL: @@ -51,19 +134,53 @@ public class RuleModel { } - public static String getRuleFiledFromCheckId(int id) { - switch (id) { + public Long getRuleSenderId() { + return senderId; + } + + public int getRuleFiledCheckId(){ + switch (filed){ + case FILED_MSG_CONTENT: + return R.id.btnContent; + case FILED_PHONE_NUM: + return R.id.btnPhone; + case FILED_MULTI_MATCH: + return R.id.btnMultiMatch; + default: + return R.id.btnTranspondAll; + } + } + + public static String getRuleFiledFromCheckId(int id){ + switch (id){ case R.id.btnContent: return FILED_MSG_CONTENT; case R.id.btnPhone: return FILED_PHONE_NUM; + case R.id.btnMultiMatch: + return FILED_MULTI_MATCH; default: return FILED_TRANSPOND_ALL; } } - public static String getRuleCheckFromCheckId(int id) { - switch (id) { + public int getRuleCheckCheckId(){ + switch (check){ + case CHECK_CONTAIN: + return R.id.btnContain; + case CHECK_START_WITH: + return R.id.btnStartWith; + case CHECK_END_WITH: + return R.id.btnEndWith; + case CHECK_NOT_IS: + return R.id.btnNotIs; + default: + return R.id.btnIs; + } + } + + public static String getRuleCheckFromCheckId(int id){ + switch (id){ case R.id.btnContain: return CHECK_CONTAIN; case R.id.btnStartWith: @@ -125,45 +242,6 @@ public class RuleModel { this.value = value; } - public String getRuleMatch() { - switch (filed) { - case FILED_TRANSPOND_ALL: - return "全部转发到 "; - default: - return "当 " + FILED_MAP.get(filed) + " " + CHECK_MAP.get(check) + " " + value + " 转发到 "; - } - - } - - public Long getRuleSenderId() { - return senderId; - } - - public int getRuleFiledCheckId() { - switch (filed) { - case FILED_MSG_CONTENT: - return R.id.btnContent; - case FILED_PHONE_NUM: - return R.id.btnPhone; - default: - return R.id.btnTranspondAll; - } - } - - public int getRuleCheckCheckId() { - switch (check) { - case CHECK_CONTAIN: - return R.id.btnContain; - case CHECK_START_WITH: - return R.id.btnStartWith; - case CHECK_END_WITH: - return R.id.btnEndWith; - case CHECK_NOT_IS: - return R.id.btnNotIs; - default: - return R.id.btnIs; - } - } @Override public String toString() { diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.java b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.java new file mode 100644 index 00000000..69dc1051 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.java @@ -0,0 +1,423 @@ +package com.idormy.sms.forwarder.utils; + + +import android.util.Log; + +import com.idormy.sms.forwarder.model.vo.SmsVo; + +import java.util.ArrayList; +import java.util.List; + +class RuleLine { + static String TAG = "RuleLine"; + static Boolean STARTLOG = true; + + //开头有几个空格 + int headSpaceNum = 0; + RuleLine beforeRuleLine; + RuleLine nextRuleLine; + RuleLine parentRuleLine; + RuleLine childRuleLine; + //and or + String conjunction; + public static List CONJUNCTION_LIST = new ArrayList(); + public static final String CONJUNCTION_AND = "并且"; + public static final String CONJUNCTION_OR = "或者"; + + static { + CONJUNCTION_LIST.add("and"); + CONJUNCTION_LIST.add("or"); + CONJUNCTION_LIST.add("并且"); + CONJUNCTION_LIST.add("或者"); + } + + //手机号 短信内容 + String field; + public static List FILED_LIST = new ArrayList(); + public static final String FILED_PHONE_NUM = "手机号"; + public static final String FILED_MSG_CONTENT = "短信内容"; + + static { + FILED_LIST.add("手机号"); + FILED_LIST.add("短信内容"); + } + + // 是否 + String sure; + public static List SURE_LIST = new ArrayList(); + public static final String SURE_YES = "是"; + public static final String SURE_NOT = "不是"; + + static { + SURE_LIST.add("是"); + SURE_LIST.add("不是"); + } + + String check; + public static List CHECK_LIST = new ArrayList(); + public static final String CHECK_EQUALS = "相等"; + public static final String CHECK_CONTAIN = "包含"; + public static final String CHECK_START_WITH = "开头"; + public static final String CHECK_END_WITH = "结尾"; + + static { + CHECK_LIST.add("相等"); + CHECK_LIST.add("包含"); + CHECK_LIST.add("开头"); + CHECK_LIST.add("结尾"); + } + + String value; + + //字段分支 + public boolean checkMsg(SmsVo msg) { + + //检查这一行和上一行合并的结果是否命中 + boolean mixChecked = false; + + //先检查规则是否命中 + switch (this.field) { + case FILED_PHONE_NUM: + mixChecked = checkValue(msg.getMobile()); + break; + case FILED_MSG_CONTENT: + mixChecked = checkValue(msg.getContent()); + break; + default: + break; + + } + + //整合肯定词 + switch (this.sure) { + case SURE_YES: + mixChecked = mixChecked; + break; + case SURE_NOT: + mixChecked = !mixChecked; + break; + default: + mixChecked = false; + break; + + } + + logg("rule:" + this + " checkMsg:" + msg + " checked:" + mixChecked); + return mixChecked; + + } + + //内容分支 + public boolean checkValue(String msgValue) { + boolean checked = false; + + switch (this.check) { + case CHECK_EQUALS: + checked = this.value.equals(msgValue); + break; + case CHECK_CONTAIN: + if (msgValue != null) { + checked = msgValue.contains(this.value); + } + break; + case CHECK_START_WITH: + if (msgValue != null) { + checked = msgValue.startsWith(this.value); + } + break; + case CHECK_END_WITH: + if (msgValue != null) { + checked = msgValue.endsWith(this.value); + } + break; + default: + break; + } + logg("checkValue " + msgValue + " " + this.check + " " + this.value + " checked:" + checked); + + return checked; + + } + + public RuleLine(String line, int linenum, RuleLine beforeRuleLine) throws Exception { + logg("----------" + linenum + "-----------------"); + logg(line); + //规则检验: + //并且 是 手机号 相等 10086 + //[并且, 是, 手机号, 相等, 10086] + // 并且 是 内容 包含 asfas + //[, , 并且, 是, 内容, 包含, asfas] + + //处理头空格数用来确认跟上一行节点的相对位置:是同级还是子级 + //处理4个字段,之后的全部当做value + + //标记3个阶段 + boolean isCountHeading = false; + boolean isDealMiddel = false; + boolean isDealValue = false; + + //用于保存4个中间体: 并且, 是, 内容, 包含 + List middleList = new ArrayList<>(4); + //保存每个中间体字符串 + StringBuilder buildMiddleWord = new StringBuilder(); + StringBuilder valueBuilder = new StringBuilder(); + + for (int i = 0; i < line.length(); i++) { + String w = String.valueOf(line.charAt(i)); + logg("walk over:" + w); + + //控制阶段 + //开始处理头 + if (i == 0) { + if (" ".equals(w)) { + logg("start to isCountHeading:"); + + isCountHeading = true; + } else { + //直接进入处理中间体阶段 + isCountHeading = false; + isDealMiddel = true; + logg("start to isDealMiddel:"); + } + + } + //正在数空格头,但是遇到非空格,阶段变更:由处理空头阶段 变为 处理 中间体阶段 + if (isCountHeading && (!" ".equals(w))) { + logg("isCountHeading to isDealMiddel:"); + + isCountHeading = false; + isDealMiddel = true; + } + + //正在处理中间体,中间体数量够了,阶段变更:由处理中间体 变为 处理 value + if (isDealMiddel && middleList.size() == 4) { + logg("isDealMiddel done middleList:" + middleList); + logg("isDealMiddel to isDealValue:"); + isDealMiddel = false; + isDealValue = true; + } + + logg("isCountHeading:" + isCountHeading); + logg("isDealMiddel:" + isDealMiddel); + logg("isDealValue:" + isDealValue); + + if (isCountHeading) { + if (" ".equals(w)) { + logg("headSpaceNum++:" + headSpaceNum); + headSpaceNum++; + } + } + + if (isDealMiddel) { + //遇到空格 + if (" ".equals(w)) { + if (buildMiddleWord.length() == 0) { + throw new Exception(linenum + "行:语法错误不允许出现连续空格!"); + } else { + //生成了一个中间体 + middleList.add(buildMiddleWord.toString()); + logg("get Middle++:" + buildMiddleWord.toString()); + + buildMiddleWord = new StringBuilder(); + } + } else { + //把w拼接到中间体上 + buildMiddleWord.append(w); + logg("buildMiddleWord length:" + buildMiddleWord.length() + "buildMiddleWord:" + buildMiddleWord.toString()); + + } + } + + if (isDealValue) { + //把余下的所有字符都拼接给value + valueBuilder.append(w); + } + + } + logg("isDealValue done valueBuilder:" + valueBuilder.toString()); + + + if (middleList.size() != 4) { + throw new Exception(linenum + "行配置错误:每行必须有4段组成,例如: 并且 手机号 是 相等 "); + } + + + //规则对齐 + if (beforeRuleLine != null) { + logg("beforeRuleLine :" + beforeRuleLine); + logg("thisRuleLine :" + this); + + //同级别 + if (headSpaceNum == beforeRuleLine.headSpaceNum) { + logg("同级别"); + this.beforeRuleLine = beforeRuleLine; + beforeRuleLine.nextRuleLine = this; + } + //子级 + if (headSpaceNum - 1 == beforeRuleLine.headSpaceNum) { + logg("子级"); + this.parentRuleLine = beforeRuleLine; + beforeRuleLine.childRuleLine = this; + } + //查找父级别 + if (headSpaceNum < beforeRuleLine.headSpaceNum) { + //匹配到最近一个同级 + RuleLine fBeforeRuleLine = beforeRuleLine.getBeforeRuleLine(); + if (fBeforeRuleLine == null) { + fBeforeRuleLine = beforeRuleLine.getParentRuleLine(); + } + + while (fBeforeRuleLine != null) { + logg("fBeforeRuleLine" + fBeforeRuleLine); + + //查找到同级别 + if (headSpaceNum == fBeforeRuleLine.headSpaceNum) { + logg("父级别"); + this.beforeRuleLine = fBeforeRuleLine; + fBeforeRuleLine.nextRuleLine = this; + break; + } else { + //向上查找 + RuleLine testfBeforeRuleLine = fBeforeRuleLine.getBeforeRuleLine(); + if (testfBeforeRuleLine == null) { + testfBeforeRuleLine = fBeforeRuleLine.getParentRuleLine(); + } + fBeforeRuleLine = testfBeforeRuleLine; + + } + } + } + + } else { + logg("根级别"); + } + + + this.conjunction = middleList.get(0); + this.sure = middleList.get(1); + this.field = middleList.get(2); + this.check = middleList.get(3); + this.value = valueBuilder.toString(); + + if (!CONJUNCTION_LIST.contains(this.conjunction)) { + throw new Exception(linenum + "行配置错误:连接词只支持:" + CONJUNCTION_LIST + " 但提供了" + this.conjunction); + } + if (!FILED_LIST.contains(this.field)) { + throw new Exception(linenum + "行配置错误:字段只支持:" + FILED_LIST + " 但提供了" + this.field); + } + if (!SURE_LIST.contains(this.sure)) { + throw new Exception(linenum + "行配置错误 " + this.sure + " 确认词只支持:" + SURE_LIST + " 但提供了" + this.sure); + } + if (!CHECK_LIST.contains(this.check)) { + throw new Exception(linenum + "行配置错误:比较词只支持:" + CHECK_LIST + " 但提供了" + this.check); + } + + logg("----------" + linenum + "==" + this); + + + } + + public static void startLog(boolean startLog) { + STARTLOG = startLog; + } + + public static void logg(String msg) { + if (STARTLOG) { + Log.i(TAG, msg); + } + + } + + @Override + public String toString() { + return "RuleLine{" + + "headSpaceNum='" + headSpaceNum + '\'' + + "conjunction='" + conjunction + '\'' + + ", field='" + field + '\'' + + ", sure='" + sure + '\'' + + ", check='" + check + '\'' + + ", value='" + value + '\'' + + '}'; + } + + public int getHeadSpaceNum() { + return headSpaceNum; + } + + public void setHeadSpaceNum(int headSpaceNum) { + this.headSpaceNum = headSpaceNum; + } + + public RuleLine getBeforeRuleLine() { + return beforeRuleLine; + } + + public void setBeforeRuleLine(RuleLine beforeRuleLine) { + this.beforeRuleLine = beforeRuleLine; + } + + public RuleLine getNextRuleLine() { + return nextRuleLine; + } + + public void setNextRuleLine(RuleLine nextRuleLine) { + this.nextRuleLine = nextRuleLine; + } + + public RuleLine getParentRuleLine() { + return parentRuleLine; + } + + public void setParentRuleLine(RuleLine parentRuleLine) { + this.parentRuleLine = parentRuleLine; + } + + public RuleLine getChildRuleLine() { + return childRuleLine; + } + + public void setChildRuleLine(RuleLine childRuleLine) { + this.childRuleLine = childRuleLine; + } + + public String getConjunction() { + return conjunction; + } + + public void setConjunction(String conjunction) { + this.conjunction = conjunction; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getSure() { + return sure; + } + + public void setSure(String sure) { + this.sure = sure; + } + + public String getCheck() { + return check; + } + + public void setCheck(String check) { + this.check = check; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLineUtils.java b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLineUtils.java new file mode 100644 index 00000000..63bb55e0 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLineUtils.java @@ -0,0 +1,134 @@ +package com.idormy.sms.forwarder.utils; + +import android.util.Log; + +import com.idormy.sms.forwarder.model.vo.SmsVo; + +import java.util.Date; +import java.util.Scanner; + +import static com.idormy.sms.forwarder.utils.RuleLine.CONJUNCTION_AND; +import static com.idormy.sms.forwarder.utils.RuleLine.CONJUNCTION_OR; + +public class RuleLineUtils { + static String TAG = "RuleLineUtils"; + static Boolean STARTLOG = false; + + public static void main(String[] args) throws Exception { + String a = "并且 是 手机号 相等 10086\n" + + " 或者 是 手机号 结尾 哈哈哈\n" + + " 并且 是 短信内容 包含 asfas\n" + + " 或者 是 手机号 结尾 aaaa\n" + + "并且 是 手机号 相等 100861\n" + + "并且 是 手机号 相等 100861"; + + SmsVo msg = new SmsVo("10086", "哈哈哈", new Date(), "15888888888"); + logg("check:" + checkRuleLines(msg, a)); + } + + public static void startLog(boolean startLog) { + STARTLOG = startLog; + } + + public static void logg(String msg) { + if (STARTLOG) { + Log.i(TAG, msg); + } + + } + + public static boolean checkRuleLines(SmsVo msg, String RuleLines) throws Exception { + + Scanner scanner = new Scanner(RuleLines); + + int linenum = 0; + RuleLine headRuleLine = null; + + RuleLine beforeRuleLine = null; + + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + logg(linenum + " : " + line); + //第一行 + if (linenum == 0) { + //第一行不允许缩进 + if (line.startsWith(" ")) { + throw new Exception("第一行不允许缩进"); + } + } + + // process the line + + + beforeRuleLine = RuleLineUtils.generateRuleTree(line, linenum, beforeRuleLine); + if (linenum == 0) { + headRuleLine = beforeRuleLine; + } + + linenum++; + } + + return checkRuleTree(msg, headRuleLine); + + } + + + /** + * 使用规则树判断消息是否命中规则 + * Rule节点是否命中取决于:该节点是否命中、该节点子结点(如果有的话)是否命中、该节点下节点(如果有的话)是否命中 + * 递归检查 + */ + + public static boolean checkRuleTree(SmsVo msg, RuleLine currentRuleLine) throws Exception { + //该节点是否命中 + boolean currentAll = currentRuleLine.checkMsg(msg); + logg("current:" + currentRuleLine + " checked:" + currentAll); + + //该节点子结点(如果有的话)是否命中 + if (currentRuleLine.getChildRuleLine() != null) { + logg(" child:" + currentRuleLine.getChildRuleLine()); + + //根据情况连接结果 + switch (currentRuleLine.getChildRuleLine().conjunction) { + case CONJUNCTION_AND: + currentAll = currentAll && checkRuleTree(msg, currentRuleLine.getChildRuleLine()); + break; + case CONJUNCTION_OR: + currentAll = currentAll || checkRuleTree(msg, currentRuleLine.getChildRuleLine()); + break; + default: + throw new Exception("child wrong conjunction"); + } + } + + //该节点下节点(如果有的话)是否命中 + if (currentRuleLine.getNextRuleLine() != null) { + logg("next:" + currentRuleLine.getNextRuleLine()); + //根据情况连接结果 + switch (currentRuleLine.getNextRuleLine().conjunction) { + case CONJUNCTION_AND: + currentAll = currentAll && checkRuleTree(msg, currentRuleLine.getNextRuleLine()); + break; + case CONJUNCTION_OR: + currentAll = currentAll || checkRuleTree(msg, currentRuleLine.getNextRuleLine()); + break; + default: + throw new Exception("next wrong conjunction"); + } + } + + return currentAll; + } + + /** + * 生成规则树 + * 一行代表一个规则 + */ + + public static RuleLine generateRuleTree(String line, int lineNum, RuleLine parentRuleLine) throws Exception { + String[] words = line.split(" "); + + return new RuleLine(line, lineNum, parentRuleLine); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java index 5b19d5f8..c63cacef 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java @@ -1,6 +1,7 @@ package com.idormy.sms.forwarder.utils; import android.content.Context; +import android.os.Handler; import android.util.Log; import com.alibaba.fastjson.JSON; @@ -16,14 +17,6 @@ import com.idormy.sms.forwarder.model.vo.WebNotifySettingVo; import java.util.List; -import static com.idormy.sms.forwarder.model.RuleModel.CHECK_CONTAIN; -import static com.idormy.sms.forwarder.model.RuleModel.CHECK_END_WITH; -import static com.idormy.sms.forwarder.model.RuleModel.CHECK_IS; -import static com.idormy.sms.forwarder.model.RuleModel.CHECK_NOT_IS; -import static com.idormy.sms.forwarder.model.RuleModel.CHECK_START_WITH; -import static com.idormy.sms.forwarder.model.RuleModel.FILED_MSG_CONTENT; -import static com.idormy.sms.forwarder.model.RuleModel.FILED_PHONE_NUM; -import static com.idormy.sms.forwarder.model.RuleModel.FILED_TRANSPOND_ALL; import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK; import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING; import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL; @@ -59,98 +52,53 @@ public class SendUtil { Log.i(TAG, "send_msg smsVo:" + smsVo); RuleUtil.init(context); LogUtil.init(context); - //初始化 EmailKit - //EmailKit.initialize(context); List rulelist = RuleUtil.getRule(null, null); if (!rulelist.isEmpty()) { SenderUtil.init(context); - for (RuleModel ruleModel : rulelist - ) { - boolean canSend = false; - //使用转发规则制定的字段 匹配 - switch (ruleModel.getFiled()) { - case FILED_TRANSPOND_ALL: - canSend = true; - break; - case FILED_PHONE_NUM: - switch (ruleModel.getCheck()) { - case CHECK_IS: - if (smsVo.getMobile() != null && smsVo.getMobile().equals(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_NOT_IS: - if (smsVo.getMobile() != null && !smsVo.getMobile().equals(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_START_WITH: - if (smsVo.getMobile() != null && smsVo.getMobile().startsWith(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_END_WITH: - if (smsVo.getMobile() != null && smsVo.getMobile().endsWith(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_CONTAIN: - if (smsVo.getMobile() != null && smsVo.getMobile().contains(ruleModel.getValue())) { - canSend = true; - } - break; - } - break; - case FILED_MSG_CONTENT: - switch (ruleModel.getCheck()) { - case CHECK_IS: - if (smsVo.getContent() != null && smsVo.getContent().equals(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_NOT_IS: - if (smsVo.getContent() != null && !smsVo.getContent().equals(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_START_WITH: - if (smsVo.getContent() != null && smsVo.getContent().startsWith(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_END_WITH: - if (smsVo.getContent() != null && smsVo.getContent().endsWith(ruleModel.getValue())) { - canSend = true; - } - break; - case CHECK_CONTAIN: - if (smsVo.getContent() != null && smsVo.getContent().contains(ruleModel.getValue())) { - canSend = true; - } - break; - } - break; - - } + for (RuleModel ruleModel : rulelist) { //规则匹配发现需要发送 - if (canSend) { - List senderModels = SenderUtil.getSender(ruleModel.getSenderId(), null); - for (SenderModel senderModel : senderModels - ) { - LogUtil.addLog(new LogModel(smsVo.getMobile(), smsVo.getContent(), smsVo.getPhoneNumber(), senderModel.getId())); - SendUtil.senderSendMsg(smsVo, senderModel); + try { + if (ruleModel.checkMsg(smsVo)) { + List senderModels = SenderUtil.getSender(ruleModel.getSenderId(), null); + for (SenderModel senderModel : senderModels + ) { + LogUtil.addLog(new LogModel(smsVo.getMobile(), smsVo.getContent(), smsVo.getPhoneNumber(), senderModel.getId())); + SendUtil.senderSendMsgNoHandError(smsVo, senderModel); + } } + } catch (Exception e) { + Log.e(TAG, "send_msg: fail checkMsg:", e); } - } - } - - //EmailKit.destroy(); } - public static void senderSendMsg(SmsVo smsVo, SenderModel senderModel) { + public static void sendMsgByRuleModelSenderId(final Handler handError, RuleModel ruleModel, SmsVo smsVo, Long senderId) throws Exception { + if (senderId == null) { + throw new Exception("先新建并选择发送方"); + } + + if (!ruleModel.checkMsg(smsVo)) { + throw new Exception("短信未匹配中规则"); + } + + List senderModels = SenderUtil.getSender(senderId, null); + if (senderModels.isEmpty()) { + throw new Exception("未找到发送方"); + } + + for (SenderModel senderModel : senderModels + ) { + SendUtil.senderSendMsg(handError, smsVo, senderModel); + } + } + + public static void senderSendMsgNoHandError(SmsVo smsVo, SenderModel senderModel) { + SendUtil.senderSendMsg(null, smsVo, senderModel); + } + + public static void senderSendMsg(Handler handError, SmsVo smsVo, SenderModel senderModel) { Log.i(TAG, "senderSendMsg smsVo:" + smsVo + "senderModel:" + senderModel); switch (senderModel.getType()) { @@ -160,7 +108,7 @@ public class SendUtil { DingDingSettingVo dingDingSettingVo = JSON.parseObject(senderModel.getJsonSetting(), DingDingSettingVo.class); if (dingDingSettingVo != null) { try { - SenderDingdingMsg.sendMsg(null, dingDingSettingVo.getToken(), dingDingSettingVo.getSecret(), dingDingSettingVo.getAtMobils(), dingDingSettingVo.getAtAll(), smsVo.getSmsVoForSend()); + SenderDingdingMsg.sendMsg(handError, dingDingSettingVo.getToken(), dingDingSettingVo.getSecret(), dingDingSettingVo.getAtMobils(), dingDingSettingVo.getAtAll(), smsVo.getSmsVoForSend()); } catch (Exception e) { Log.e(TAG, "senderSendMsg: dingding error " + e.getMessage()); } @@ -175,7 +123,7 @@ public class SendUtil { EmailSettingVo emailSettingVo = JSON.parseObject(senderModel.getJsonSetting(), EmailSettingVo.class); if (emailSettingVo != null) { try { - SenderMailMsg.sendEmail(null, emailSettingVo.getHost(), emailSettingVo.getPort(), emailSettingVo.getSsl(), emailSettingVo.getFromEmail(), + SenderMailMsg.sendEmail(handError, emailSettingVo.getHost(), emailSettingVo.getPort(), emailSettingVo.getSsl(), emailSettingVo.getFromEmail(), emailSettingVo.getPwd(), emailSettingVo.getToEmail(), smsVo.getMobile(), smsVo.getSmsVoForSend()); } catch (Exception e) { Log.e(TAG, "senderSendMsg: SenderMailMsg error " + e.getMessage()); @@ -191,7 +139,7 @@ public class SendUtil { WebNotifySettingVo webNotifySettingVo = JSON.parseObject(senderModel.getJsonSetting(), WebNotifySettingVo.class); if (webNotifySettingVo != null) { try { - SenderWebNotifyMsg.sendMsg(null, webNotifySettingVo.getToken(), webNotifySettingVo.getSecret(), smsVo.getMobile(), smsVo.getSmsVoForSend()); + SenderWebNotifyMsg.sendMsg(handError, webNotifySettingVo.getToken(), webNotifySettingVo.getSecret(), smsVo.getMobile(), smsVo.getSmsVoForSend()); } catch (Exception e) { Log.e(TAG, "senderSendMsg: SenderWebNotifyMsg error " + e.getMessage()); } @@ -206,7 +154,7 @@ public class SendUtil { QYWXGroupRobotSettingVo qywxGroupRobotSettingVo = JSON.parseObject(senderModel.getJsonSetting(), QYWXGroupRobotSettingVo.class); if (qywxGroupRobotSettingVo != null) { try { - SenderQyWxGroupRobotMsg.sendMsg(null, qywxGroupRobotSettingVo.getWebHook(), smsVo.getMobile(), smsVo.getSmsVoForSend()); + SenderQyWxGroupRobotMsg.sendMsg(handError, qywxGroupRobotSettingVo.getWebHook(), smsVo.getMobile(), smsVo.getSmsVoForSend()); } catch (Exception e) { Log.e(TAG, "senderSendMsg: SenderQyWxGroupRobotMsg error " + e.getMessage()); } @@ -215,13 +163,14 @@ public class SendUtil { } break; + case TYPE_BARK: //try phrase json setting if (senderModel.getJsonSetting() != null) { BarkSettingVo barkSettingVo = JSON.parseObject(senderModel.getJsonSetting(), BarkSettingVo.class); if (barkSettingVo != null) { try { - SenderBarkMsg.sendMsg(null, barkSettingVo.getServer(), smsVo.getMobile(), smsVo.getContent(), smsVo.getPhoneNumber()); + SenderBarkMsg.sendMsg(handError, barkSettingVo.getServer(), smsVo.getMobile(), smsVo.getContent(), smsVo.getPhoneNumber()); } catch (Exception e) { Log.e(TAG, "senderSendMsg: SenderBarkMsg error " + e.getMessage()); } diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java index 213cab6f..5c7aaa14 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java @@ -6,8 +6,9 @@ import android.preference.PreferenceManager; import android.util.Log; public class SettingUtil { - static Boolean hasInit = false; private static String TAG = "SettingUtil"; + + static Boolean hasInit = false; private static SharedPreferences sp_setting = null; private static Context context = null; @@ -60,7 +61,7 @@ public class SettingUtil { public static String get_send_util_email(String key) { Log.d(TAG, "get_send_util_email key" + key); String defaultstt = ""; - if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY)) defaultstt = "stmp服务器"; + if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY)) defaultstt = "smtp服务器"; if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY)) defaultstt = "端口"; if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)) defaultstt = "发送邮箱"; if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY)) defaultstt = "密码"; diff --git a/app/src/main/res/layout/activity_alter_dialog_setview_rule.xml b/app/src/main/res/layout/activity_alter_dialog_setview_rule.xml index c07356ac..44060656 100644 --- a/app/src/main/res/layout/activity_alter_dialog_setview_rule.xml +++ b/app/src/main/res/layout/activity_alter_dialog_setview_rule.xml @@ -44,7 +44,29 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="内容" /> + + + + + android:orientation="vertical"> + android:orientation="vertical"> +