新增:发送通道的测试内容携带通道名称 #317

This commit is contained in:
pppscn 2023-07-11 09:51:08 +08:00
parent 47b8efc8b4
commit 3edf6cc7bc
18 changed files with 2688 additions and 2678 deletions

View File

@ -210,7 +210,8 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
BarkUtils.sendMsg(settingVo, msgInfo) BarkUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@ -190,7 +190,8 @@ class DingtalkGroupRobotFragment : BaseFragment<FragmentSendersDingtalkGroupRobo
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
DingtalkGroupRobotUtils.sendMsg(settingVo, msgInfo) DingtalkGroupRobotUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@ -1,302 +1,303 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.EditText import android.widget.EditText
import android.widget.RadioGroup import android.widget.RadioGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersDingtalkInnerRobotBinding import com.idormy.sms.forwarder.databinding.FragmentSendersDingtalkInnerRobotBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.DingtalkInnerRobotUtils import com.idormy.sms.forwarder.utils.sender.DingtalkInnerRobotUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.net.Proxy import java.net.Proxy
import java.util.* import java.util.*
@Page(name = "钉钉企业机器人") @Page(name = "钉钉企业机器人")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobotBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener { class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobotBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private val TAG: String = DingtalkInnerRobotFragment::class.java.simpleName private val TAG: String = DingtalkInnerRobotFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersDingtalkInnerRobotBinding { ): FragmentSendersDingtalkInnerRobotBinding {
return FragmentSendersDingtalkInnerRobotBinding.inflate(inflater, container, false) return FragmentSendersDingtalkInnerRobotBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.dingtalk_inner_robot) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.dingtalk_inner_robot)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, DingtalkInnerRobotSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, DingtalkInnerRobotSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.etAgentID.setText(settingVo.agentID) binding!!.etAgentID.setText(settingVo.agentID)
binding!!.etAppKey.setText(settingVo.appKey) binding!!.etAppKey.setText(settingVo.appKey)
binding!!.etAppSecret.setText(settingVo.appSecret) binding!!.etAppSecret.setText(settingVo.appSecret)
binding!!.etUserIds.setText(settingVo.userIds) binding!!.etUserIds.setText(settingVo.userIds)
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId()) binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
binding!!.etTitleTemplate.setText(settingVo.titleTemplate) binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId()) binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
binding!!.etProxyHost.setText(settingVo.proxyHost) binding!!.etProxyHost.setText(settingVo.proxyHost)
binding!!.etProxyPort.setText(settingVo.proxyPort) binding!!.etProxyPort.setText(settingVo.proxyPort)
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
binding!!.etProxyUsername.setText(settingVo.proxyUsername) binding!!.etProxyUsername.setText(settingVo.proxyUsername)
binding!!.etProxyPassword.setText(settingVo.proxyPassword) binding!!.etProxyPassword.setText(settingVo.proxyPassword)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this) binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this) binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this) binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this) binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this)
binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int -> binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) { if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) {
binding!!.layoutProxyHost.visibility = View.VISIBLE binding!!.layoutProxyHost.visibility = View.VISIBLE
binding!!.layoutProxyPort.visibility = View.VISIBLE binding!!.layoutProxyPort.visibility = View.VISIBLE
binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE
} else { } else {
binding!!.layoutProxyHost.visibility = View.GONE binding!!.layoutProxyHost.visibility = View.GONE
binding!!.layoutProxyPort.visibility = View.GONE binding!!.layoutProxyPort.visibility = View.GONE
binding!!.layoutProxyAuthenticator.visibility = View.GONE binding!!.layoutProxyAuthenticator.visibility = View.GONE
} }
} }
binding!!.rgMsgType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int -> binding!!.rgMsgType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
binding!!.layoutCustomTemplate.visibility = if (checkedId == R.id.rb_msg_type_markdown) View.VISIBLE else View.GONE binding!!.layoutCustomTemplate.visibility = if (checkedId == R.id.rb_msg_type_markdown) View.VISIBLE else View.GONE
} }
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) { override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
when (buttonView.id) { when (buttonView.id) {
R.id.sb_proxyAuthenticator -> { R.id.sb_proxyAuthenticator -> {
binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE
} }
else -> {} else -> {}
} }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) { when (v.id) {
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra -> { R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time -> { R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name -> { R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
DingtalkInnerRobotUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { DingtalkInnerRobotUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): DingtalkInnerRobotSetting {
val agentID = binding!!.etAgentID.text.toString().trim() private fun checkSetting(): DingtalkInnerRobotSetting {
val appKey = binding!!.etAppKey.text.toString().trim() val agentID = binding!!.etAgentID.text.toString().trim()
val appSecret = binding!!.etAppSecret.text.toString().trim() val appKey = binding!!.etAppKey.text.toString().trim()
val userIds = binding!!.etUserIds.text.toString().trim() val appSecret = binding!!.etAppSecret.text.toString().trim()
if (TextUtils.isEmpty(agentID) || TextUtils.isEmpty(appKey) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(userIds)) { val userIds = binding!!.etUserIds.text.toString().trim()
throw Exception(getString(R.string.invalid_dingtalk_inner_robot)) if (TextUtils.isEmpty(agentID) || TextUtils.isEmpty(appKey) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(userIds)) {
} throw Exception(getString(R.string.invalid_dingtalk_inner_robot))
}
val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
R.id.rb_proxyHttp -> Proxy.Type.HTTP val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
R.id.rb_proxySocks -> Proxy.Type.SOCKS R.id.rb_proxyHttp -> Proxy.Type.HTTP
else -> Proxy.Type.DIRECT R.id.rb_proxySocks -> Proxy.Type.SOCKS
} else -> Proxy.Type.DIRECT
val proxyHost = binding!!.etProxyHost.text.toString().trim() }
val proxyPort = binding!!.etProxyPort.text.toString().trim() val proxyHost = binding!!.etProxyHost.text.toString().trim()
val proxyPort = binding!!.etProxyPort.text.toString().trim()
if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
throw Exception(getString(R.string.invalid_host_or_port)) if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
} throw Exception(getString(R.string.invalid_host_or_port))
}
val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
val proxyUsername = binding!!.etProxyUsername.text.toString().trim() val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
val proxyPassword = binding!!.etProxyPassword.text.toString().trim() val proxyUsername = binding!!.etProxyUsername.text.toString().trim()
if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) { val proxyPassword = binding!!.etProxyPassword.text.toString().trim()
throw Exception(getString(R.string.invalid_username_or_password)) if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) {
} throw Exception(getString(R.string.invalid_username_or_password))
}
val msgKey = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_markdown) "sampleMarkdown" else "sampleText"
val titleTemplate = binding!!.etTitleTemplate.text.toString().trim() val msgKey = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_markdown) "sampleMarkdown" else "sampleText"
val titleTemplate = binding!!.etTitleTemplate.text.toString().trim()
return DingtalkInnerRobotSetting(agentID, appKey, appSecret, userIds, msgKey, titleTemplate, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
} return DingtalkInnerRobotSetting(agentID, appKey, appSecret, userIds, msgKey, titleTemplate, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,302 +1,303 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersEmailBinding import com.idormy.sms.forwarder.databinding.FragmentSendersEmailBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.EmailSetting import com.idormy.sms.forwarder.entity.setting.EmailSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.EmailUtils import com.idormy.sms.forwarder.utils.sender.EmailUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "Email") @Page(name = "Email")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClickListener { class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClickListener {
private val TAG: String = EmailFragment::class.java.simpleName private val TAG: String = EmailFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
private var mailType: String = getString(R.string.other_mail_type) //邮箱类型 private var mailType: String = getString(R.string.other_mail_type) //邮箱类型
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersEmailBinding { ): FragmentSendersEmailBinding {
return FragmentSendersEmailBinding.inflate(inflater, container, false) return FragmentSendersEmailBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.email) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.email)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
val mailTypeArray = ResUtils.getStringArray(R.array.MailType) val mailTypeArray = ResUtils.getStringArray(R.array.MailType)
Log.d(TAG, mailTypeArray.toString()) Log.d(TAG, mailTypeArray.toString())
binding!!.spMailType.setOnItemSelectedListener { _: MaterialSpinner?, position: Int, _: Long, item: Any -> binding!!.spMailType.setOnItemSelectedListener { _: MaterialSpinner?, position: Int, _: Long, item: Any ->
mailType = item.toString() mailType = item.toString()
//XToastUtils.warning(mailType) //XToastUtils.warning(mailType)
binding!!.layoutServiceSetting.visibility = if (position == mailTypeArray.size - 1) View.VISIBLE else View.GONE binding!!.layoutServiceSetting.visibility = if (position == mailTypeArray.size - 1) View.VISIBLE else View.GONE
} }
binding!!.spMailType.setOnNothingSelectedListener { binding!!.spMailType.setOnNothingSelectedListener {
mailType = mailTypeArray[mailTypeArray.size - 1] mailType = mailTypeArray[mailTypeArray.size - 1]
binding!!.spMailType.selectedIndex = mailTypeArray.size - 1 binding!!.spMailType.selectedIndex = mailTypeArray.size - 1
binding!!.layoutServiceSetting.visibility = View.VISIBLE binding!!.layoutServiceSetting.visibility = View.VISIBLE
} }
binding!!.spMailType.selectedIndex = mailTypeArray.size - 1 binding!!.spMailType.selectedIndex = mailTypeArray.size - 1
binding!!.layoutServiceSetting.visibility = View.VISIBLE binding!!.layoutServiceSetting.visibility = View.VISIBLE
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, EmailSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, EmailSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
if (!TextUtils.isEmpty(settingVo.mailType)) { if (!TextUtils.isEmpty(settingVo.mailType)) {
mailType = settingVo.mailType.toString() mailType = settingVo.mailType.toString()
binding!!.spMailType.setSelectedItem(mailType) binding!!.spMailType.setSelectedItem(mailType)
if (mailType != getString(R.string.other_mail_type)) { if (mailType != getString(R.string.other_mail_type)) {
binding!!.layoutServiceSetting.visibility = View.GONE binding!!.layoutServiceSetting.visibility = View.GONE
} }
} }
binding!!.etFromEmail.setText(settingVo.fromEmail) binding!!.etFromEmail.setText(settingVo.fromEmail)
binding!!.etPwd.setText(settingVo.pwd) binding!!.etPwd.setText(settingVo.pwd)
binding!!.etNickname.setText(settingVo.nickname) binding!!.etNickname.setText(settingVo.nickname)
binding!!.etHost.setText(settingVo.host) binding!!.etHost.setText(settingVo.host)
binding!!.etPort.setText(settingVo.port) binding!!.etPort.setText(settingVo.port)
binding!!.sbSsl.isChecked = settingVo.ssl == true binding!!.sbSsl.isChecked = settingVo.ssl == true
binding!!.sbStartTls.isChecked = settingVo.startTls == true binding!!.sbStartTls.isChecked = settingVo.startTls == true
binding!!.etToEmail.setText(settingVo.toEmail) binding!!.etToEmail.setText(settingVo.toEmail)
binding!!.etTitleTemplate.setText(settingVo.title) binding!!.etTitleTemplate.setText(settingVo.title)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSenderToNickname.setOnClickListener(this) binding!!.btInsertSenderToNickname.setOnClickListener(this)
binding!!.btInsertExtraToNickname.setOnClickListener(this) binding!!.btInsertExtraToNickname.setOnClickListener(this)
binding!!.btInsertTimeToNickname.setOnClickListener(this) binding!!.btInsertTimeToNickname.setOnClickListener(this)
binding!!.btInsertDeviceNameToNickname.setOnClickListener(this) binding!!.btInsertDeviceNameToNickname.setOnClickListener(this)
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this) binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this) binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this) binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
val etNickname: EditText = binding!!.etNickname val etNickname: EditText = binding!!.etNickname
val etTitleTemplate: EditText = binding!!.etTitleTemplate val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) { when (v.id) {
R.id.bt_insert_sender_to_nickname -> { R.id.bt_insert_sender_to_nickname -> {
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra_to_nickname -> { R.id.bt_insert_extra_to_nickname -> {
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time_to_nickname -> { R.id.bt_insert_time_to_nickname -> {
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name_to_nickname -> { R.id.bt_insert_device_name_to_nickname -> {
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_device_name))
return return
} }
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra -> { R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time -> { R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name -> { R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
EmailUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { EmailUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): EmailSetting {
val fromEmail = binding!!.etFromEmail.text.toString().trim() private fun checkSetting(): EmailSetting {
val pwd = binding!!.etPwd.text.toString().trim() val fromEmail = binding!!.etFromEmail.text.toString().trim()
val nickname = binding!!.etNickname.text.toString().trim() val pwd = binding!!.etPwd.text.toString().trim()
val host = binding!!.etHost.text.toString().trim() val nickname = binding!!.etNickname.text.toString().trim()
val port = binding!!.etPort.text.toString().trim() val host = binding!!.etHost.text.toString().trim()
val ssl = binding!!.sbSsl.isChecked val port = binding!!.etPort.text.toString().trim()
val startTls = binding!!.sbStartTls.isChecked val ssl = binding!!.sbSsl.isChecked
val toEmail = binding!!.etToEmail.text.toString().trim() val startTls = binding!!.sbStartTls.isChecked
val title = binding!!.etTitleTemplate.text.toString().trim() val toEmail = binding!!.etToEmail.text.toString().trim()
if (TextUtils.isEmpty(fromEmail) || TextUtils.isEmpty(pwd) || TextUtils.isEmpty(toEmail)) { val title = binding!!.etTitleTemplate.text.toString().trim()
throw Exception(getString(R.string.invalid_email)) if (TextUtils.isEmpty(fromEmail) || TextUtils.isEmpty(pwd) || TextUtils.isEmpty(toEmail)) {
} throw Exception(getString(R.string.invalid_email))
if (mailType == getString(R.string.other_mail_type) && (TextUtils.isEmpty(host) || TextUtils.isEmpty(port))) { }
throw Exception(getString(R.string.invalid_email_server)) if (mailType == getString(R.string.other_mail_type) && (TextUtils.isEmpty(host) || TextUtils.isEmpty(port))) {
} throw Exception(getString(R.string.invalid_email_server))
}
return EmailSetting(mailType, fromEmail, pwd, nickname, host, port, ssl, startTls, toEmail, title)
} return EmailSetting(mailType, fromEmail, pwd, nickname, host, port, ssl, startTls, toEmail, title)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,246 +1,247 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuAppBinding import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuAppBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.FeishuAppUtils import com.idormy.sms.forwarder.utils.sender.FeishuAppUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "飞书企业应用") @Page(name = "飞书企业应用")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View.OnClickListener { class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View.OnClickListener {
private val TAG: String = FeishuAppFragment::class.java.simpleName private val TAG: String = FeishuAppFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersFeishuAppBinding { ): FragmentSendersFeishuAppBinding {
return FragmentSendersFeishuAppBinding.inflate(inflater, container, false) return FragmentSendersFeishuAppBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu_app) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu_app)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuAppSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, FeishuAppSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.etAppId.setText(settingVo.appId) binding!!.etAppId.setText(settingVo.appId)
binding!!.etAppSecret.setText(settingVo.appSecret) binding!!.etAppSecret.setText(settingVo.appSecret)
binding!!.etUserId.setText(settingVo.receiveId) binding!!.etUserId.setText(settingVo.receiveId)
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId()) binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
binding!!.etTitleTemplate.setText(settingVo.titleTemplate) binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this) binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this) binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this) binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) { when (v.id) {
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra -> { R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time -> { R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name -> { R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
FeishuAppUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { FeishuAppUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): FeishuAppSetting {
val appId = binding!!.etAppId.text.toString().trim() private fun checkSetting(): FeishuAppSetting {
val appSecret = binding!!.etAppSecret.text.toString().trim() val appId = binding!!.etAppId.text.toString().trim()
val receiveId = binding!!.etUserId.text.toString().trim() val appSecret = binding!!.etAppSecret.text.toString().trim()
if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(receiveId)) { val receiveId = binding!!.etUserId.text.toString().trim()
throw Exception(getString(R.string.invalid_feishu_app_parameter)) if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(receiveId)) {
} throw Exception(getString(R.string.invalid_feishu_app_parameter))
}
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
val title = binding!!.etTitleTemplate.text.toString().trim() val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
val title = binding!!.etTitleTemplate.text.toString().trim()
return FeishuAppSetting(appId, appSecret, receiveId, msgType, title)
} return FeishuAppSetting(appId, appSecret, receiveId, msgType, title)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,244 +1,245 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuBinding import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.FeishuSetting import com.idormy.sms.forwarder.entity.setting.FeishuSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.FeishuUtils import com.idormy.sms.forwarder.utils.sender.FeishuUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "飞书群机器人") @Page(name = "飞书群机器人")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnClickListener { class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnClickListener {
private val TAG: String = FeishuFragment::class.java.simpleName private val TAG: String = FeishuFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersFeishuBinding { ): FragmentSendersFeishuBinding {
return FragmentSendersFeishuBinding.inflate(inflater, container, false) return FragmentSendersFeishuBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, FeishuSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.etWebhook.setText(settingVo.webhook) binding!!.etWebhook.setText(settingVo.webhook)
binding!!.etSecret.setText(settingVo.secret) binding!!.etSecret.setText(settingVo.secret)
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId()) binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
binding!!.etTitleTemplate.setText(settingVo.titleTemplate) binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this) binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this) binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this) binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) { when (v.id) {
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra -> { R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time -> { R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name -> { R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
FeishuUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { FeishuUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): FeishuSetting {
val webhook = binding!!.etWebhook.text.toString().trim() private fun checkSetting(): FeishuSetting {
if (!CommonUtils.checkUrl(webhook, false)) { val webhook = binding!!.etWebhook.text.toString().trim()
throw Exception(getString(R.string.invalid_webhook)) if (!CommonUtils.checkUrl(webhook, false)) {
} throw Exception(getString(R.string.invalid_webhook))
}
val secret = binding!!.etSecret.text.toString().trim()
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text" val secret = binding!!.etSecret.text.toString().trim()
val title = binding!!.etTitleTemplate.text.toString().trim() val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
val title = binding!!.etTitleTemplate.text.toString().trim()
return FeishuSetting(webhook, secret, msgType, title)
} return FeishuSetting(webhook, secret, msgType, title)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,242 +1,243 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersGotifyBinding import com.idormy.sms.forwarder.databinding.FragmentSendersGotifyBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.GotifySetting import com.idormy.sms.forwarder.entity.setting.GotifySetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.GotifyUtils import com.idormy.sms.forwarder.utils.sender.GotifyUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "Gotify") @Page(name = "Gotify")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnClickListener { class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnClickListener {
private val TAG: String = GotifyFragment::class.java.simpleName private val TAG: String = GotifyFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersGotifyBinding { ): FragmentSendersGotifyBinding {
return FragmentSendersGotifyBinding.inflate(inflater, container, false) return FragmentSendersGotifyBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.gotify) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.gotify)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, GotifySetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, GotifySetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.etWebServer.setText(settingVo.webServer) binding!!.etWebServer.setText(settingVo.webServer)
binding!!.etTitleTemplate.setText(settingVo.title) binding!!.etTitleTemplate.setText(settingVo.title)
binding!!.etPriority.setText(settingVo.priority) binding!!.etPriority.setText(settingVo.priority)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this) binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this) binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this) binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) { when (v.id) {
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra -> { R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time -> { R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name -> { R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
GotifyUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { GotifyUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): GotifySetting {
val webServer = binding!!.etWebServer.text.toString().trim() private fun checkSetting(): GotifySetting {
if (!CommonUtils.checkUrl(webServer, false)) { val webServer = binding!!.etWebServer.text.toString().trim()
throw Exception(getString(R.string.invalid_webserver)) if (!CommonUtils.checkUrl(webServer, false)) {
} throw Exception(getString(R.string.invalid_webserver))
}
val title = binding!!.etTitleTemplate.text.toString().trim()
val priority = binding!!.etPriority.text.toString().trim() val title = binding!!.etTitleTemplate.text.toString().trim()
val priority = binding!!.etPriority.text.toString().trim()
return GotifySetting(webServer, title, priority)
} return GotifySetting(webServer, title, priority)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,272 +1,273 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import android.widget.RadioGroup import android.widget.RadioGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersPushplusBinding import com.idormy.sms.forwarder.databinding.FragmentSendersPushplusBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.PushplusSetting import com.idormy.sms.forwarder.entity.setting.PushplusSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.PushplusUtils import com.idormy.sms.forwarder.utils.sender.PushplusUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "PushPlus") @Page(name = "PushPlus")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.OnClickListener { class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.OnClickListener {
private val TAG: String = PushplusFragment::class.java.simpleName private val TAG: String = PushplusFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersPushplusBinding { ): FragmentSendersPushplusBinding {
return FragmentSendersPushplusBinding.inflate(inflater, container, false) return FragmentSendersPushplusBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.pushplus) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.pushplus)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, PushplusSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, PushplusSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
if (TextUtils.isEmpty(settingVo.website) || settingVo.website == getString(R.string.pushplus_plus)) { if (TextUtils.isEmpty(settingVo.website) || settingVo.website == getString(R.string.pushplus_plus)) {
binding!!.rgWebsite.check(R.id.rb_website_plus) binding!!.rgWebsite.check(R.id.rb_website_plus)
} else { } else {
binding!!.rgWebsite.check(R.id.rb_website_hxtrip) binding!!.rgWebsite.check(R.id.rb_website_hxtrip)
} }
binding!!.etToken.setText(settingVo.token) binding!!.etToken.setText(settingVo.token)
binding!!.etTopic.setText(settingVo.topic) binding!!.etTopic.setText(settingVo.topic)
binding!!.etTemplate.setText(settingVo.template) binding!!.etTemplate.setText(settingVo.template)
binding!!.etChannel.setText(settingVo.channel) binding!!.etChannel.setText(settingVo.channel)
binding!!.etWebhook.setText(settingVo.webhook) binding!!.etWebhook.setText(settingVo.webhook)
binding!!.etCallbackUrl.setText(settingVo.callbackUrl) binding!!.etCallbackUrl.setText(settingVo.callbackUrl)
binding!!.etValidTime.setText(settingVo.validTime) binding!!.etValidTime.setText(settingVo.validTime)
binding!!.etTitleTemplate.setText(settingVo.titleTemplate) binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this) binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this) binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this) binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
binding!!.rgWebsite.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int -> binding!!.rgWebsite.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
if (checkedId == R.id.rb_website_hxtrip) { if (checkedId == R.id.rb_website_hxtrip) {
binding!!.layoutPlusOne.visibility = View.GONE binding!!.layoutPlusOne.visibility = View.GONE
binding!!.layoutPlusTwo.visibility = View.GONE binding!!.layoutPlusTwo.visibility = View.GONE
} else { } else {
binding!!.layoutPlusOne.visibility = View.VISIBLE binding!!.layoutPlusOne.visibility = View.VISIBLE
binding!!.layoutPlusTwo.visibility = View.VISIBLE binding!!.layoutPlusTwo.visibility = View.VISIBLE
} }
} }
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) { when (v.id) {
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return return
} }
R.id.bt_insert_extra -> { R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return return
} }
R.id.bt_insert_time -> { R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return return
} }
R.id.bt_insert_device_name -> { R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name)) CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
PushplusUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { PushplusUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): PushplusSetting {
val website = when (binding!!.rgWebsite.checkedRadioButtonId) { private fun checkSetting(): PushplusSetting {
R.id.rb_website_hxtrip -> getString(R.string.pushplus_hxtrip) val website = when (binding!!.rgWebsite.checkedRadioButtonId) {
else -> getString(R.string.pushplus_plus) R.id.rb_website_hxtrip -> getString(R.string.pushplus_hxtrip)
} else -> getString(R.string.pushplus_plus)
}
val token = binding!!.etToken.text.toString().trim()
if (TextUtils.isEmpty(token)) { val token = binding!!.etToken.text.toString().trim()
throw Exception(getString(R.string.invalid_token)) if (TextUtils.isEmpty(token)) {
} throw Exception(getString(R.string.invalid_token))
}
val topic = binding!!.etTopic.text.toString().trim()
val template = binding!!.etTemplate.text.toString().trim() val topic = binding!!.etTopic.text.toString().trim()
val channel = binding!!.etChannel.text.toString().trim() val template = binding!!.etTemplate.text.toString().trim()
val webhook = binding!!.etWebhook.text.toString().trim() val channel = binding!!.etChannel.text.toString().trim()
val callbackUrl = binding!!.etCallbackUrl.text.toString().trim() val webhook = binding!!.etWebhook.text.toString().trim()
val validTime = binding!!.etValidTime.text.toString().trim() val callbackUrl = binding!!.etCallbackUrl.text.toString().trim()
val title = binding!!.etTitleTemplate.text.toString().trim() val validTime = binding!!.etValidTime.text.toString().trim()
val title = binding!!.etTitleTemplate.text.toString().trim()
return PushplusSetting(website, token, topic, template, channel, webhook, callbackUrl, validTime, title)
} return PushplusSetting(website, token, topic, template, channel, webhook, callbackUrl, validTime, title)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,231 +1,232 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersServerchanBinding import com.idormy.sms.forwarder.databinding.FragmentSendersServerchanBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.ServerchanSetting import com.idormy.sms.forwarder.entity.setting.ServerchanSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.ServerchanUtils import com.idormy.sms.forwarder.utils.sender.ServerchanUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "Server酱·Turbo") @Page(name = "Server酱·Turbo")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class ServerchanFragment : BaseFragment<FragmentSendersServerchanBinding?>(), View.OnClickListener { class ServerchanFragment : BaseFragment<FragmentSendersServerchanBinding?>(), View.OnClickListener {
private val TAG: String = ServerchanFragment::class.java.simpleName private val TAG: String = ServerchanFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersServerchanBinding { ): FragmentSendersServerchanBinding {
return FragmentSendersServerchanBinding.inflate(inflater, container, false) return FragmentSendersServerchanBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.server_chan) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.server_chan)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, ServerchanSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, ServerchanSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.etSendKey.setText(settingVo.sendKey) binding!!.etSendKey.setText(settingVo.sendKey)
binding!!.etChannel.setText(settingVo.channel) binding!!.etChannel.setText(settingVo.channel)
binding!!.etOpenid.setText(settingVo.openid) binding!!.etOpenid.setText(settingVo.openid)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
when (v.id) { when (v.id) {
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
ServerchanUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { ServerchanUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): ServerchanSetting {
val sendKey = binding!!.etSendKey.text.toString().trim() private fun checkSetting(): ServerchanSetting {
if (TextUtils.isEmpty(sendKey)) { val sendKey = binding!!.etSendKey.text.toString().trim()
throw Exception(getString(R.string.invalid_sendkey)) if (TextUtils.isEmpty(sendKey)) {
} throw Exception(getString(R.string.invalid_sendkey))
val channel = binding!!.etChannel.text.toString().trim() }
if (!TextUtils.isEmpty(channel)) { val channel = binding!!.etChannel.text.toString().trim()
val regex = """^\d+(\|\d+)?$""".toRegex() if (!TextUtils.isEmpty(channel)) {
if (!regex.matches(channel)) { val regex = """^\d+(\|\d+)?$""".toRegex()
throw Exception(getString(R.string.invalid_channel)) if (!regex.matches(channel)) {
} throw Exception(getString(R.string.invalid_channel))
} }
val openid = binding!!.etOpenid.text.toString().trim() }
if (!TextUtils.isEmpty(openid)) { val openid = binding!!.etOpenid.text.toString().trim()
val regex = """^[A-Za-z\d\-_=]+(,[A-Za-z\d\-_=]+)?$""".toRegex() if (!TextUtils.isEmpty(openid)) {
if (!regex.matches(openid)) { val regex = """^[A-Za-z\d\-_=]+(,[A-Za-z\d\-_=]+)?$""".toRegex()
throw Exception(getString(R.string.invalid_openid)) if (!regex.matches(openid)) {
} throw Exception(getString(R.string.invalid_openid))
} }
}
return ServerchanSetting(sendKey, channel, openid)
} return ServerchanSetting(sendKey, channel, openid)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -1,255 +1,256 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.hjq.permissions.OnPermissionCallback import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions import com.hjq.permissions.XXPermissions
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersSmsBinding import com.idormy.sms.forwarder.databinding.FragmentSendersSmsBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.SmsSetting import com.idormy.sms.forwarder.entity.setting.SmsSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.SmsUtils import com.idormy.sms.forwarder.utils.sender.SmsUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "短信") @Page(name = "短信")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class SmsFragment : BaseFragment<FragmentSendersSmsBinding?>(), View.OnClickListener { class SmsFragment : BaseFragment<FragmentSendersSmsBinding?>(), View.OnClickListener {
private val TAG: String = SmsFragment::class.java.simpleName private val TAG: String = SmsFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersSmsBinding { ): FragmentSendersSmsBinding {
return FragmentSendersSmsBinding.inflate(inflater, container, false) return FragmentSendersSmsBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.sms_menu) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.sms_menu)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//检查发短信权限 //检查发短信权限
XXPermissions.with(this) XXPermissions.with(this)
.permission(Permission.SEND_SMS) .permission(Permission.SEND_SMS)
.request(object : OnPermissionCallback { .request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) { override fun onGranted(permissions: List<String>, all: Boolean) {
if (!all) { if (!all) {
XToastUtils.error(R.string.toast_granted_part) XToastUtils.error(R.string.toast_granted_part)
HttpServerUtils.enableApiSmsSend = false HttpServerUtils.enableApiSmsSend = false
} }
} }
override fun onDenied(permissions: List<String>, never: Boolean) { override fun onDenied(permissions: List<String>, never: Boolean) {
HttpServerUtils.enableApiSmsSend = false HttpServerUtils.enableApiSmsSend = false
if (never) { if (never) {
XToastUtils.error(R.string.toast_denied_never) XToastUtils.error(R.string.toast_denied_never)
// 如果是被永久拒绝就跳转到应用权限系统设置页面 // 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(requireContext(), permissions) XXPermissions.startPermissionActivity(requireContext(), permissions)
} else { } else {
XToastUtils.error(R.string.toast_denied) XToastUtils.error(R.string.toast_denied)
} }
} }
}) })
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, SmsSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, SmsSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.rgSimSlot.check(settingVo.getSmsSimSlotCheckId()) binding!!.rgSimSlot.check(settingVo.getSmsSimSlotCheckId())
binding!!.etMobiles.setText(settingVo.mobiles) binding!!.etMobiles.setText(settingVo.mobiles)
binding!!.sbOnlyNoNetwork.isChecked = settingVo.onlyNoNetwork == true binding!!.sbOnlyNoNetwork.isChecked = settingVo.onlyNoNetwork == true
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this) binding!!.btInsertSender.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
when (v.id) { when (v.id) {
R.id.bt_insert_sender -> { R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(binding!!.etMobiles, getString(R.string.tag_from)) CommonUtils.insertOrReplaceText2Cursor(binding!!.etMobiles, getString(R.string.tag_from))
return return
} }
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
SmsUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { SmsUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): SmsSetting {
val mobiles = binding!!.etMobiles.text.toString().trim() private fun checkSetting(): SmsSetting {
if (TextUtils.isEmpty(mobiles)) { val mobiles = binding!!.etMobiles.text.toString().trim()
throw Exception(getString(R.string.invalid_phone_num)) if (TextUtils.isEmpty(mobiles)) {
} throw Exception(getString(R.string.invalid_phone_num))
}
val simSlot = when (binding!!.rgSimSlot.checkedRadioButtonId) {
R.id.rb_sim_slot_1 -> 1 val simSlot = when (binding!!.rgSimSlot.checkedRadioButtonId) {
R.id.rb_sim_slot_2 -> 2 R.id.rb_sim_slot_1 -> 1
else -> 0 R.id.rb_sim_slot_2 -> 2
} else -> 0
val onlyNoNetwork = binding!!.sbOnlyNoNetwork.isChecked }
val onlyNoNetwork = binding!!.sbOnlyNoNetwork.isChecked
return SmsSetting(simSlot, mobiles, onlyNoNetwork)
} return SmsSetting(simSlot, mobiles, onlyNoNetwork)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -157,9 +157,8 @@ class SocketFragment : BaseFragment<FragmentSendersSocketBinding?>(), View.OnCli
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo( val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
"sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
)
SocketUtils.sendMsg(settingVo, msgInfo) SocketUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@ -1,265 +1,266 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.RadioGroup import android.widget.RadioGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersTelegramBinding import com.idormy.sms.forwarder.databinding.FragmentSendersTelegramBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.TelegramSetting import com.idormy.sms.forwarder.entity.setting.TelegramSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.TelegramUtils import com.idormy.sms.forwarder.utils.sender.TelegramUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.net.Proxy import java.net.Proxy
import java.util.* import java.util.*
@Page(name = "Telegram机器人") @Page(name = "Telegram机器人")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener { class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private val TAG: String = TelegramFragment::class.java.simpleName private val TAG: String = TelegramFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersTelegramBinding { ): FragmentSendersTelegramBinding {
return FragmentSendersTelegramBinding.inflate(inflater, container, false) return FragmentSendersTelegramBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.telegram) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.telegram)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener { mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, TelegramSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, TelegramSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.rgMethod.check(settingVo.getMethodCheckId()) binding!!.rgMethod.check(settingVo.getMethodCheckId())
binding!!.etApiToken.setText(settingVo.apiToken) binding!!.etApiToken.setText(settingVo.apiToken)
binding!!.etChatId.setText(settingVo.chatId) binding!!.etChatId.setText(settingVo.chatId)
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId()) binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
binding!!.etProxyHost.setText(settingVo.proxyHost) binding!!.etProxyHost.setText(settingVo.proxyHost)
binding!!.etProxyPort.setText(settingVo.proxyPort) binding!!.etProxyPort.setText(settingVo.proxyPort)
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
binding!!.etProxyUsername.setText(settingVo.proxyUsername) binding!!.etProxyUsername.setText(settingVo.proxyUsername)
binding!!.etProxyPassword.setText(settingVo.proxyPassword) binding!!.etProxyPassword.setText(settingVo.proxyPassword)
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this) binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this)
binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int -> binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) { if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) {
binding!!.layoutProxyHost.visibility = View.VISIBLE binding!!.layoutProxyHost.visibility = View.VISIBLE
binding!!.layoutProxyPort.visibility = View.VISIBLE binding!!.layoutProxyPort.visibility = View.VISIBLE
binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE
} else { } else {
binding!!.layoutProxyHost.visibility = View.GONE binding!!.layoutProxyHost.visibility = View.GONE
binding!!.layoutProxyPort.visibility = View.GONE binding!!.layoutProxyPort.visibility = View.GONE
binding!!.layoutProxyAuthenticator.visibility = View.GONE binding!!.layoutProxyAuthenticator.visibility = View.GONE
} }
} }
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() } LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
} }
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) { override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
//注意因为只有一个监听暂不需要判断id //注意因为只有一个监听暂不需要判断id
binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
when (v.id) { when (v.id) {
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
TelegramUtils.sendMsg(settingVo, msgInfo) val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
} catch (e: Exception) { TelegramUtils.sendMsg(settingVo, msgInfo)
e.printStackTrace() } catch (e: Exception) {
if (Looper.myLooper() == null) Looper.prepare() e.printStackTrace()
XToastUtils.error(e.message.toString()) if (Looper.myLooper() == null) Looper.prepare()
Looper.loop() XToastUtils.error(e.message.toString())
} Looper.loop()
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") }
}.start() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
return }.start()
} return
R.id.btn_del -> { }
if (senderId <= 0 || isClone) { R.id.btn_del -> {
popToBack() if (senderId <= 0 || isClone) {
return popToBack()
} return
}
MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title) MaterialDialog.Builder(requireContext())
.content(R.string.delete_sender_tips) .title(R.string.delete_sender_title)
.positiveText(R.string.lab_yes) .content(R.string.delete_sender_tips)
.negativeText(R.string.lab_no) .positiveText(R.string.lab_yes)
.onPositive { _: MaterialDialog?, _: DialogAction? -> .negativeText(R.string.lab_no)
viewModel.delete(senderId) .onPositive { _: MaterialDialog?, _: DialogAction? ->
XToastUtils.success(R.string.delete_sender_toast) viewModel.delete(senderId)
popToBack() XToastUtils.success(R.string.delete_sender_toast)
} popToBack()
.show() }
return .show()
} return
R.id.btn_save -> { }
val name = binding!!.etName.text.toString().trim() R.id.btn_save -> {
if (TextUtils.isEmpty(name)) { val name = binding!!.etName.text.toString().trim()
throw Exception(getString(R.string.invalid_name)) if (TextUtils.isEmpty(name)) {
} throw Exception(getString(R.string.invalid_name))
}
val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (isClone) senderId = 0 val settingVo = checkSetting()
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status) if (isClone) senderId = 0
Log.d(TAG, senderNew.toString()) val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())
viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess) viewModel.insertOrUpdate(senderNew)
popToBack() XToastUtils.success(R.string.tipSaveSuccess)
return popToBack()
} return
} }
} catch (e: Exception) { }
XToastUtils.error(e.message.toString()) } catch (e: Exception) {
e.printStackTrace() XToastUtils.error(e.message.toString())
} e.printStackTrace()
} }
}
private fun checkSetting(): TelegramSetting {
val apiToken = binding!!.etApiToken.text.toString().trim() private fun checkSetting(): TelegramSetting {
val chatId = binding!!.etChatId.text.toString().trim() val apiToken = binding!!.etApiToken.text.toString().trim()
if (TextUtils.isEmpty(apiToken) || TextUtils.isEmpty(chatId)) { val chatId = binding!!.etChatId.text.toString().trim()
throw Exception(getString(R.string.invalid_apiToken_or_chatId)) if (TextUtils.isEmpty(apiToken) || TextUtils.isEmpty(chatId)) {
} throw Exception(getString(R.string.invalid_apiToken_or_chatId))
}
val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
R.id.rb_proxyHttp -> Proxy.Type.HTTP val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
R.id.rb_proxySocks -> Proxy.Type.SOCKS R.id.rb_proxyHttp -> Proxy.Type.HTTP
else -> Proxy.Type.DIRECT R.id.rb_proxySocks -> Proxy.Type.SOCKS
} else -> Proxy.Type.DIRECT
val proxyHost = binding!!.etProxyHost.text.toString().trim() }
val proxyPort = binding!!.etProxyPort.text.toString().trim() val proxyHost = binding!!.etProxyHost.text.toString().trim()
val proxyPort = binding!!.etProxyPort.text.toString().trim()
if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
throw Exception(getString(R.string.invalid_host_or_port)) if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
} throw Exception(getString(R.string.invalid_host_or_port))
}
val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
val proxyUsername = binding!!.etProxyUsername.text.toString().trim() val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
val proxyPassword = binding!!.etProxyPassword.text.toString().trim() val proxyUsername = binding!!.etProxyUsername.text.toString().trim()
if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) { val proxyPassword = binding!!.etProxyPassword.text.toString().trim()
throw Exception(getString(R.string.invalid_username_or_password)) if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) {
} throw Exception(getString(R.string.invalid_username_or_password))
}
val method = if (binding!!.rgMethod.checkedRadioButtonId == R.id.rb_method_get) "GET" else "POST"
val method = if (binding!!.rgMethod.checkedRadioButtonId == R.id.rb_method_get) "GET" else "POST"
return TelegramSetting(method, apiToken, chatId, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
} return TelegramSetting(method, apiToken, chatId, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
}
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle() override fun onDestroyView() {
super.onDestroyView() if (mCountDownHelper != null) mCountDownHelper!!.recycle()
} super.onDestroyView()
}
} }

