新增:远程改话簿(方便给老人家添加联系人) #256
This commit is contained in:
parent
f9ddbd7261
commit
1e1dd8e3fd
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -435,6 +441,8 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
|
|||
}
|
||||
HttpServerUtils.enableApiContactQuery = false
|
||||
binding!!.sbApiQueryContacts.isChecked = false
|
||||
HttpServerUtils.enableApiContactAdd = false
|
||||
binding!!.sbApiAddContacts.isChecked = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
|
@ -35,10 +35,13 @@ class LoggerInterceptor : HandlerInterceptor {
|
|||
//判断是否开启该功能
|
||||
if (
|
||||
(httpPath.startsWith("/clone") && !HttpServerUtils.enableApiClone)
|
||||
|| (httpPath.startsWith("/sms/send") && !HttpServerUtils.enableApiSmsSend)
|
||||
|| (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))
|
||||
|
|
|
@ -35,6 +35,7 @@ class ConfigController {
|
|||
HttpServerUtils.enableApiSmsQuery,
|
||||
HttpServerUtils.enableApiCallQuery,
|
||||
HttpServerUtils.enableApiContactQuery,
|
||||
HttpServerUtils.enableApiContactAdd,
|
||||
HttpServerUtils.enableApiBatteryQuery,
|
||||
HttpServerUtils.enableApiWol,
|
||||
HttpServerUtils.enableApiLocation,
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package com.idormy.sms.forwarder.server.controller
|
||||
|
||||
import android.content.ContentUris
|
||||
import android.content.ContentValues
|
||||
import android.provider.ContactsContract
|
||||
import android.util.Log
|
||||
import com.idormy.sms.forwarder.entity.ContactInfo
|
||||
import com.idormy.sms.forwarder.server.model.BaseRequest
|
||||
import com.idormy.sms.forwarder.server.model.ContactQueryData
|
||||
import com.idormy.sms.forwarder.utils.PhoneUtils
|
||||
import com.xuexiang.xutil.XUtil.getContentResolver
|
||||
import com.yanzhenjie.andserver.annotation.*
|
||||
|
||||
|
||||
@Suppress("PrivatePropertyName")
|
||||
@RestController
|
||||
@RequestMapping(path = ["/contact"])
|
||||
|
@ -26,4 +31,37 @@ class ContactController {
|
|||
return PhoneUtils.getContactInfoList(limit, offset, contactQueryData.phoneNumber, contactQueryData.name)
|
||||
}
|
||||
|
||||
//远程加话簿
|
||||
@CrossOrigin(methods = [RequestMethod.POST])
|
||||
@PostMapping("/add")
|
||||
fun add(@RequestBody bean: BaseRequest<ContactInfo>): String {
|
||||
val contactData = bean.data
|
||||
Log.d(TAG, contactData.toString())
|
||||
|
||||
//创建一个空的ContentValues
|
||||
val values = ContentValues()
|
||||
//首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
|
||||
val rawcontacturi = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values)
|
||||
val rawcontactid = ContentUris.parseId(rawcontacturi!!)
|
||||
|
||||
//插入姓名数据
|
||||
values.clear()
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawcontactid)
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
||||
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contactData.name)
|
||||
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values)
|
||||
|
||||
//插入电话数据
|
||||
for (phoneNumber in contactData.phoneNumber.split(";")) {
|
||||
values.clear()
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawcontactid)
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber)
|
||||
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
|
||||
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values)
|
||||
}
|
||||
|
||||
return "success"
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,8 @@ data class ConfigData(
|
|||
var enableApiCallQuery: Boolean = false,
|
||||
@SerializedName("enable_api_contact_query")
|
||||
var enableApiContactQuery: Boolean = false,
|
||||
@SerializedName("enable_api_contact_add")
|
||||
var enableApiContactAdd: Boolean = false,
|
||||
@SerializedName("enable_api_battery_query")
|
||||
var enableApiBatteryQuery: Boolean = false,
|
||||
@SerializedName("enable_api_wol")
|
||||
|
|
|
@ -356,6 +356,7 @@ const val SP_ENABLE_API_SMS_SEND = "enable_api_sms_send"
|
|||
const val SP_ENABLE_API_SMS_QUERY = "enable_api_sms_query"
|
||||
const val SP_ENABLE_API_CALL_QUERY = "enable_api_call_query"
|
||||
const val SP_ENABLE_API_CONTACT_QUERY = "enable_api_contact_query"
|
||||
const val SP_ENABLE_API_CONTACT_ADD = "enable_api_contact_add"
|
||||
const val SP_ENABLE_API_BATTERY_QUERY = "enable_api_battery_query"
|
||||
const val SP_ENABLE_API_WOL = "enable_api_wol"
|
||||
const val SP_ENABLE_API_LOCATION = "enable_api_location"
|
||||
|
@ -375,13 +376,6 @@ var CLIENT_FRAGMENT_LIST = listOf(
|
|||
CoreAnim.slide,
|
||||
R.drawable.icon_api_clone
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_sms_send),
|
||||
"com.idormy.sms.forwarder.fragment.client.SmsSendFragment",
|
||||
"{\"\":\"\"}",
|
||||
CoreAnim.slide,
|
||||
R.drawable.icon_api_sms_send
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_sms_query),
|
||||
"com.idormy.sms.forwarder.fragment.client.SmsQueryFragment",
|
||||
|
@ -389,6 +383,13 @@ var CLIENT_FRAGMENT_LIST = listOf(
|
|||
CoreAnim.slide,
|
||||
R.drawable.icon_api_sms_query
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_sms_send),
|
||||
"com.idormy.sms.forwarder.fragment.client.SmsSendFragment",
|
||||
"{\"\":\"\"}",
|
||||
CoreAnim.slide,
|
||||
R.drawable.icon_api_sms_send
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_call_query),
|
||||
"com.idormy.sms.forwarder.fragment.client.CallQueryFragment",
|
||||
|
@ -404,11 +405,11 @@ var CLIENT_FRAGMENT_LIST = listOf(
|
|||
R.drawable.icon_api_contact_query
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_battery_query),
|
||||
"com.idormy.sms.forwarder.fragment.client.BatteryQueryFragment",
|
||||
getString(R.string.api_contact_add),
|
||||
"com.idormy.sms.forwarder.fragment.client.ContactAddFragment",
|
||||
"{\"\":\"\"}",
|
||||
CoreAnim.slide,
|
||||
R.drawable.icon_api_battery_query
|
||||
R.drawable.icon_api_contact_add
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_wol),
|
||||
|
@ -424,4 +425,11 @@ var CLIENT_FRAGMENT_LIST = listOf(
|
|||
CoreAnim.slide,
|
||||
R.drawable.icon_api_location
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.api_battery_query),
|
||||
"com.idormy.sms.forwarder.fragment.client.BatteryQueryFragment",
|
||||
"{\"\":\"\"}",
|
||||
CoreAnim.slide,
|
||||
R.drawable.icon_api_battery_query
|
||||
),
|
||||
)
|
|
@ -79,6 +79,9 @@ class HttpServerUtils private constructor() {
|
|||
//是否启用远程查话簿
|
||||
var enableApiContactQuery: Boolean by SharedPreference(SP_ENABLE_API_CONTACT_QUERY, true)
|
||||
|
||||
//是否启用远程加话簿
|
||||
var enableApiContactAdd: Boolean by SharedPreference(SP_ENABLE_API_CONTACT_ADD, true)
|
||||
|
||||
//是否启用远程查电量
|
||||
var enableApiBatteryQuery: Boolean by SharedPreference(SP_ENABLE_API_BATTERY_QUERY, true)
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/xui_config_color_background"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:overScrollMode="never">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:contentDescription="@string/api_contact_add"
|
||||
app:srcCompat="@drawable/icon_api_contact_add" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/senderBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/phone_numbers" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||
android:id="@+id/et_phone_numbers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/phone_numbers_hint"
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true"
|
||||
app:met_errorMessage="@string/phone_numbers_error"
|
||||
app:met_regexp="@string/phone_numbers_regex"
|
||||
app:met_validateOnFocusLost="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/senderBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/display_name" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||
android:id="@+id/et_display_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/display_name_hint"
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||
android:id="@+id/btn_submit"
|
||||
style="@style/SuperButton.Blue.Icon"
|
||||
android:drawableStart="@drawable/ic_send_white"
|
||||
android:paddingStart="20dp"
|
||||
android:text="@string/send"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -535,21 +535,21 @@
|
|||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_sms_send"
|
||||
android:text="@string/api_sms_query"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_sms_send_tips"
|
||||
android:text="@string/api_sms_query_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_api_send_sms"
|
||||
android:id="@+id/sb_api_query_sms"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -570,21 +570,21 @@
|
|||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_sms_query"
|
||||
android:text="@string/api_sms_send"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_sms_query_tips"
|
||||
android:text="@string/api_sms_send_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_api_query_sms"
|
||||
android:id="@+id/sb_api_send_sms"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -664,8 +664,7 @@
|
|||
<LinearLayout
|
||||
style="@style/settingBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="TooManyViews">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
@ -676,21 +675,21 @@
|
|||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_battery_query"
|
||||
android:text="@string/api_contact_add"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_battery_query_tips"
|
||||
android:text="@string/api_contact_add_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_api_query_battery"
|
||||
android:id="@+id/sb_api_add_contacts"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -767,6 +766,42 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/settingBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="TooManyViews">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_battery_query"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/api_battery_query_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_api_query_battery"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
@ -804,6 +804,8 @@
|
|||
<string name="api_call_query_tips">Remotely check call records, including incoming calls, outgoing calls, and missed calls</string>
|
||||
<string name="api_contact_query">Query Linkman</string>
|
||||
<string name="api_contact_query_tips">Remotely check contact list</string>
|
||||
<string name="api_contact_add">Add Linkman</string>
|
||||
<string name="api_contact_add_tips">Remotely add contact</string>
|
||||
<string name="api_battery_query">Query Battery</string>
|
||||
<string name="api_battery_query_tips">Remotely query mobile phone power and battery status</string>
|
||||
<string name="api_wol">Remotely WOL</string>
|
||||
|
@ -817,6 +819,8 @@
|
|||
<string name="location_provider">Provider:%s</string>
|
||||
|
||||
<string name="sim_slot">Sim Slot</string>
|
||||
<string name="display_name">Display Name</string>
|
||||
<string name="display_name_hint">Optional, address book display name</string>
|
||||
<string name="phone_numbers">Phone Numbers</string>
|
||||
<string name="phone_numbers_hint">Required, separate multiple phone numbers with semicolons</string>
|
||||
<string name="phone_numbers_error">Invalid Phone Numbers, eg. 15888888888;19999999999</string>
|
||||
|
|
|
@ -805,6 +805,8 @@
|
|||
<string name="api_call_query_tips">远程查通话记录,包括来电、去电、未接电话</string>
|
||||
<string name="api_contact_query">远程查话簿</string>
|
||||
<string name="api_contact_query_tips">远程查联系人列表</string>
|
||||
<string name="api_contact_add">远程加话簿</string>
|
||||
<string name="api_contact_add_tips">远程添加联系人</string>
|
||||
<string name="api_battery_query">远程查电量</string>
|
||||
<string name="api_battery_query_tips">远程查询手机电量与电池状态</string>
|
||||
<string name="api_wol">远程WOL</string>
|
||||
|
@ -818,6 +820,8 @@
|
|||
<string name="location_provider">供应商:%s</string>
|
||||
|
||||
<string name="sim_slot">发送卡槽</string>
|
||||
<string name="display_name">姓名</string>
|
||||
<string name="display_name_hint">选填,通讯录显示名称</string>
|
||||
<string name="phone_numbers">手机号码</string>
|
||||
<string name="phone_numbers_hint">必填,多个手机号用半角分号分隔</string>
|
||||
<string name="phone_numbers_error">手机号码格式错误,例:15888888888;19999999999</string>
|
||||
|
|
Loading…
Reference in New Issue