Skip to content

Commit

Permalink
新增:远程改话簿(方便给老人家添加联系人) #256
Browse files Browse the repository at this point in the history
  • Loading branch information
pppscn committed Feb 10, 2023
1 parent f9ddbd7 commit 1e1dd8e
Show file tree
Hide file tree
Showing 14 changed files with 491 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
XToastUtils.error(getString(R.string.click_test_button_first))
return
}
if (serverConfig != null && ((item.name == ResUtils.getString(R.string.api_sms_send) && !serverConfig!!.enableApiSmsSend) || (item.name == ResUtils.getString(R.string.api_sms_query) && !serverConfig!!.enableApiSmsQuery) || (item.name == ResUtils.getString(R.string.api_call_query) && !serverConfig!!.enableApiCallQuery) || (item.name == ResUtils.getString(R.string.api_contact_query) && !serverConfig!!.enableApiContactQuery) || (item.name == ResUtils.getString(R.string.api_battery_query) && !serverConfig!!.enableApiBatteryQuery) || (item.name == ResUtils.getString(R.string.api_wol) && !serverConfig!!.enableApiWol) || (item.name == ResUtils.getString(R.string.api_location) && !serverConfig!!.enableApiLocation))) {
if (serverConfig != null && ((item.name == ResUtils.getString(R.string.api_sms_send) && !serverConfig!!.enableApiSmsSend) || (item.name == ResUtils.getString(R.string.api_sms_query) && !serverConfig!!.enableApiSmsQuery) || (item.name == ResUtils.getString(R.string.api_call_query) && !serverConfig!!.enableApiCallQuery) || (item.name == ResUtils.getString(R.string.api_contact_query) && !serverConfig!!.enableApiContactQuery) || (item.name == ResUtils.getString(R.string.api_contact_add) && !serverConfig!!.enableApiContactAdd) || (item.name == ResUtils.getString(R.string.api_battery_query) && !serverConfig!!.enableApiBatteryQuery) || (item.name == ResUtils.getString(R.string.api_wol) && !serverConfig!!.enableApiWol) || (item.name == ResUtils.getString(R.string.api_location) && !serverConfig!!.enableApiLocation))) {
XToastUtils.error(getString(R.string.disabled_on_the_server))
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
if (isChecked) checkContactsPermission()
}

binding!!.sbApiAddContacts.isChecked = HttpServerUtils.enableApiContactAdd
binding!!.sbApiAddContacts.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
HttpServerUtils.enableApiContactAdd = isChecked
if (isChecked) checkContactsPermission()
}

binding!!.sbApiQueryBattery.isChecked = HttpServerUtils.enableApiBatteryQuery
binding!!.sbApiQueryBattery.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
HttpServerUtils.enableApiBatteryQuery = isChecked
Expand Down Expand Up @@ -435,6 +441,8 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
}
HttpServerUtils.enableApiContactQuery = false
binding!!.sbApiQueryContacts.isChecked = false
HttpServerUtils.enableApiContactAdd = false
binding!!.sbApiAddContacts.isChecked = false
}
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package com.idormy.sms.forwarder.fragment.client

import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentClientContactAddBinding
import com.idormy.sms.forwarder.server.model.BaseResponse
import com.idormy.sms.forwarder.utils.*
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.utils.TextUtils
import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xutil.data.ConvertTools

@Suppress("PropertyName")
@Page(name = "远程加话簿")
class ContactAddFragment : BaseFragment<FragmentClientContactAddBinding?>(), View.OnClickListener {

val TAG: String = ContactAddFragment::class.java.simpleName
private var mCountDownHelper: CountDownButtonHelper? = null

override fun viewBindingInflate(
inflater: LayoutInflater,
container: ViewGroup,
): FragmentClientContactAddBinding {
return FragmentClientContactAddBinding.inflate(inflater, container, false)
}

override fun initTitle(): TitleBar? {
return super.initTitle()!!.setImmersive(false).setTitle(R.string.api_contact_add)
}

/**
* 初始化控件
*/
@SuppressLint("SetTextI18n")
override fun initViews() {
//发送按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnSubmit, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnSubmit.text = String.format(getString(R.string.seconds_n), time)
}

override fun onFinished() {
binding!!.btnSubmit.text = getString(R.string.submit)
}
})
}