View File

@ -147,7 +147,8 @@ class UrlSchemeFragment : BaseFragment<FragmentSendersUrlSchemeBinding?>(), View
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
UrlSchemeUtils.sendMsg(settingVo, msgInfo) UrlSchemeUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@ -1,319 +1,314 @@
package com.idormy.sms.forwarder.fragment.senders package com.idormy.sms.forwarder.fragment.senders
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersWebhookBinding import com.idormy.sms.forwarder.databinding.FragmentSendersWebhookBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.WebhookSetting import com.idormy.sms.forwarder.entity.setting.WebhookSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.WebhookUtils import com.idormy.sms.forwarder.utils.sender.WebhookUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.* import java.util.*
@Page(name = "Webhook") @Page(name = "Webhook")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class WebhookFragment : BaseFragment<FragmentSendersWebhookBinding?>(), View.OnClickListener { class WebhookFragment : BaseFragment<FragmentSendersWebhookBinding?>(), View.OnClickListener {
private val TAG: String = WebhookFragment::class.java.simpleName private val TAG: String = WebhookFragment::class.java.simpleName
var titleBar: TitleBar? = null var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null private var mCountDownHelper: CountDownButtonHelper? = null
private var headerItemMap = HashMap<Int, LinearLayout>(2) private var headerItemMap = HashMap<Int, LinearLayout>(2)
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_ID) @AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0 var senderId: Long = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_TYPE) @AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0 var senderType: Int = 0
@JvmField @JvmField
@AutoWired(name = KEY_SENDER_CLONE) @AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false var isClone: Boolean = false
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentSendersWebhookBinding { ): FragmentSendersWebhookBinding {
return FragmentSendersWebhookBinding.inflate(inflater, container, false) return FragmentSendersWebhookBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.webhook) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.webhook)
return titleBar return titleBar
} }
/** /**
* 初始化控件 * 初始化控件
*/ */
override fun initViews() { override fun initViews() {
//测试按钮增加倒计时,避免重复点击 //测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout) mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : mCountDownHelper!!.setOnCountDownListener(object :
CountDownButtonHelper.OnCountDownListener { CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) { override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time) binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
} }
override fun onFinished() { override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test) binding!!.btnTest.text = getString(R.string.test)
} }
}) })
//新增 //新增
if (senderId <= 0) { if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender)) titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
return return
} }
//编辑 //编辑
binding!!.btnDel.setText(R.string.del) binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext()) AppDatabase.getInstance(requireContext())
.senderDao() .senderDao()
.get(senderId) .get(senderId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> { .subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {} override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
override fun onSuccess(sender: Sender) { override fun onSuccess(sender: Sender) {
if (isClone) { if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard) binding!!.btnDel.setText(R.string.discard)
} else { } else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name) titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
} }
binding!!.etName.setText(sender.name) binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1 binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, WebhookSetting::class.java) val settingVo = Gson().fromJson(sender.jsonSetting, WebhookSetting::class.java)
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
binding!!.rgMethod.check(settingVo.getMethodCheckId()) binding!!.rgMethod.check(settingVo.getMethodCheckId())
binding!!.etWebServer.setText(settingVo.webServer) binding!!.etWebServer.setText(settingVo.webServer)
binding!!.etSecret.setText(settingVo.secret) binding!!.etSecret.setText(settingVo.secret)
binding!!.etWebParams.setText(settingVo.webParams) binding!!.etWebParams.setText(settingVo.webParams)
//set header //set header
if (settingVo.headers != null) { if (settingVo.headers != null) {
for ((key, value) in settingVo.headers) { for ((key, value) in settingVo.headers) {
addHeaderItemLinearLayout( addHeaderItemLinearLayout(
headerItemMap, headerItemMap,
binding!!.layoutHeaders, binding!!.layoutHeaders,
key, key,
value value
) )
} }
} }
} }
} }
}) })
} }
override fun initListeners() { override fun initListeners() {
binding!!.btnTest.setOnClickListener(this) binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
binding!!.btnAddHeader.setOnClickListener { binding!!.btnAddHeader.setOnClickListener {
addHeaderItemLinearLayout( addHeaderItemLinearLayout(
headerItemMap, headerItemMap,
binding!!.layoutHeaders, binding!!.layoutHeaders,
null, null,
null null
) )
} }
LiveEventBus.get(KEY_SENDER_TEST, String::class.java) LiveEventBus.get(KEY_SENDER_TEST, String::class.java)
.observe(this) { mCountDownHelper?.finish() } .observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick
override fun onClick(v: View) { override fun onClick(v: View) {
try { try {
when (v.id) { when (v.id) {
R.id.btn_test -> { R.id.btn_test -> {
mCountDownHelper?.start() mCountDownHelper?.start()
Thread { Thread {
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo( val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
"sms", val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
getString(R.string.test_phone_num), WebhookUtils.sendMsg(settingVo, msgInfo)
getString(R.string.test_sender_sms), } catch (e: Exception) {
Date(), e.printStackTrace()
getString(R.string.test_sim_info) if (Looper.myLooper() == null) Looper.prepare()
) XToastUtils.error(e.message.toString())
WebhookUtils.sendMsg(settingVo, msgInfo) Looper.loop()
} catch (e: Exception) { }
e.printStackTrace() LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
if (Looper.myLooper() == null) Looper.prepare() }.start()
XToastUtils.error(e.message.toString()) return
Looper.loop() }
} R.id.btn_del -> {
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish") if (senderId <= 0 || isClone) {
}.start() popToBack()
return return
} }
R.id.btn_del -> {
if (senderId <= 0 || isClone) { MaterialDialog.Builder(requireContext())
popToBack() .title(R.string.delete_sender_title)
return .content(R.string.delete_sender_tips)
} .positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
MaterialDialog.Builder(requireContext()) .onPositive { _: MaterialDialog?, _: DialogAction? ->
.title(R.string.delete_sender_title) viewModel.delete(senderId)
.content(R.string.delete_sender_tips) XToastUtils.success(R.string.delete_sender_toast)
.positiveText(R.string.lab_yes) popToBack()
.negativeText(R.string.lab_no) }
.onPositive { _: MaterialDialog?, _: DialogAction? -> .show()
viewModel.delete(senderId) return
XToastUtils.success(R.string.delete_sender_toast) }
popToBack() R.id.btn_save -> {
} val name = binding!!.etName.text.toString().trim()
.show() if (TextUtils.isEmpty(name)) {
return throw Exception(getString(R.string.invalid_name))
} }
R.id.btn_save -> {
val name = binding!!.etName.text.toString().trim() val status = if (binding!!.sbEnable.isChecked) 1 else 0
if (TextUtils.isEmpty(name)) { val settingVo = checkSetting()
throw Exception(getString(R.string.invalid_name)) if (isClone) senderId = 0
} val senderNew =
Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
val status = if (binding!!.sbEnable.isChecked) 1 else 0 Log.d(TAG, senderNew.toString())
val settingVo = checkSetting()
if (isClone) senderId = 0 viewModel.insertOrUpdate(senderNew)
val senderNew = XToastUtils.success(R.string.tipSaveSuccess)
Sender(senderId, senderType, name, Gson().toJson(settingVo), status) popToBack()
Log.d(TAG, senderNew.toString()) return
}
viewModel.insertOrUpdate(senderNew) }
XToastUtils.success(R.string.tipSaveSuccess) } catch (e: Exception) {
popToBack() XToastUtils.error(e.message.toString())
return e.printStackTrace()
} }
} }
} catch (e: Exception) {
XToastUtils.error(e.message.toString()) private fun checkSetting(): WebhookSetting {
e.printStackTrace() val webServer = binding!!.etWebServer.text.toString().trim()
} if (!CommonUtils.checkUrl(webServer, false)) {
} throw Exception(getString(R.string.invalid_webserver))
}
private fun checkSetting(): WebhookSetting {
val webServer = binding!!.etWebServer.text.toString().trim() val method = when (binding!!.rgMethod.checkedRadioButtonId) {
if (!CommonUtils.checkUrl(webServer, false)) { R.id.rb_method_get -> "GET"
throw Exception(getString(R.string.invalid_webserver)) R.id.rb_method_put -> "PUT"
} R.id.rb_method_patch -> "PATCH"
else -> "POST"
val method = when (binding!!.rgMethod.checkedRadioButtonId) { }
R.id.rb_method_get -> "GET" val secret = binding!!.etSecret.text.toString().trim()
R.id.rb_method_put -> "PUT" val webParams = binding!!.etWebParams.text.toString().trim()
R.id.rb_method_patch -> "PATCH" val headers = getHeadersFromHeaderItemMap(headerItemMap)
else -> "POST"
} return WebhookSetting(method, webServer, secret, webParams, headers)
val secret = binding!!.etSecret.text.toString().trim() }
val webParams = binding!!.etWebParams.text.toString().trim()
val headers = getHeadersFromHeaderItemMap(headerItemMap)
//header序号
return WebhookSetting(method, webServer, secret, webParams, headers) private var headerItemId = 0
}
/**
* 动态增删header
//header序号 *
private var headerItemId = 0 * @param headerItemMap 管理item的map用于删除指定header
* @param linearLayoutWebNotifyHeaders 需要挂载item的LinearLayout
/** * @param key header的key为空则不设置
* 动态增删header * @param value header的value为空则不设置
* */
* @param headerItemMap 管理item的map用于删除指定header private fun addHeaderItemLinearLayout(
* @param linearLayoutWebNotifyHeaders 需要挂载item的LinearLayout headerItemMap: MutableMap<Int, LinearLayout>,
* @param key header的key为空则不设置 linearLayoutWebNotifyHeaders: LinearLayout,
* @param value header的value为空则不设置 key: String?,
*/ value: String?
private fun addHeaderItemLinearLayout( ) {
headerItemMap: MutableMap<Int, LinearLayout>, val linearLayoutItemAddHeader =
linearLayoutWebNotifyHeaders: LinearLayout, View.inflate(requireContext(), R.layout.item_add_header, null) as LinearLayout
key: String?, val imageViewRemoveHeader =
value: String? linearLayoutItemAddHeader.findViewById<ImageView>(R.id.imageViewRemoveHeader)
) { if (key != null && value != null) {
val linearLayoutItemAddHeader = val editTextHeaderKey =
View.inflate(requireContext(), R.layout.item_add_header, null) as LinearLayout linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderKey)
val imageViewRemoveHeader = val editTextHeaderValue =
linearLayoutItemAddHeader.findViewById<ImageView>(R.id.imageViewRemoveHeader) linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderValue)
if (key != null && value != null) { editTextHeaderKey.setText(key)
val editTextHeaderKey = editTextHeaderValue.setText(value)
linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderKey) }
val editTextHeaderValue = imageViewRemoveHeader.tag = headerItemId
linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderValue) imageViewRemoveHeader.setOnClickListener { view2: View ->
editTextHeaderKey.setText(key) val itemId = view2.tag as Int
editTextHeaderValue.setText(value) linearLayoutWebNotifyHeaders.removeView(headerItemMap[itemId])
} headerItemMap.remove(itemId)
imageViewRemoveHeader.tag = headerItemId }
imageViewRemoveHeader.setOnClickListener { view2: View -> linearLayoutWebNotifyHeaders.addView(linearLayoutItemAddHeader)
val itemId = view2.tag as Int headerItemMap[headerItemId] = linearLayoutItemAddHeader
linearLayoutWebNotifyHeaders.removeView(headerItemMap[itemId]) headerItemId++
headerItemMap.remove(itemId) }
}
linearLayoutWebNotifyHeaders.addView(linearLayoutItemAddHeader) /**
headerItemMap[headerItemId] = linearLayoutItemAddHeader * 从EditText控件中获取全部headers
headerItemId++ *
} * @param headerItemMap 管理item的map
* @return 全部headers
/** */
* 从EditText控件中获取全部headers private fun getHeadersFromHeaderItemMap(headerItemMap: Map<Int, LinearLayout>): Map<String, String> {
* val headers: MutableMap<String, String> = HashMap()
* @param headerItemMap 管理item的map for (headerItem in headerItemMap.values) {
* @return 全部headers val editTextHeaderKey = headerItem.findViewById<EditText>(R.id.editTextHeaderKey)
*/ val editTextHeaderValue = headerItem.findViewById<EditText>(R.id.editTextHeaderValue)
private fun getHeadersFromHeaderItemMap(headerItemMap: Map<Int, LinearLayout>): Map<String, String> { val key = editTextHeaderKey.text.toString().trim()
val headers: MutableMap<String, String> = HashMap() val value = editTextHeaderValue.text.toString().trim()
for (headerItem in headerItemMap.values) { headers[key] = value
val editTextHeaderKey = headerItem.findViewById<EditText>(R.id.editTextHeaderKey) }
val editTextHeaderValue = headerItem.findViewById<EditText>(R.id.editTextHeaderValue) return headers
val key = editTextHeaderKey.text.toString().trim() }
val value = editTextHeaderValue.text.toString().trim()
headers[key] = value override fun onDestroyView() {
} if (mCountDownHelper != null) mCountDownHelper!!.recycle()
return headers super.onDestroyView()
} }
override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
super.onDestroyView()
}
} }

View File

@ -202,7 +202,8 @@ class WeworkAgentFragment : BaseFragment<FragmentSendersWeworkAgentBinding?>(),
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
WeworkAgentUtils.sendMsg(settingVo, msgInfo) WeworkAgentUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@ -144,7 +144,8 @@ class WeworkRobotFragment : BaseFragment<FragmentSendersWeworkRobotBinding?>(),
try { try {
val settingVo = checkSetting() val settingVo = checkSetting()
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)) val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
WeworkRobotUtils.sendMsg(settingVo, msgInfo) WeworkRobotUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@ -565,7 +565,8 @@
<string name="seconds">secs</string> <string name="seconds">secs</string>
<string name="seconds_n">%s sec</string> <string name="seconds_n">%s sec</string>
<string name="retry">Retry</string> <string name="retry">Retry</string>
<string name="test_sender_sms">[Test Channel] Congratulations, the sending channel test is successful, please continue to add forwarding rules!</string> <string name="test_sender_sms">[%s] Congratulations, the sending channel test is successful, please continue to add forwarding rules!</string>
<string name="test_sender_name">Test Channel</string>
<string name="test_sim_info" tools:ignore="Typos">SIM1_TestOperator_18888888888</string> <string name="test_sim_info" tools:ignore="Typos">SIM1_TestOperator_18888888888</string>
<string name="keep_reminding">Continued</string> <string name="keep_reminding">Continued</string>
<string name="resend">Resend</string> <string name="resend">Resend</string>

View File

@ -566,7 +566,8 @@
<string name="seconds"></string> <string name="seconds"></string>
<string name="seconds_n">%s 秒</string> <string name="seconds_n">%s 秒</string>
<string name="retry">重试</string> <string name="retry">重试</string>
<string name="test_sender_sms">【测试通道】恭喜您,该发送通道测试成功,请继续添加转发规则!</string> <string name="test_sender_sms">【%s】恭喜您该发送通道测试成功请继续添加转发规则</string>
<string name="test_sender_name">测试通道</string>
<string name="test_sim_info" tools:ignore="Typos">SIM1_测试运营商_18888888888</string> <string name="test_sim_info" tools:ignore="Typos">SIM1_测试运营商_18888888888</string>
<string name="keep_reminding">持续提醒</string> <string name="keep_reminding">持续提醒</string>
<string name="resend">重发消息</string> <string name="resend">重发消息</string>