override fun initListeners() {
binding!!.btnSubmit.setOnClickListener(this)
LiveEventBus.get(EVENT_KEY_PHONE_NUMBERS, String::class.java).observeSticky(this) { value: String ->
binding!!.etPhoneNumbers.setText(value)
}
}

@SingleClick
override fun onClick(v: View) {
when (v.id) {
R.id.btn_submit -> {
val requestUrl: String = HttpServerUtils.serverAddress + "/contact/add"
Log.i(TAG, "requestUrl:$requestUrl")

val msgMap: MutableMap<String, Any> = mutableMapOf()
val timestamp = System.currentTimeMillis()
msgMap["timestamp"] = timestamp
val clientSignKey = HttpServerUtils.clientSignKey
if (!TextUtils.isEmpty(clientSignKey)) {
msgMap["sign"] = HttpServerUtils.calcSign(timestamp.toString(), clientSignKey)
}

val phoneNumbers = binding!!.etPhoneNumbers.text.toString()
val phoneRegex = getString(R.string.phone_numbers_regex).toRegex()
if (!phoneRegex.matches(phoneNumbers)) {
XToastUtils.error(ResUtils.getString(R.string.phone_numbers_error))
return
}

val name = binding!!.etDisplayName.text.toString()

val dataMap: MutableMap<String, Any> = mutableMapOf()
dataMap["phone_number"] = phoneNumbers
dataMap["name"] = name
msgMap["data"] = dataMap

var requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg")

val postRequest = XHttp.post(requestUrl)
.keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE)
.timeStamp(true)

when (HttpServerUtils.clientSafetyMeasures) {
2 -> {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey)
try {
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
3 -> {
try {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey)
//requestMsg = Base64.encode(requestMsg.toByteArray())
val encryptCBC = SM4Crypt.encrypt(requestMsg.toByteArray(), sm4Key)
requestMsg = ConvertTools.bytes2HexString(encryptCBC)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
else -> {
postRequest.upJson(requestMsg)
}
}

mCountDownHelper?.start()
postRequest.execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) {
XToastUtils.error(e.displayMessage)
mCountDownHelper?.finish()
}

override fun onSuccess(response: String) {
Log.i(TAG, response)
try {
var json = response
if (HttpServerUtils.clientSafetyMeasures == 2) {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey)
json = RSACrypt.decryptByPublicKey(json, publicKey)
json = String(Base64.decode(json))
} else if (HttpServerUtils.clientSafetyMeasures == 3) {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey)
val encryptCBC = ConvertTools.hexStringToByteArray(json)
val decryptCBC = SM4Crypt.decrypt(encryptCBC, sm4Key)
json = String(decryptCBC)
}
val resp: BaseResponse<String> = Gson().fromJson(json, object : TypeToken<BaseResponse<String>>() {}.type)
if (resp.code == 200) {
XToastUtils.success(ResUtils.getString(R.string.request_succeeded))
} else {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + resp.msg)
}
} catch (e: Exception) {
e.printStackTrace()
XToastUtils.error(ResUtils.getString(R.string.request_failed) + response)
}
mCountDownHelper?.finish()
}
})
}
else -> {}
}
}

override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
super.onDestroyView()
}

}
Original file line number Diff line number Diff line change
@@ -1,55 +1,58 @@
package com.idormy.sms.forwarder.server.component

import android.util.Log
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.xuexiang.xui.utils.ResUtils.getString
import com.yanzhenjie.andserver.annotation.Interceptor
import com.yanzhenjie.andserver.error.HttpException
import com.yanzhenjie.andserver.framework.HandlerInterceptor
import com.yanzhenjie.andserver.framework.handler.MethodHandler
import com.yanzhenjie.andserver.framework.handler.RequestHandler
import com.yanzhenjie.andserver.http.HttpMethod
import com.yanzhenjie.andserver.http.HttpRequest
import com.yanzhenjie.andserver.http.HttpResponse

@Suppress("PrivatePropertyName")
@Interceptor
class LoggerInterceptor : HandlerInterceptor {

private val TAG: String = "LoggerInterceptor"

override fun onIntercept(
request: HttpRequest,
respons: HttpResponse,
handler: RequestHandler,
): Boolean {
if (handler is MethodHandler) {
val httpPath = request.path
val method: HttpMethod = request.method
val valueMap = request.parameter
Log.i(TAG, "Path: $httpPath")
Log.i(TAG, "Method: " + method.value())
Log.i(TAG, "Param: $valueMap")

//判断是否开启该功能
if (
(httpPath.startsWith("/clone") && !HttpServerUtils.enableApiClone)
|| (httpPath.startsWith("/sms/send") && !HttpServerUtils.enableApiSmsSend)
|| (httpPath.startsWith("/sms/query") && !HttpServerUtils.enableApiSmsQuery)
|| (httpPath.startsWith("/call/query") && !HttpServerUtils.enableApiCallQuery)
|| (httpPath.startsWith("/contact/query") && !HttpServerUtils.enableApiContactQuery)
|| (httpPath.startsWith("/battery/query") && !HttpServerUtils.enableApiBatteryQuery)
) {
throw HttpException(500, getString(R.string.disabled_on_the_server))
}

/*
//注意:这里读取body会导致 MessageConverter 报错:RequestBody is missing.
val body = request.body?.string()
Log.i(TAG, "Body: $body")
*/
}
return false
}
package com.idormy.sms.forwarder.server.component

import android.util.Log
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.xuexiang.xui.utils.ResUtils.getString
import com.yanzhenjie.andserver.annotation.Interceptor
import com.yanzhenjie.andserver.error.HttpException
import com.yanzhenjie.andserver.framework.HandlerInterceptor
import com.yanzhenjie.andserver.framework.handler.MethodHandler
import com.yanzhenjie.andserver.framework.handler.RequestHandler
import com.yanzhenjie.andserver.http.HttpMethod
import com.yanzhenjie.andserver.http.HttpRequest
import com.yanzhenjie.andserver.http.HttpResponse

@Suppress("PrivatePropertyName")
@Interceptor
class LoggerInterceptor : HandlerInterceptor {

private val TAG: String = "LoggerInterceptor"

override fun onIntercept(
request: HttpRequest,
respons: HttpResponse,
handler: RequestHandler,
): Boolean {
if (handler is MethodHandler) {
val httpPath = request.path
val method: HttpMethod = request.method
val valueMap = request.parameter
Log.i(TAG, "Path: $httpPath")
Log.i(TAG, "Method: " + method.value())
Log.i(TAG, "Param: $valueMap")

//判断是否开启该功能
if (
(httpPath.startsWith("/clone") && !HttpServerUtils.enableApiClone)
|| (httpPath.startsWith("/sms/query") && !HttpServerUtils.enableApiSmsQuery)
|| (httpPath.startsWith("/sms/send") && !HttpServerUtils.enableApiSmsSend)
|| (httpPath.startsWith("/call/query") && !HttpServerUtils.enableApiCallQuery)
|| (httpPath.startsWith("/contact/query") && !HttpServerUtils.enableApiContactQuery)
|| (httpPath.startsWith("/contact/add") && !HttpServerUtils.enableApiContactAdd)
|| (httpPath.startsWith("/wol/send") && !HttpServerUtils.enableApiWol)
|| (httpPath.startsWith("/location/query") && !HttpServerUtils.enableApiLocation)
|| (httpPath.startsWith("/battery/query") && !HttpServerUtils.enableApiBatteryQuery)
) {
throw HttpException(500, getString(R.string.disabled_on_the_server))
}

/*
//注意:这里读取body会导致 MessageConverter 报错:RequestBody is missing.
val body = request.body?.string()
Log.i(TAG, "Body: $body")
*/
}
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ConfigController {
HttpServerUtils.enableApiSmsQuery,
HttpServerUtils.enableApiCallQuery,
HttpServerUtils.enableApiContactQuery,
HttpServerUtils.enableApiContactAdd,
HttpServerUtils.enableApiBatteryQuery,
HttpServerUtils.enableApiWol,
HttpServerUtils.enableApiLocation,
Expand Down
Loading

0 comments on commit 1e1dd8e

Please sign in to comment.