mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 01:17:41 +08:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
751f1b3163 | ||
![]() |
45dc37aea9 | ||
![]() |
de9509fead | ||
![]() |
114052d1c6 | ||
![]() |
0391868790 | ||
![]() |
44728b858a | ||
![]() |
23acf01c61 | ||
![]() |
b733fc2d4c | ||
![]() |
992cabe323 | ||
![]() |
8b37862121 | ||
![]() |
f49310027e | ||
![]() |
cc86c0718f | ||
![]() |
2a910fe504 | ||
![]() |
0a3f9f53f1 | ||
![]() |
a77f630524 | ||
![]() |
7c33566696 | ||
![]() |
f029048d09 | ||
![]() |
b05d856f26 | ||
![]() |
3a341f6c4e | ||
![]() |
c86f20c6de | ||
![]() |
aa8ab646f5 | ||
![]() |
8e7c425fdc | ||
![]() |
dc3726d0de | ||
![]() |
3adfffee4f | ||
![]() |
c56ac0e425 | ||
![]() |
3cc2311600 | ||
![]() |
5c19c10121 | ||
![]() |
785a3a2364 | ||
![]() |
66831865cb | ||
![]() |
d4ed59b37f |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1,3 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
custom: ["https://foruda.gitee.com/images/1705068554951915754/89c6e226_16273.png", "https://afdian.net/a/pppscn", "https://github.com/pppscn/SmsForwarder/wiki/%E6%89%93%E8%B5%8F%E5%90%8D%E5%8D%95", "https://gitee.com/pp/SmsForwarder/wikis/pages?sort_id=4912193&doc_id=1821427"]
|
||||
custom: ["https://foruda.gitee.com/images/1730529431184709105/20bfc86c_16273.gif", "https://ifdian.net/a/pppscn", "https://github.com/pppscn/SmsForwarder/wiki/%E6%89%93%E8%B5%8F%E5%90%8D%E5%8D%95", "https://gitee.com/pp/SmsForwarder/wikis/pages?sort_id=4912193&doc_id=1821427"]
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,3 +28,4 @@
|
||||
/pic/*.drawio
|
||||
/pic/*.vsdx
|
||||
/psd
|
||||
/pic/*.psd
|
||||
|
@ -101,7 +101,7 @@
|
||||
+ https://github.com/yanzhenjie/AndServer (HttpServer)
|
||||
+ https://github.com/jenly1314/Location (Location)
|
||||
+ https://gitee.com/xuankaicat/kmnkt (socket通信)
|
||||
+ [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg?_ga=2.126618957.1361252949.1638261367-1417196221.1635638144&_gl=1*1pfl3dq*_ga*MTQxNzE5NjIyMS4xNjM1NjM4MTQ0*_ga_V0XZL7QHEB*MTYzODMzMjA4OC43LjAuMTYzODMzMjA5Ny4w" alt="GitHub license" style="width:96px" width="96" />](https://jb.gg/OpenSourceSupport) (License Certificate for JetBrains All Products Pack)
|
||||
+ [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg" alt="GitHub license" style="width:159px; height: 32px" width="159" height="32" />](https://jb.gg/OpenSourceSupport) (License Certificate for JetBrains All Products Pack)
|
||||
|
||||
--------
|
||||
|
||||
|
@ -97,7 +97,7 @@ See more screenshots:https://github.com/pppscn/SmsForwarder/wiki
|
||||
+ https://github.com/yanzhenjie/AndServer (HttpServer)
|
||||
+ https://github.com/jenly1314/Location (Location)
|
||||
+ https://gitee.com/xuankaicat/kmnkt (socket)
|
||||
+ [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg?_ga=2.126618957.1361252949.1638261367-1417196221.1635638144&_gl=1*1pfl3dq*_ga*MTQxNzE5NjIyMS4xNjM1NjM4MTQ0*_ga_V0XZL7QHEB*MTYzODMzMjA4OC43LjAuMTYzODMzMjA5Ny4w" alt="GitHub license" style="width:96px" width="96" />](https://jb.gg/OpenSourceSupport) (License Certificate for JetBrains All Products Pack)
|
||||
+ [<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg" alt="GitHub license" style="width:159px; height: 32px" width="159" height="32" />](https://jb.gg/OpenSourceSupport) (License Certificate for JetBrains All Products Pack)
|
||||
|
||||
--------
|
||||
|
||||
|
@ -277,8 +277,8 @@ dependencies {
|
||||
//vLayout:https://github.com/alibaba/vlayout
|
||||
implementation 'com.alibaba.android:vlayout:1.3.0'
|
||||
//下拉刷新
|
||||
implementation 'com.github.xuexiangjys.SmartRefreshLayout:refresh-header:1.1.5'
|
||||
implementation 'com.github.xuexiangjys.SmartRefreshLayout:refresh-layout:1.1.5'
|
||||
implementation 'com.github.xuexiangjys.SmartRefreshLayout:refresh-header:1.1.4'
|
||||
implementation 'com.github.xuexiangjys.SmartRefreshLayout:refresh-layout:1.1.4'
|
||||
//WebView
|
||||
implementation 'com.github.xuexiangjys.AgentWeb:agentweb-core:1.0.1'
|
||||
implementation 'com.github.xuexiangjys.AgentWeb:agentweb-download:1.0.1'//选填
|
||||
@ -286,7 +286,7 @@ dependencies {
|
||||
implementation 'me.jessyan:autosize:1.2.1'
|
||||
//友盟统计
|
||||
implementation 'com.umeng.umsdk:common:9.6.8'
|
||||
implementation 'com.umeng.umsdk:asms:1.8.2'
|
||||
implementation 'com.umeng.umsdk:asms:1.8.6'
|
||||
|
||||
//预加载占位控件
|
||||
implementation 'me.samlss:broccoli:1.0.0'
|
||||
@ -323,8 +323,8 @@ dependencies {
|
||||
implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0'
|
||||
|
||||
//MarkdownView:https://github.com/tiagohm/MarkdownView
|
||||
implementation 'com.github.tiagohm.MarkdownView:library:0.19.0'
|
||||
//implementation 'com.github.tiagohm.MarkdownView:emoji:0.19.0'
|
||||
implementation 'com.github.pppscn.MarkdownView:library:0.19.0'
|
||||
//implementation 'com.github.pppscn.MarkdownView:emoji:0.19.0'
|
||||
|
||||
def retrofit2_version = '2.9.0'
|
||||
//noinspection GradleDependency
|
||||
@ -342,13 +342,14 @@ dependencies {
|
||||
testImplementation "androidx.paging:paging-common-ktx:$paging_version"
|
||||
|
||||
//权限请求框架:https://github.com/getActivity/XXPermissions
|
||||
implementation 'com.github.getActivity:XXPermissions:18.62'
|
||||
implementation 'com.github.getActivity:XXPermissions:20.0'
|
||||
//语种切换框架:https://github.com/getActivity/MultiLanguages
|
||||
implementation 'com.github.getActivity:MultiLanguages:b47f7be' //9.3
|
||||
|
||||
def mail_version = '1.6.7'
|
||||
implementation "com.sun.mail:android-mail:$mail_version"
|
||||
implementation "com.sun.mail:android-activation:$mail_version"
|
||||
// https://jakartaee.github.io/mail-api/Android
|
||||
def mail_version = '2.0.1'
|
||||
implementation "com.sun.mail:jakarta.mail:$mail_version"
|
||||
implementation "com.sun.activation:jakarta.activation:$mail_version"
|
||||
|
||||
//国密算法SM4 的JAVA实现(基于BC实现)
|
||||
def bouncycastle_version = '1.77'
|
||||
@ -396,4 +397,4 @@ static def getGitCommitId() {
|
||||
e.printStackTrace()
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,12 @@
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera.flash"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="com.android.permission.GET_INSTALLED_APPS" />
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
@ -72,6 +77,8 @@
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
@ -156,10 +163,6 @@
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="about" />
|
||||
<data android:scheme="javascript" />
|
||||
<!-- 设置自己的deeplink -->
|
||||
<!-- <data-->
|
||||
<!-- android:host="xxx.com"-->
|
||||
<!-- android:scheme="xui"/>-->
|
||||
</intent-filter>
|
||||
<!-- AppLink -->
|
||||
<intent-filter
|
||||
@ -377,4 +380,4 @@
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
@ -1,13 +1,21 @@
|
||||
{
|
||||
"Code": 0,
|
||||
"Data": [
|
||||
{
|
||||
"title": "短信转发器",
|
||||
"content": "本软件用于监控Android手机短信、来电、APP通知,并根据指定规则转发到其他设备!<br />\n请确认您是否清楚该软件的用途?!<br />\n否则,请立即卸载!"
|
||||
},
|
||||
{
|
||||
"title": "防诈提醒",
|
||||
"content": "本软件不参与任何刷单返利担保!请您远离刷单返利陷阱,谨防网络诈骗!<br />\n请再次确认是否出于本人自用需要自愿安装?!<br />\n否则,请立即卸载!"
|
||||
},
|
||||
{
|
||||
"title": "新用户必读",
|
||||
"content": "开始设置之前,请您认真地看一遍 <a href=\"https://gitee.com/pp/SmsForwarder/wikis/pages\"><font color=\"#800080\">Wiki</font></a> !<br />\n遇到问题,请按照 <a href=\"https://gitee.com/pp/SmsForwarder/wikis/pages?sort_id=4877445&doc_id=1821427\"><font color=\"#0000FF\">常见问题</font></a> 章节进行排查!<br />\n没找到答案的,再加入互助交流群提问,请清楚地描述问题,并给出对应的配置截图与相关日志,方便大家直观的判断问题! "
|
||||
},
|
||||
{
|
||||
"title": "SmsF 互助交流群",
|
||||
"content": "<a href=\"https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&appChannel=share&inviteCode=1W5aewP&appChannel=share&businessType=9&from=246610&biz=ka\">QQ频道号: q7oofwp13s</a><br /><a href=\"https://t.me/+QBZgnL_fxYM0NjE9\">Telegram 群组</a><br />钉钉群号: 29760014208"
|
||||
"content": "<a href=\"https://t.me/+QBZgnL_fxYM0NjE9\">Telegram 群组</a>"
|
||||
},
|
||||
{
|
||||
"title": "打赏名单",
|
||||
|
@ -93,6 +93,15 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
lateinit var context: Context
|
||||
|
||||
//自定义模板可用变量标签
|
||||
var COMMON_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var SMS_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var CALL_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var APP_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var LOCATION_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var BATTERY_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var NETWORK_TAG_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
|
||||
//通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出
|
||||
var CALL_TYPE_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
var FILED_MAP: MutableMap<String, String> = mutableMapOf()
|
||||
@ -290,7 +299,7 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P && SettingUtils.enableOnePixelActivity) {
|
||||
setOnePixEnabled(true)
|
||||
}
|
||||
//奔溃是否可以重启用户界面
|
||||
//崩溃是否可以重启用户界面
|
||||
setCrashRestartUIEnabled(true)
|
||||
addCallback({
|
||||
Log.d(TAG, "Cactus保活:onStop回调")
|
||||
@ -390,6 +399,78 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
|
||||
private fun switchLanguage(newLocale: Locale) {
|
||||
isNeedSpaceBetweenWords = !newLocale.language.contains("zh")
|
||||
|
||||
//自定义模板可用变量标签
|
||||
COMMON_TAG_MAP.clear()
|
||||
COMMON_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_receive_time) to getString(R.string.insert_tag_receive_time),
|
||||
getString(R.string.tag_current_time) to getString(R.string.insert_tag_current_time),
|
||||
getString(R.string.tag_device_name) to getString(R.string.insert_tag_device_name),
|
||||
getString(R.string.tag_app_version) to getString(R.string.insert_tag_app_version),
|
||||
)
|
||||
)
|
||||
SMS_TAG_MAP.clear()
|
||||
SMS_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_from) to getString(R.string.insert_tag_from),
|
||||
getString(R.string.tag_sms) to getString(R.string.insert_tag_sms),
|
||||
getString(R.string.tag_card_slot) to getString(R.string.insert_tag_card_slot),
|
||||
getString(R.string.tag_card_subid) to getString(R.string.insert_tag_card_subid),
|
||||
getString(R.string.tag_contact_name) to getString(R.string.insert_tag_contact_name),
|
||||
getString(R.string.tag_phone_area) to getString(R.string.insert_tag_phone_area),
|
||||
)
|
||||
)
|
||||
CALL_TAG_MAP.clear()
|
||||
CALL_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_from) to getString(R.string.insert_tag_from),
|
||||
getString(R.string.tag_sms) to getString(R.string.insert_tag_msg),
|
||||
getString(R.string.tag_card_slot) to getString(R.string.insert_tag_card_slot),
|
||||
getString(R.string.tag_card_subid) to getString(R.string.insert_tag_card_subid),
|
||||
getString(R.string.tag_call_type) to getString(R.string.insert_tag_call_type),
|
||||
getString(R.string.tag_contact_name) to getString(R.string.insert_tag_contact_name),
|
||||
getString(R.string.tag_phone_area) to getString(R.string.insert_tag_phone_area),
|
||||
)
|
||||
)
|
||||
APP_TAG_MAP.clear()
|
||||
APP_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_uid) to getString(R.string.insert_tag_uid),
|
||||
getString(R.string.tag_package_name) to getString(R.string.insert_tag_package_name),
|
||||
getString(R.string.tag_app_name) to getString(R.string.insert_tag_app_name),
|
||||
getString(R.string.tag_title) to getString(R.string.insert_tag_title),
|
||||
getString(R.string.tag_msg) to getString(R.string.insert_tag_msg),
|
||||
)
|
||||
)
|
||||
LOCATION_TAG_MAP.clear()
|
||||
LOCATION_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_location) to getString(R.string.insert_tag_location),
|
||||
getString(R.string.tag_location_longitude) to getString(R.string.insert_tag_location_longitude),
|
||||
getString(R.string.tag_location_latitude) to getString(R.string.insert_tag_location_latitude),
|
||||
getString(R.string.tag_location_address) to getString(R.string.insert_tag_location_address),
|
||||
)
|
||||
)
|
||||
BATTERY_TAG_MAP.clear()
|
||||
BATTERY_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_battery_pct) to getString(R.string.insert_tag_battery_pct),
|
||||
getString(R.string.tag_battery_status) to getString(R.string.insert_tag_battery_status),
|
||||
getString(R.string.tag_battery_plugged) to getString(R.string.insert_tag_battery_plugged),
|
||||
getString(R.string.tag_battery_info) to getString(R.string.insert_tag_battery_info),
|
||||
getString(R.string.tag_battery_info_simple) to getString(R.string.insert_tag_battery_info_simple),
|
||||
)
|
||||
)
|
||||
NETWORK_TAG_MAP.clear()
|
||||
NETWORK_TAG_MAP.putAll(
|
||||
mapOf(
|
||||
getString(R.string.tag_ipv4) to getString(R.string.insert_tag_ipv4),
|
||||
getString(R.string.tag_ipv6) to getString(R.string.insert_tag_ipv6),
|
||||
getString(R.string.tag_ip_list) to getString(R.string.insert_tag_ip_list),
|
||||
getString(R.string.tag_net_type) to getString(R.string.insert_tag_net_type),
|
||||
)
|
||||
)
|
||||
|
||||
CALL_TYPE_MAP.clear()
|
||||
CALL_TYPE_MAP.putAll(
|
||||
mapOf(
|
||||
@ -471,4 +552,4 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xhttp2.XHttp
|
||||
import com.xuexiang.xhttp2.callback.DownloadProgressCallBack
|
||||
import com.xuexiang.xhttp2.exception.ApiException
|
||||
import com.xuexiang.xui.XUI.getContext
|
||||
import com.xuexiang.xui.utils.ResUtils
|
||||
import com.xuexiang.xui.utils.ThemeUtils
|
||||
import com.xuexiang.xui.utils.ViewUtils
|
||||
@ -207,10 +208,6 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(), DrawerAdapter.OnItemS
|
||||
private fun initSlidingMenu(savedInstanceState: Bundle?) {
|
||||
mSlidingRootNav = SlidingRootNavBuilder(this).withGravity(if (ResUtils.isRtl(this)) SlideGravity.RIGHT else SlideGravity.LEFT).withMenuOpened(false).withContentClickableWhenMenuOpened(false).withSavedState(savedInstanceState).withMenuLayout(R.layout.menu_left_drawer).inject()
|
||||
mLLMenu = mSlidingRootNav.layout.findViewById(R.id.ll_menu)
|
||||
//val ivQrcode = mSlidingRootNav.layout.findViewById<AppCompatImageView>(R.id.iv_qrcode)
|
||||
//ivQrcode.setOnClickListener { openNewPage(SettingsFragment::class.java) }
|
||||
//val ivSetting = mSlidingRootNav.layout.findViewById<AppCompatImageView>(R.id.iv_setting)
|
||||
//ivSetting.setOnClickListener { openNewPage(SettingsFragment::class.java) }
|
||||
ViewUtils.setVisibility(mLLMenu, false)
|
||||
mAdapter = DrawerAdapter(
|
||||
mutableListOf(
|
||||
@ -243,25 +240,6 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(), DrawerAdapter.OnItemS
|
||||
|
||||
override fun onDragEnd(isMenuOpened: Boolean) {
|
||||
ViewUtils.setVisibility(mLLMenu, isMenuOpened)
|
||||
/*if (isMenuOpened) {
|
||||
if (!GuideCaseView.isShowOnce(this@MainActivity, getString(R.string.guide_key_sliding_root_navigation))) {
|
||||
val guideStep1 = GuideCaseView.Builder(this@MainActivity)
|
||||
.title("点击进入,可切换主题样式哦~~")
|
||||
.titleSize(18, TypedValue.COMPLEX_UNIT_SP)
|
||||
.focusOn(ivSetting)
|
||||
.build()
|
||||
val guideStep2 = GuideCaseView.Builder(this@MainActivity)
|
||||
.title("点击进入,扫码关注哦~~")
|
||||
.titleSize(18, TypedValue.COMPLEX_UNIT_SP)
|
||||
.focusOn(ivQrcode)
|
||||
.build()
|
||||
GuideCaseQueue()
|
||||
.add(guideStep1)
|
||||
.add(guideStep2)
|
||||
.show()
|
||||
GuideCaseView.setShowOnce(this@MainActivity, getString(R.string.guide_key_sliding_root_navigation))
|
||||
}
|
||||
}*/
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -302,14 +280,26 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(), DrawerAdapter.OnItemS
|
||||
}
|
||||
|
||||
POS_APPS -> {
|
||||
if (App.UserAppList.isEmpty() && App.SystemAppList.isEmpty()) {
|
||||
XToastUtils.info(getString(R.string.loading_app_list))
|
||||
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
|
||||
WorkManager.getInstance(this).enqueue(request)
|
||||
needToAppListFragment = true
|
||||
return
|
||||
}
|
||||
openNewPage(AppListFragment::class.java)
|
||||
//检查读取应用列表权限是否获取
|
||||
XXPermissions.with(this).permission(Permission.GET_INSTALLED_APPS).request(object : OnPermissionCallback {
|
||||
override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
|
||||
if (App.UserAppList.isEmpty() && App.SystemAppList.isEmpty()) {
|
||||
XToastUtils.info(getString(R.string.loading_app_list))
|
||||
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
|
||||
WorkManager.getInstance(getContext()).enqueue(request)
|
||||
needToAppListFragment = true
|
||||
return
|
||||
}
|
||||
openNewPage(AppListFragment::class.java)
|
||||
}
|
||||
|
||||
override fun onDenied(permissions: MutableList<String>, doNotAskAgain: Boolean) {
|
||||
XToastUtils.error(R.string.tips_get_installed_apps)
|
||||
if (doNotAskAgain) {
|
||||
XXPermissions.startPermissionActivity(getContext(), permissions)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
POS_HELP -> AgentWebActivity.goWeb(this, getString(R.string.url_help))
|
||||
@ -389,4 +379,4 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(), DrawerAdapter.OnItemS
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package com.idormy.sms.forwarder.core.http.api
|
||||
|
||||
import com.idormy.sms.forwarder.core.http.entity.TipInfo
|
||||
import com.xuexiang.xhttp2.model.ApiResult
|
||||
import io.reactivex.Observable
|
||||
import retrofit2.http.GET
|
||||
|
||||
/**
|
||||
* @author xuexiang
|
||||
* @since 2021/1/9 7:01 PM
|
||||
*/
|
||||
@Suppress("unused")
|
||||
class ApiService {
|
||||
/**
|
||||
* 使用的是retrofit的接口定义
|
||||
*/
|
||||
interface IGetService {
|
||||
/**
|
||||
* 获得小贴士
|
||||
*/
|
||||
@get:GET("/pp/SmsForwarder.wiki/raw/master/tips.json")
|
||||
val tips: Observable<ApiResult<List<TipInfo?>?>>
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package com.idormy.sms.forwarder.core.http.callback
|
||||
|
||||
import com.xuexiang.xhttp2.callback.SimpleCallBack
|
||||
import com.xuexiang.xhttp2.exception.ApiException
|
||||
import com.xuexiang.xhttp2.model.XHttpRequest
|
||||
import com.xuexiang.xutil.common.StringUtils
|
||||
import com.xuexiang.xutil.common.logger.Logger
|
||||
|
||||
/**
|
||||
* 不带错误提示的网络请求回调
|
||||
*
|
||||
* @author xuexiang
|
||||
* @since 2019-11-18 23:02
|
||||
*/
|
||||
@Suppress("unused")
|
||||
abstract class NoTipCallBack<T> : SimpleCallBack<T> {
|
||||
/**
|
||||
* 记录一下请求的url,确定出错的请求是哪个请求
|
||||
*/
|
||||
private var mUrl: String? = null
|
||||
|
||||
constructor()
|
||||
constructor(req: XHttpRequest) : this(req.url)
|
||||
constructor(url: String?) {
|
||||
mUrl = url
|
||||
}
|
||||
|
||||
override fun onError(e: ApiException) {
|
||||
if (!StringUtils.isEmpty(mUrl)) {
|
||||
Logger.e("Request Url: $mUrl", e)
|
||||
} else {
|
||||
Logger.e(e)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.idormy.sms.forwarder.core.http.callback
|
||||
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.xuexiang.xhttp2.callback.SimpleCallBack
|
||||
import com.xuexiang.xhttp2.exception.ApiException
|
||||
import com.xuexiang.xhttp2.model.XHttpRequest
|
||||
import com.xuexiang.xutil.common.StringUtils
|
||||
import com.xuexiang.xutil.common.logger.Logger
|
||||
|
||||
/**
|
||||
* 带错误toast提示的网络请求回调
|
||||
*
|
||||
* @author xuexiang
|
||||
* @since 2019-11-18 23:02
|
||||
*/
|
||||
@Suppress("unused")
|
||||
abstract class TipCallBack<T> : SimpleCallBack<T> {
|
||||
/**
|
||||
* 记录一下请求的url,确定出错的请求是哪个请求
|
||||
*/
|
||||
private var mUrl: String? = null
|
||||
|
||||
constructor()
|
||||
constructor(req: XHttpRequest) : this(req.url)
|
||||
constructor(url: String?) {
|
||||
mUrl = url
|
||||
}
|
||||
|
||||
override fun onError(e: ApiException) {
|
||||
XToastUtils.error(e)
|
||||
if (!StringUtils.isEmpty(mUrl)) {
|
||||
Logger.e("Request Url: $mUrl", e)
|
||||
} else {
|
||||
Logger.e(e)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.idormy.sms.forwarder.core.http.callback
|
||||
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.xuexiang.xhttp2.callback.ProgressLoadingCallBack
|
||||
import com.xuexiang.xhttp2.exception.ApiException
|
||||
import com.xuexiang.xhttp2.model.XHttpRequest
|
||||
import com.xuexiang.xhttp2.subsciber.impl.IProgressLoader
|
||||
import com.xuexiang.xutil.common.StringUtils
|
||||
import com.xuexiang.xutil.common.logger.Logger
|
||||
|
||||
/**
|
||||
* 带错误toast提示和加载进度条的网络请求回调
|
||||
*
|
||||
* @author xuexiang
|
||||
* @since 2019-11-18 23:16
|
||||
*/
|
||||
@Suppress("unused")
|
||||
abstract class TipProgressLoadingCallBack<T> : ProgressLoadingCallBack<T> {
|
||||
/**
|
||||
* 记录一下请求的url,确定出错的请求是哪个请求
|
||||
*/
|
||||
private var mUrl: String? = null
|
||||
|
||||
constructor(fragment: BaseFragment<*>) : super(fragment.progressLoader)
|
||||
constructor(iProgressLoader: IProgressLoader?) : super(iProgressLoader)
|
||||
constructor(req: XHttpRequest, iProgressLoader: IProgressLoader?) : this(
|
||||
req.url,
|
||||
iProgressLoader
|
||||
)
|
||||
|
||||
constructor(url: String?, iProgressLoader: IProgressLoader?) : super(iProgressLoader) {
|
||||
mUrl = url
|
||||
}
|
||||
|
||||
override fun onError(e: ApiException) {
|
||||
super.onError(e)
|
||||
XToastUtils.error(e)
|
||||
if (!StringUtils.isEmpty(mUrl)) {
|
||||
Logger.e("Request Url: $mUrl", e)
|
||||
} else {
|
||||
Logger.e(e)
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ import com.idormy.sms.forwarder.utils.TAG_LIST
|
||||
@Database(
|
||||
entities = [Frpc::class, Msg::class, Logs::class, Rule::class, Sender::class, Task::class],
|
||||
views = [LogsDetail::class],
|
||||
version = 19,
|
||||
version = 20,
|
||||
exportSchema = false
|
||||
)
|
||||
@TypeConverters(ConvertersDate::class)
|
||||
@ -110,6 +110,7 @@ custom_domains = smsf.demo.com
|
||||
MIGRATION_16_17,
|
||||
MIGRATION_17_18,
|
||||
MIGRATION_18_19,
|
||||
MIGRATION_19_20,
|
||||
)
|
||||
|
||||
/*if (BuildConfig.DEBUG) {
|
||||
@ -452,6 +453,13 @@ CREATE TABLE "Task" (
|
||||
}
|
||||
}
|
||||
|
||||
//免打扰星期段
|
||||
private val MIGRATION_19_20 = object : Migration(19, 20) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("Alter table rule add column silent_day_of_week TEXT NOT NULL DEFAULT '' ")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ data class Rule(
|
||||
//免打扰(禁用转发)时间段
|
||||
@ColumnInfo(name = "silent_period_start", defaultValue = "0") var silentPeriodStart: Int = 0,
|
||||
@ColumnInfo(name = "silent_period_end", defaultValue = "0") var silentPeriodEnd: Int = 0,
|
||||
@ColumnInfo(name = "silent_day_of_week", defaultValue = "") var silentDayOfWeek: String = "",
|
||||
) : Parcelable {
|
||||
|
||||
companion object {
|
||||
|
@ -10,6 +10,7 @@ import com.idormy.sms.forwarder.utils.AppUtils
|
||||
import com.idormy.sms.forwarder.utils.BatteryUtils
|
||||
import com.idormy.sms.forwarder.utils.HttpServerUtils
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.PhoneUtils
|
||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.enableSmsTemplate
|
||||
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.extraDeviceMark
|
||||
@ -129,6 +130,8 @@ data class MsgInfo(
|
||||
)
|
||||
.replaceAppNameTag(from, encoderName)
|
||||
.replaceLocationTag(encoderName)
|
||||
.replaceContactNameTag(encoderName)
|
||||
.replacePhoneAreaTag(encoderName)
|
||||
.regexReplace(regexReplace)
|
||||
.trim()
|
||||
}
|
||||
@ -185,6 +188,33 @@ data class MsgInfo(
|
||||
return result
|
||||
}
|
||||
|
||||
//替换{{CONTACT_NAME}}标签
|
||||
private fun String.replaceContactNameTag(encoderName: String = ""): String {
|
||||
if (TextUtils.isEmpty(this)) return this
|
||||
if (this.indexOf(getString(R.string.tag_contact_name)) == -1) return this
|
||||
|
||||
val contacts = PhoneUtils.getContactByNumber(from)
|
||||
var contactName = if (contacts.isNotEmpty()) contacts[0].name else getString(R.string.unknown_number)
|
||||
when (encoderName) {
|
||||
"Gson" -> contactName = toJsonStr(contactName)
|
||||
"URLEncoder" -> contactName = URLEncoder.encode(contactName, "UTF-8")
|
||||
}
|
||||
return this.replaceTag(getString(R.string.tag_contact_name), contactName)
|
||||
}
|
||||
|
||||
//替换{{PHONE_AREA}}标签
|
||||
private fun String.replacePhoneAreaTag(encoderName: String = ""): String {
|
||||
if (TextUtils.isEmpty(this)) return this
|
||||
if (this.indexOf(getString(R.string.tag_phone_area)) == -1) return this
|
||||
|
||||
var phoneArea = PhoneUtils.getPhoneArea(from)
|
||||
when (encoderName) {
|
||||
"Gson" -> phoneArea = toJsonStr(phoneArea)
|
||||
"URLEncoder" -> phoneArea = URLEncoder.encode(phoneArea, "UTF-8")
|
||||
}
|
||||
return this.replaceTag(getString(R.string.tag_phone_area), phoneArea)
|
||||
}
|
||||
|
||||
//替换{{APP名称}}标签
|
||||
private fun String.replaceAppNameTag(packageName: String, encoderName: String = ""): String {
|
||||
if (TextUtils.isEmpty(this)) return this
|
||||
@ -256,4 +286,4 @@ data class MsgInfo(
|
||||
", simInfo=" + simInfo +
|
||||
'}'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,11 @@ import java.io.Serializable
|
||||
data class AlarmSetting(
|
||||
var description: String = "", //描述
|
||||
var action: String = "stop", //动作: start=启动警报, stop=停止警报
|
||||
var volume: Int = 80, //播放音量
|
||||
var playTimes: Int = 1, //播放次数,0=无限循环
|
||||
var volume: Int = 80, //播放音量,0-100
|
||||
var playTimes: Int = 1, //播放次数,0=无限循环,-1=禁用
|
||||
var music: String = "", //音乐文件
|
||||
var repeatTimes: Int = 5, //振动重复次数,0=无限循环,-1=禁用
|
||||
var vibrate: String = "---___===___", //振动律动:=强振动, -弱震动, _不振动, 时长都是100ms
|
||||
var flashTimes: Int = 5, //闪烁次数,0=无限循环,-1=禁用
|
||||
var flash: String = "XXOOXXOO", //闪烁律动:X亮灯, O灭灯, 时长都是100ms
|
||||
) : Serializable
|
||||
|
@ -25,4 +25,8 @@ data class BarkSetting(
|
||||
val key: String = "",
|
||||
//初始偏移向量
|
||||
val iv: String = "",
|
||||
) : Serializable
|
||||
//持续提醒
|
||||
val call: String = "",
|
||||
//自动复制模板
|
||||
val autoCopy: String = "",
|
||||
) : Serializable
|
||||
|
@ -14,6 +14,7 @@ data class TelegramSetting(
|
||||
val proxyAuthenticator: Boolean = false,
|
||||
val proxyUsername: String = "",
|
||||
val proxyPassword: String = "",
|
||||
val parseMode: String = "HTML",
|
||||
) : Serializable {
|
||||
|
||||
fun getMethodCheckId(): Int {
|
||||
@ -27,4 +28,12 @@ data class TelegramSetting(
|
||||
else -> R.id.rb_proxyNone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getParseModeCheckId(): Int {
|
||||
return when (parseMode) {
|
||||
"TEXT" -> R.id.rb_parse_mode_text
|
||||
"MarkdownV2" -> R.id.rb_parse_mode_markdown
|
||||
else -> R.id.rb_parse_mode_html
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.hjq.permissions.OnPermissionCallback
|
||||
import com.hjq.permissions.Permission
|
||||
import com.hjq.permissions.XXPermissions
|
||||
import com.idormy.sms.forwarder.App
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.AppListAdapter
|
||||
@ -24,11 +27,11 @@ import com.scwang.smartrefresh.layout.api.RefreshLayout
|
||||
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xui.XUI
|
||||
import com.xuexiang.xui.utils.DensityUtils
|
||||
import com.xuexiang.xui.utils.ThemeUtils
|
||||
import com.xuexiang.xui.utils.WidgetUtils
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xutil.XUtil
|
||||
import com.xuexiang.xutil.resource.ResUtils.getStringArray
|
||||
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
@ -91,10 +94,10 @@ class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
|
||||
}
|
||||
|
||||
override fun onRefresh(refreshLayout: RefreshLayout) {
|
||||
appListAdapter?.refresh(getAppsList(true))
|
||||
refreshLayout.layout.postDelayed({
|
||||
appListAdapter?.refresh(getAppsList(true))
|
||||
refreshLayout.finishRefresh()
|
||||
}, 3000)
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
appListAdapter?.setOnItemClickListener { _, item, _ ->
|
||||
@ -120,12 +123,24 @@ class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
|
||||
|
||||
private fun getAppsList(refresh: Boolean): MutableList<AppInfo> {
|
||||
if (refresh || (currentType == "user" && App.UserAppList.isEmpty()) || (currentType == "system" && App.SystemAppList.isEmpty())) {
|
||||
XToastUtils.info(getString(R.string.loading_app_list))
|
||||
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
|
||||
WorkManager.getInstance(XUtil.getContext()).enqueue(request)
|
||||
//检查读取应用列表权限是否获取
|
||||
XXPermissions.with(this).permission(Permission.GET_INSTALLED_APPS).request(object : OnPermissionCallback {
|
||||
override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
|
||||
XToastUtils.info(getString(R.string.loading_app_list))
|
||||
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
|
||||
WorkManager.getInstance(XUI.getContext()).enqueue(request)
|
||||
}
|
||||
|
||||
override fun onDenied(permissions: MutableList<String>, doNotAskAgain: Boolean) {
|
||||
XToastUtils.error(R.string.tips_get_installed_apps)
|
||||
if (doNotAskAgain) {
|
||||
XXPermissions.startPermissionActivity(XUI.getContext(), permissions)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return if (currentType == "system") App.SystemAppList else App.UserAppList
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
@Page(name = "转发规则·编辑器")
|
||||
@ -165,9 +166,6 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
binding!!.rbCallType.visibility = View.GONE
|
||||
binding!!.rbContent.visibility = View.GONE
|
||||
binding!!.tvMuRuleTips.setText(R.string.mu_rule_app_tips)
|
||||
binding!!.btInsertExtra.visibility = View.GONE
|
||||
binding!!.btInsertSender.visibility = View.GONE
|
||||
binding!!.btInsertContent.visibility = View.GONE
|
||||
//初始化APP下拉列表
|
||||
initAppSpinner()
|
||||
//监听已安装App信息列表加载完成事件
|
||||
@ -182,11 +180,6 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
binding!!.rbInformContent.visibility = View.GONE
|
||||
//binding!!.rbMultiMatch.visibility = View.GONE
|
||||
binding!!.tvMuRuleTips.setText(R.string.mu_rule_call_tips)
|
||||
binding!!.btInsertContent.visibility = View.GONE
|
||||
binding!!.btInsertSenderApp.visibility = View.GONE
|
||||
binding!!.btInsertUid.visibility = View.GONE
|
||||
binding!!.btInsertTitleApp.visibility = View.GONE
|
||||
binding!!.btInsertContentApp.visibility = View.GONE
|
||||
|
||||
//通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出
|
||||
binding!!.spCallType.setItems(CALL_TYPE_MAP.values.toList())
|
||||
@ -209,13 +202,12 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
binding!!.rbPackageName.visibility = View.GONE
|
||||
binding!!.rbUid.visibility = View.GONE
|
||||
binding!!.rbInformContent.visibility = View.GONE
|
||||
binding!!.btInsertSenderApp.visibility = View.GONE
|
||||
binding!!.btInsertUid.visibility = View.GONE
|
||||
binding!!.btInsertTitleApp.visibility = View.GONE
|
||||
binding!!.btInsertContentApp.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glSmsTemplate, binding!!.etSmsTemplate, ruleType)
|
||||
|
||||
if (ruleId <= 0) { //新增
|
||||
titleBar?.setSubTitle(getString(R.string.add_rule))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
@ -229,15 +221,6 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnSilentPeriod.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertContent.setOnClickListener(this)
|
||||
binding!!.btInsertSenderApp.setOnClickListener(this)
|
||||
binding!!.btInsertUid.setOnClickListener(this)
|
||||
binding!!.btInsertTitleApp.setOnClickListener(this)
|
||||
binding!!.btInsertContentApp.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -333,7 +316,6 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etSmsTemplate: EditText = binding!!.etSmsTemplate
|
||||
when (v.id) {
|
||||
R.id.btn_silent_period -> {
|
||||
OptionsPickerBuilder(context, OnOptionsSelectListener { _: View?, options1: Int, options2: Int, _: Int ->
|
||||
@ -349,51 +331,6 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
}
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_sms))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender_app -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_package_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_uid -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_uid))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_title_app -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_title))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content_app -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_msg))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
val ruleNew = checkForm()
|
||||
testRule(ruleNew)
|
||||
@ -639,6 +576,21 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
silentPeriodEnd = rule.silentPeriodEnd
|
||||
//初始化发送通道下拉框
|
||||
initSenderSpinner()
|
||||
|
||||
//绑定免打扰日期
|
||||
val silentPeriodDays = rule.silentDayOfWeek.split(",").filter { it.isNotEmpty() }.map { it.toInt() }
|
||||
if (silentPeriodDays.isNotEmpty()) {
|
||||
val map = mapOf(
|
||||
Calendar.SUNDAY to binding!!.sun,
|
||||
Calendar.MONDAY to binding!!.mon,
|
||||
Calendar.TUESDAY to binding!!.tue,
|
||||
Calendar.WEDNESDAY to binding!!.wed,
|
||||
Calendar.THURSDAY to binding!!.thu,
|
||||
Calendar.FRIDAY to binding!!.fri,
|
||||
Calendar.SATURDAY to binding!!.sat,
|
||||
)
|
||||
silentPeriodDays.forEach { map[it]?.isChecked = true }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -715,6 +667,19 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
}
|
||||
val status = if (binding!!.sbStatus.isChecked) STATUS_ON else STATUS_OFF
|
||||
|
||||
val map = mapOf(
|
||||
Calendar.SUNDAY to binding!!.sun,
|
||||
Calendar.MONDAY to binding!!.mon,
|
||||
Calendar.TUESDAY to binding!!.tue,
|
||||
Calendar.WEDNESDAY to binding!!.wed,
|
||||
Calendar.THURSDAY to binding!!.thu,
|
||||
Calendar.FRIDAY to binding!!.fri,
|
||||
Calendar.SATURDAY to binding!!.sat,
|
||||
)
|
||||
|
||||
val silentDayOfWeek = map.filter { it.value.isChecked }
|
||||
.toList().map { it.first }.joinToString(",")
|
||||
|
||||
return Rule(
|
||||
ruleId,
|
||||
ruleType,
|
||||
@ -730,7 +695,8 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
senderListSelected,
|
||||
senderLogic,
|
||||
silentPeriodStart,
|
||||
silentPeriodEnd
|
||||
silentPeriodEnd,
|
||||
silentDayOfWeek,
|
||||
)
|
||||
}
|
||||
|
||||
@ -852,7 +818,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
val contactName = if (contacts.isNotEmpty()) contacts[0].name else getString(R.string.unknown_number)
|
||||
msg.append(getString(R.string.contact)).append(contactName).append("\n")
|
||||
msg.append(getString(R.string.mandatory_type))
|
||||
msg.append(CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call))
|
||||
msg.append(CALL_TYPE_MAP[callTypeTest.toString()] ?: getString(R.string.unknown_call))
|
||||
} else {
|
||||
msg.append(etContent.text.toString())
|
||||
}
|
||||
@ -877,4 +843,4 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,12 +180,18 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
editAddExtraDeviceMark(binding!!.etExtraDeviceMark)
|
||||
//SIM1主键
|
||||
editAddSubidSim1(binding!!.etSubidSim1)
|
||||
//SIM2主键
|
||||
editAddSubidSim2(binding!!.etSubidSim2)
|
||||
//SIM1备注
|
||||
editAddExtraSim1(binding!!.etExtraSim1)
|
||||
//SIM2备注
|
||||
editAddExtraSim2(binding!!.etExtraSim2)
|
||||
|
||||
// sim 槽只有一个的时候不显示 SIM2 设置
|
||||
if (PhoneUtils.getSimSlotCount() != 1) {
|
||||
//SIM2主键
|
||||
editAddSubidSim2(binding!!.etSubidSim2)
|
||||
//SIM2备注
|
||||
editAddExtraSim2(binding!!.etExtraSim2)
|
||||
} else {
|
||||
binding!!.layoutSim2.visibility = View.GONE
|
||||
}
|
||||
//通知内容
|
||||
editNotifyContent(binding!!.etNotifyContent)
|
||||
//启用自定义模版
|
||||
@ -215,11 +221,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
binding!!.btnExtraDeviceMark.setOnClickListener(this)
|
||||
binding!!.btnExtraSim1.setOnClickListener(this)
|
||||
binding!!.btnExtraSim2.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertContent.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnExportLog.setOnClickListener(this)
|
||||
|
||||
//监听已安装App信息列表加载完成事件
|
||||
@ -229,7 +230,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
@SuppressLint("SetTextI18n")
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
val etSmsTemplate: EditText = binding!!.etSmsTemplate
|
||||
when (v.id) {
|
||||
R.id.btn_silent_period -> {
|
||||
OptionsPickerBuilder(context, OnOptionsSelectListener { _: View?, options1: Int, options2: Int, _: Int ->
|
||||
@ -298,37 +298,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_sms))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(
|
||||
etSmsTemplate, getString(R.string.tag_card_slot)
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(
|
||||
etSmsTemplate, getString(R.string.tag_receive_time)
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(
|
||||
etSmsTemplate, getString(R.string.tag_device_name)
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_export_log -> {
|
||||
XXPermissions.with(this)
|
||||
// 申请储存权限
|
||||
@ -991,7 +960,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
|
||||
//设置SIM1主键
|
||||
private fun editAddSubidSim1(etSubidSim1: EditText) {
|
||||
etSubidSim1.setText(SettingUtils.subidSim1.toString())
|
||||
etSubidSim1.setText("${SettingUtils.subidSim1}")
|
||||
etSubidSim1.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||
@ -1008,7 +977,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
|
||||
//设置SIM2主键
|
||||
private fun editAddSubidSim2(etSubidSim2: EditText) {
|
||||
etSubidSim2.setText(SettingUtils.subidSim2.toString())
|
||||
etSubidSim2.setText("${SettingUtils.subidSim2}")
|
||||
etSubidSim2.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||
@ -1092,6 +1061,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
|
||||
//设置转发信息模版
|
||||
private fun editSmsTemplate(textSmsTemplate: EditText) {
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glSmsTemplate, textSmsTemplate, "all")
|
||||
textSmsTemplate.setText(SettingUtils.smsTemplate)
|
||||
textSmsTemplate.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
@ -1206,6 +1177,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
"huawei" -> getString(R.string.auto_start_huawei)
|
||||
"honor" -> getString(R.string.auto_start_honor)
|
||||
"xiaomi" -> getString(R.string.auto_start_xiaomi)
|
||||
"redmi" -> getString(R.string.auto_start_redmi)
|
||||
"oppo" -> getString(R.string.auto_start_oppo)
|
||||
"vivo" -> getString(R.string.auto_start_vivo)
|
||||
"meizu" -> getString(R.string.auto_start_meizu)
|
||||
|
@ -20,6 +20,7 @@ import com.idormy.sms.forwarder.databinding.FragmentTasksActionAlarmBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||
import com.idormy.sms.forwarder.entity.action.AlarmSetting
|
||||
import com.idormy.sms.forwarder.utils.CommonUtils
|
||||
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
|
||||
@ -37,6 +38,7 @@ import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import java.io.File
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
@Page(name = "Alarm")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
@ -84,24 +86,45 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
}
|
||||
})
|
||||
|
||||
binding!!.sbEnableMusic.setOnCheckedChangeListener { _, isChecked ->
|
||||
binding!!.layoutAlarmSettingsContent.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
checkSetting(true)
|
||||
}
|
||||
binding!!.sbEnableVibrate.setOnCheckedChangeListener { _, isChecked ->
|
||||
binding!!.layoutVibrateSettingsContent.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
checkSetting(true)
|
||||
}
|
||||
|
||||
var settingVo = AlarmSetting()
|
||||
Log.d(TAG, "initViews eventData:$eventData")
|
||||
if (eventData != null) {
|
||||
val settingVo = Gson().fromJson(eventData, AlarmSetting::class.java)
|
||||
settingVo = Gson().fromJson(eventData, AlarmSetting::class.java)
|
||||
Log.d(TAG, "initViews settingVo:$settingVo")
|
||||
if (settingVo.action == "start") {
|
||||
binding!!.rgAlarmState.check(R.id.rb_start_alarm)
|
||||
binding!!.layoutAlarmSettings.visibility = View.VISIBLE
|
||||
binding!!.layoutVibrateSettings.visibility = View.VISIBLE
|
||||
binding!!.layoutFlashSettings.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding!!.rgAlarmState.check(R.id.rb_stop_alarm)
|
||||
binding!!.layoutAlarmSettings.visibility = View.GONE
|
||||
binding!!.layoutVibrateSettings.visibility = View.GONE
|
||||
binding!!.layoutFlashSettings.visibility = View.GONE
|
||||
}
|
||||
binding!!.xsbVolume.setDefaultValue(settingVo.volume)
|
||||
binding!!.xsbLoopTimes.setDefaultValue(settingVo.playTimes)
|
||||
binding!!.etMusicPath.setText(settingVo.music)
|
||||
} else {
|
||||
binding!!.xsbVolume.setDefaultValue(80)
|
||||
binding!!.xsbLoopTimes.setDefaultValue(1)
|
||||
}
|
||||
binding!!.xsbVolume.setDefaultValue(settingVo.volume)
|
||||
binding!!.xsbPlayTimes.setDefaultValue(if (settingVo.playTimes >= 0) settingVo.playTimes else 0)
|
||||
binding!!.etMusicPath.setText(settingVo.music)
|
||||
binding!!.xsbRepeatTimes.setDefaultValue(if (settingVo.repeatTimes >= 0) settingVo.repeatTimes else 0)
|
||||
binding!!.etVibrationEffect.setText(settingVo.vibrate)
|
||||
binding!!.xsbFlashTimes.setDefaultValue(if (settingVo.flashTimes >= 0) settingVo.flashTimes else 0)
|
||||
binding!!.etFlashEffect.setText(settingVo.flash)
|
||||
binding!!.sbEnableMusic.isChecked = settingVo.playTimes >= 0
|
||||
binding!!.sbEnableVibrate.isChecked = settingVo.repeatTimes >= 0
|
||||
binding!!.sbEnableFlash.isChecked = settingVo.flashTimes >= 0
|
||||
binding!!.layoutAlarmSettingsContent.visibility = if (settingVo.playTimes >= 0) View.VISIBLE else View.GONE
|
||||
binding!!.layoutVibrateSettingsContent.visibility = if (settingVo.repeatTimes >= 0) View.VISIBLE else View.GONE
|
||||
binding!!.layoutFlashSettingsContent.visibility = if (settingVo.flashTimes >= 0) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -118,19 +141,53 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
binding!!.xsbVolume.setOnSeekBarListener { _, _ ->
|
||||
checkSetting(true)
|
||||
}
|
||||
binding!!.xsbLoopTimes.setOnSeekBarListener { _, _ ->
|
||||
binding!!.xsbPlayTimes.setOnSeekBarListener { _, _ ->
|
||||
checkSetting(true)
|
||||
}
|
||||
binding!!.xsbRepeatTimes.setOnSeekBarListener { _, _ ->
|
||||
checkSetting(true)
|
||||
}
|
||||
binding!!.rgAlarmState.setOnCheckedChangeListener { _, checkedId ->
|
||||
binding!!.layoutAlarmSettings.visibility = if (checkedId == R.id.rb_start_alarm) View.VISIBLE else View.GONE
|
||||
binding!!.layoutVibrateSettings.visibility = if (checkedId == R.id.rb_start_alarm) View.VISIBLE else View.GONE
|
||||
binding!!.layoutFlashSettings.visibility = if (checkedId == R.id.rb_start_alarm) View.VISIBLE else View.GONE
|
||||
checkSetting(true)
|
||||
}
|
||||
binding!!.btInsertVibrationEffect1.setOnClickListener(this)
|
||||
binding!!.btInsertVibrationEffect2.setOnClickListener(this)
|
||||
binding!!.btInsertVibrationEffect3.setOnClickListener(this)
|
||||
binding!!.btInsertFlashEffect1.setOnClickListener(this)
|
||||
binding!!.btInsertFlashEffect2.setOnClickListener(this)
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.bt_insert_vibration_effect_1 -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etVibrationEffect, "=")
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_vibration_effect_2 -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etVibrationEffect, "-")
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_vibration_effect_3 -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etVibrationEffect, "_")
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_flash_effect_1 -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etFlashEffect, "X")
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_flash_effect_2 -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etFlashEffect, "O")
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_file_picker -> {
|
||||
// 申请储存权限
|
||||
@ -165,14 +222,23 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
val permissions = arrayListOf<String>()
|
||||
permissions.add(Permission.WRITE_SETTINGS)
|
||||
if (binding!!.sbEnableFlash.isChecked) {
|
||||
permissions.add(Permission.CAMERA)
|
||||
}
|
||||
// 申请修改系统设置权限
|
||||
XXPermissions.with(this).permission(Permission.WRITE_SETTINGS).request(object : OnPermissionCallback {
|
||||
XXPermissions.with(this).permission(permissions).request(object : OnPermissionCallback {
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||
mCountDownHelper?.start()
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo.playTimes < 0 && settingVo.repeatTimes < 0 && settingVo.flashTimes < 0) {
|
||||
XToastUtils.error(getString(R.string.alarm_settings_error))
|
||||
return
|
||||
}
|
||||
val taskAction = TaskSetting(TASK_ACTION_ALARM, getString(R.string.task_alarm), settingVo.description, Gson().toJson(settingVo), requestCode)
|
||||
val taskActionsJson = Gson().toJson(arrayListOf(taskAction))
|
||||
val msgInfo = MsgInfo("task", getString(R.string.task_alarm), settingVo.description, Date(), getString(R.string.task_alarm))
|
||||
@ -207,11 +273,20 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
}
|
||||
|
||||
R.id.btn_save -> {
|
||||
val permissions = arrayListOf<String>()
|
||||
permissions.add(Permission.WRITE_SETTINGS)
|
||||
if (binding!!.sbEnableFlash.isChecked) {
|
||||
permissions.add(Permission.CAMERA)
|
||||
}
|
||||
// 申请修改系统设置权限
|
||||
XXPermissions.with(this).permission(Permission.WRITE_SETTINGS).request(object : OnPermissionCallback {
|
||||
XXPermissions.with(this).permission(permissions).request(object : OnPermissionCallback {
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||
val settingVo = checkSetting()
|
||||
if (settingVo.playTimes < 0 && settingVo.repeatTimes < 0 && settingVo.flashTimes < 0) {
|
||||
XToastUtils.error(getString(R.string.alarm_settings_error))
|
||||
return
|
||||
}
|
||||
val intent = Intent()
|
||||
intent.putExtra(KEY_BACK_DESCRIPTION_ACTION, settingVo.description)
|
||||
intent.putExtra(KEY_BACK_DATA_ACTION, Gson().toJson(settingVo))
|
||||
@ -244,16 +319,42 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
@Suppress("SameParameterValue")
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun checkSetting(updateView: Boolean = false): AlarmSetting {
|
||||
val enableMusic = binding!!.sbEnableMusic.isChecked
|
||||
val enableVibrate = binding!!.sbEnableVibrate.isChecked
|
||||
val enableFlash = binding!!.sbEnableFlash.isChecked
|
||||
val volume = binding!!.xsbVolume.selectedNumber
|
||||
val loopTimes = binding!!.xsbLoopTimes.selectedNumber
|
||||
var playTimes = binding!!.xsbPlayTimes.selectedNumber
|
||||
val music = binding!!.etMusicPath.text.toString().trim()
|
||||
var repeatTimes = binding!!.xsbRepeatTimes.selectedNumber
|
||||
val vibrationEffect = binding!!.etVibrationEffect.text.toString().trim()
|
||||
var flashTimes = binding!!.xsbFlashTimes.selectedNumber
|
||||
var flashEffect = binding!!.etFlashEffect.text.toString().trim()
|
||||
val description = StringBuilder()
|
||||
val action = if (binding!!.rgAlarmState.checkedRadioButtonId == R.id.rb_start_alarm) {
|
||||
description.append(getString(R.string.start_alarm))
|
||||
description.append(", ").append(getString(R.string.alarm_volume)).append(":").append(volume).append("%")
|
||||
description.append(", ").append(getString(R.string.alarm_play_times)).append(":").append(loopTimes)
|
||||
if (music.isNotEmpty()) {
|
||||
description.append(", ").append(getString(R.string.alarm_music)).append(":").append(music)
|
||||
if (enableMusic) {
|
||||
description.append(", ").append(getString(R.string.alarm_volume)).append(":").append(volume).append("%")
|
||||
description.append(", ").append(getString(R.string.alarm_play_times)).append(":").append(playTimes)
|
||||
if (music.isNotEmpty()) {
|
||||
description.append(", ").append(getString(R.string.alarm_music)).append(":").append(music)
|
||||
}
|
||||
} else {
|
||||
playTimes = -1
|
||||
}
|
||||
if (enableVibrate) {
|
||||
vibrationEffect.ifEmpty { "---___===___".also { binding!!.etVibrationEffect.setText(it) } }
|
||||
description.append(", ").append(getString(R.string.alarm_vibration_effect)).append(":").append(vibrationEffect)
|
||||
description.append(", ").append(getString(R.string.alarm_repeat_times)).append(":").append(repeatTimes)
|
||||
} else {
|
||||
repeatTimes = -1
|
||||
}
|
||||
if (enableFlash) {
|
||||
flashEffect.ifEmpty { "XXOOXXOO".also { binding!!.etFlashEffect.setText(it) } }
|
||||
flashEffect = flashEffect.toUpperCase(Locale.ROOT).replace("1", "X").replace("0", "O")
|
||||
description.append(", ").append(getString(R.string.alarm_flash_effect)).append(":").append(flashEffect)
|
||||
description.append(", ").append(getString(R.string.alarm_repeat_times)).append(":").append(flashTimes)
|
||||
} else {
|
||||
flashTimes = -1
|
||||
}
|
||||
"start"
|
||||
} else {
|
||||
@ -265,7 +366,7 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
binding!!.tvDescription.text = description.toString()
|
||||
}
|
||||
|
||||
return AlarmSetting(description.toString(), action, volume, loopTimes, music)
|
||||
return AlarmSetting(description.toString(), action, volume, playTimes, music, repeatTimes, vibrationEffect, flashTimes, flashEffect)
|
||||
}
|
||||
|
||||
private fun findAudioFiles(directoryPath: String): List<String> {
|
||||
@ -286,4 +387,4 @@ class AlarmFragment : BaseFragment<FragmentTasksActionAlarmBinding?>(), View.OnC
|
||||
val supportedExtensions = listOf("mp3", "ogg", "wav")
|
||||
return supportedExtensions.any { it.equals(file.extension, ignoreCase = true) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.EditText
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -156,6 +155,9 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
||||
|
||||
//初始化发送通道下拉框
|
||||
initSenderSpinner()
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glSmsTemplate, binding!!.etSmsTemplate, ruleType)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -165,15 +167,6 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnSilentPeriod.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertContent.setOnClickListener(this)
|
||||
binding!!.btInsertSenderApp.setOnClickListener(this)
|
||||
binding!!.btInsertUid.setOnClickListener(this)
|
||||
binding!!.btInsertTitleApp.setOnClickListener(this)
|
||||
binding!!.btInsertContentApp.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -213,7 +206,6 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etSmsTemplate: EditText = binding!!.etSmsTemplate
|
||||
when (v.id) {
|
||||
R.id.btn_silent_period -> {
|
||||
OptionsPickerBuilder(context, OnOptionsSelectListener { _: View?, options1: Int, options2: Int, _: Int ->
|
||||
@ -229,51 +221,6 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
||||
}
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_sms))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender_app -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_package_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_uid -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_uid))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_title_app -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_title))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content_app -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_msg))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
try {
|
||||
@ -506,4 +453,4 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.App.Companion.BARK_ENCRYPTION_ALGORITHM_MAP
|
||||
@ -124,6 +123,10 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
}
|
||||
binding!!.spEncryptionAlgorithm.selectedIndex = 0
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glAutoCopyTemplate, binding!!.etAutoCopyTemplate)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -156,6 +159,7 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
binding!!.etServer.setText(settingVo.server)
|
||||
binding!!.etGroup.setText(settingVo.group)
|
||||
binding!!.etIcon.setText(settingVo.icon)
|
||||
binding!!.sbCall.isChecked = settingVo.call == "1"
|
||||
binding!!.etSound.setText(settingVo.sound)
|
||||
binding!!.etBadge.setText(settingVo.badge)
|
||||
binding!!.etUrl.setText(settingVo.url)
|
||||
@ -178,10 +182,6 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -191,27 +191,7 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -281,6 +261,7 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
if (!CommonUtils.checkUrl(icon, true)) {
|
||||
throw Exception(getString(R.string.invalid_bark_icon))
|
||||
}
|
||||
val call = if (binding!!.sbCall.isChecked) "1" else "0"
|
||||
val sound = binding!!.etSound.text.toString().trim()
|
||||
val badge = binding!!.etBadge.text.toString().trim()
|
||||
val url = binding!!.etUrl.text.toString().trim()
|
||||
@ -288,6 +269,7 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
throw Exception(getString(R.string.invalid_bark_url))
|
||||
}
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
val autoCopy = binding!!.etAutoCopyTemplate.text.toString().trim()
|
||||
val key = binding!!.etEncryptionKey.text.toString().trim()
|
||||
val iv = binding!!.etEncryptionIv.text.toString().trim()
|
||||
if (transformation.startsWith("AES128") && key.length != 16) {
|
||||
@ -301,7 +283,7 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
throw Exception(getString(R.string.bark_encryption_key_error4))
|
||||
}
|
||||
|
||||
return BarkSetting(server, group, icon, sound, badge, url, barkLevel, title, transformation, key, iv)
|
||||
return BarkSetting(server, group, icon, sound, badge, url, barkLevel, title, transformation, key, iv, call, autoCopy)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -309,4 +291,4 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
@ -96,6 +95,9 @@ class DingtalkGroupRobotFragment : BaseFragment<FragmentSendersDingtalkGroupRobo
|
||||
}
|
||||
})
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -138,10 +140,6 @@ class DingtalkGroupRobotFragment : BaseFragment<FragmentSendersDingtalkGroupRobo
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -168,27 +166,7 @@ class DingtalkGroupRobotFragment : BaseFragment<FragmentSendersDingtalkGroupRobo
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -269,4 +247,4 @@ class DingtalkGroupRobotFragment : BaseFragment<FragmentSendersDingtalkGroupRobo
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
@ -19,7 +18,15 @@ import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersDingtalkInnerRobotBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.CommonUtils
|
||||
import com.idormy.sms.forwarder.utils.EVENT_TOAST_ERROR
|
||||
import com.idormy.sms.forwarder.utils.KEY_SENDER_CLONE
|
||||
import com.idormy.sms.forwarder.utils.KEY_SENDER_ID
|
||||
import com.idormy.sms.forwarder.utils.KEY_SENDER_TEST
|
||||
import com.idormy.sms.forwarder.utils.KEY_SENDER_TYPE
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.idormy.sms.forwarder.utils.sender.DingtalkInnerRobotUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
@ -35,7 +42,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.net.Proxy
|
||||
import java.util.*
|
||||
import java.util.Date
|
||||
|
||||
@Page(name = "钉钉企业机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
@ -90,6 +97,9 @@ class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobo
|
||||
}
|
||||
})
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -137,10 +147,6 @@ class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobo
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -176,27 +182,7 @@ class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobo
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -295,4 +281,4 @@ class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobo
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -166,6 +166,10 @@ class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClick
|
||||
}
|
||||
}
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glNickname, binding!!.etNickname)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -237,14 +241,6 @@ class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClick
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSenderToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertExtraToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertTimeToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceNameToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -260,48 +256,7 @@ class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClick
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etNickname: EditText = binding!!.etNickname
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -653,4 +608,4 @@ class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClick
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
@ -105,6 +104,10 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
|
||||
}
|
||||
}
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glMessageCard, binding!!.etMessageCard)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -150,15 +153,6 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSenderToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertExtraToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertTimeToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceNameToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertContent.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -168,53 +162,7 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
val etMessageCard: EditText = binding!!.etMessageCard
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_sms))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -315,4 +263,4 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
@ -105,6 +104,10 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
|
||||
}
|
||||
}
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glMessageCard, binding!!.etMessageCard)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -145,15 +148,6 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSenderToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertExtraToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertTimeToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceNameToTitle.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertContent.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -163,53 +157,7 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
val etMessageCard: EditText = binding!!.etMessageCard
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name_to_title -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_content -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_sms))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -295,4 +243,4 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
@ -94,6 +93,9 @@ class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnCli
|
||||
}
|
||||
})
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -132,10 +134,6 @@ class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnCli
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -145,27 +143,7 @@ class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnCli
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -242,4 +220,4 @@ class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnCli
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
@ -95,6 +94,9 @@ class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.O
|
||||
}
|
||||
})
|
||||
|
||||
//创建标签按钮
|
||||
CommonUtils.createTagButtons(requireContext(), binding!!.glTitleTemplate, binding!!.etTitleTemplate)
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
@ -143,10 +145,6 @@ class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.O
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
@ -165,27 +163,7 @@ class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.O
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
@ -272,4 +250,4 @@ class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.O
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -226,4 +226,4 @@ class ServerchanFragment : BaseFragment<FragmentSendersServerchanBinding?>(), Vi
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -251,4 +251,4 @@ class SmsFragment : BaseFragment<FragmentSendersSmsBinding?>(), View.OnClickList
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -262,4 +262,4 @@ class SocketFragment : BaseFragment<FragmentSendersSocketBinding?>(), View.OnCli
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +133,7 @@ class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.O
|
||||
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
|
||||
binding!!.etProxyUsername.setText(settingVo.proxyUsername)
|
||||
binding!!.etProxyPassword.setText(settingVo.proxyPassword)
|
||||
binding!!.rgParseMode.check(settingVo.getParseModeCheckId())
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -251,8 +252,13 @@ class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.O
|
||||
}
|
||||
|
||||
val method = if (binding!!.rgMethod.checkedRadioButtonId == R.id.rb_method_get) "GET" else "POST"
|
||||
val parseMode = when (binding!!.rgParseMode.checkedRadioButtonId) {
|
||||
R.id.rb_parse_mode_text -> "TEXT"
|
||||
R.id.rb_parse_mode_markdown -> "MarkdownV2"
|
||||
else -> "HTML"
|
||||
}
|
||||
|
||||
return TelegramSetting(method, apiToken, chatId, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
|
||||
return TelegramSetting(method, apiToken, chatId, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword, parseMode)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -260,4 +266,4 @@ class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.O
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -223,4 +223,4 @@ class UrlSchemeFragment : BaseFragment<FragmentSendersUrlSchemeBinding?>(), View
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -336,4 +336,4 @@ class WebhookFragment : BaseFragment<FragmentSendersWebhookBinding?>(), View.OnC
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -307,4 +307,4 @@ class WeworkAgentFragment : BaseFragment<FragmentSendersWeworkAgentBinding?>(),
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -238,4 +238,4 @@ class WeworkRobotFragment : BaseFragment<FragmentSendersWeworkRobotBinding?>(),
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -36,10 +36,12 @@ import com.idormy.sms.forwarder.utils.EXTRA_UPDATE_NOTIFICATION
|
||||
import com.idormy.sms.forwarder.utils.FRONT_CHANNEL_ID
|
||||
import com.idormy.sms.forwarder.utils.FRONT_CHANNEL_NAME
|
||||
import com.idormy.sms.forwarder.utils.FRONT_NOTIFY_ID
|
||||
import com.idormy.sms.forwarder.utils.FlashUtils
|
||||
import com.idormy.sms.forwarder.utils.INTENT_FRPC_APPLY_FILE
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
|
||||
import com.idormy.sms.forwarder.utils.VibrationUtils
|
||||
import com.idormy.sms.forwarder.utils.task.CronJobScheduler
|
||||
import com.idormy.sms.forwarder.workers.LoadAppListWorker
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
@ -92,77 +94,108 @@ class ForegroundService : Service() {
|
||||
})
|
||||
}
|
||||
|
||||
// 振动控制
|
||||
private lateinit var vibrationUtils: VibrationUtils
|
||||
private var isVibrating = false
|
||||
|
||||
// 闪光灯控制
|
||||
private lateinit var flashUtils: FlashUtils
|
||||
private var isFlash = false
|
||||
|
||||
// 音乐播放器
|
||||
private var alarmPlayer: MediaPlayer? = null
|
||||
private var alarmPlayTimes = 0
|
||||
private val alarmObserver = Observer<AlarmSetting> { alarm ->
|
||||
Log.d(TAG, "Received alarm: $alarm")
|
||||
//停止振动
|
||||
if (vibrationUtils.isVibrating) {
|
||||
vibrationUtils.stopVibration()
|
||||
}
|
||||
//停止闪光灯
|
||||
if (flashUtils.isFlashing) {
|
||||
flashUtils.stopFlashing()
|
||||
}
|
||||
//停止播放音乐
|
||||
alarmPlayer?.release()
|
||||
alarmPlayer = null
|
||||
if (alarm.action == "start") {
|
||||
//获取音量
|
||||
val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
||||
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
Log.d(TAG, "maxVolume=$maxVolume, currentVolume=$currentVolume")
|
||||
//设置音量
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (maxVolume * alarm.volume / 100), 0)
|
||||
//播放音乐
|
||||
alarmPlayer = MediaPlayer().apply {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val audioAttributes = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build()
|
||||
setAudioAttributes(audioAttributes)
|
||||
} else {
|
||||
// 对于 Android 5.0 之前的版本,使用 setAudioStreamType
|
||||
val audioStreamType = AudioManager.STREAM_ALARM
|
||||
setAudioStreamType(audioStreamType)
|
||||
}
|
||||
|
||||
try {
|
||||
if (alarm.music.isEmpty() || !File(alarm.music).exists()) {
|
||||
val fd = resources.openRawResourceFd(R.raw.alarm)
|
||||
setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)
|
||||
if (alarm.playTimes >= 0) {
|
||||
//获取音量
|
||||
val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
||||
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
Log.d(TAG, "maxVolume=$maxVolume, currentVolume=$currentVolume")
|
||||
//设置音量
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (maxVolume * alarm.volume / 100), 0)
|
||||
//播放音乐
|
||||
alarmPlayer = MediaPlayer().apply {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val audioAttributes = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build()
|
||||
setAudioAttributes(audioAttributes)
|
||||
} else {
|
||||
setDataSource(alarm.music)
|
||||
// 对于 Android 5.0 之前的版本,使用 setAudioStreamType
|
||||
val audioStreamType = AudioManager.STREAM_ALARM
|
||||
setAudioStreamType(audioStreamType)
|
||||
}
|
||||
|
||||
setOnPreparedListener {
|
||||
Log.d(TAG, "MediaPlayer prepared")
|
||||
start()
|
||||
alarmPlayTimes++
|
||||
//更新通知栏
|
||||
updateNotification(alarm.description, R.drawable.auto_task_icon_alarm, true)
|
||||
}
|
||||
try {
|
||||
if (alarm.music.isEmpty() || !File(alarm.music).exists()) {
|
||||
val fd = resources.openRawResourceFd(R.raw.alarm)
|
||||
setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)
|
||||
} else {
|
||||
setDataSource(alarm.music)
|
||||
}
|
||||
|
||||
setOnCompletionListener {
|
||||
Log.d(TAG, "MediaPlayer completed")
|
||||
if (alarm.playTimes == 0 || alarmPlayTimes < alarm.playTimes) {
|
||||
setOnPreparedListener {
|
||||
Log.d(TAG, "MediaPlayer prepared")
|
||||
start()
|
||||
alarmPlayTimes++
|
||||
} else {
|
||||
stop()
|
||||
reset()
|
||||
release()
|
||||
alarmPlayer = null
|
||||
alarmPlayTimes = 0
|
||||
//恢复音量
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0)
|
||||
//恢复通知栏
|
||||
updateNotification(SettingUtils.notifyContent)
|
||||
//更新通知栏
|
||||
updateNotification(alarm.description, R.drawable.auto_task_icon_alarm, true)
|
||||
}
|
||||
}
|
||||
|
||||
setOnErrorListener { _, what, extra ->
|
||||
Log.e(TAG, "MediaPlayer error: what=$what, extra=$extra")
|
||||
release()
|
||||
return@setOnErrorListener true
|
||||
}
|
||||
setOnCompletionListener {
|
||||
Log.d(TAG, "MediaPlayer completed")
|
||||
if (alarm.playTimes == 0 || alarmPlayTimes < alarm.playTimes) {
|
||||
start()
|
||||
alarmPlayTimes++
|
||||
} else {
|
||||
stop()
|
||||
reset()
|
||||
release()
|
||||
alarmPlayer = null
|
||||
alarmPlayTimes = 0
|
||||
//恢复音量
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0)
|
||||
//恢复通知栏
|
||||
updateNotification(SettingUtils.notifyContent)
|
||||
}
|
||||
}
|
||||
|
||||
setVolume(alarm.volume / 100F, alarm.volume / 100F)
|
||||
prepareAsync()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "MediaPlayer Exception: ${e.message}")
|
||||
setOnErrorListener { _, what, extra ->
|
||||
Log.e(TAG, "MediaPlayer error: what=$what, extra=$extra")
|
||||
release()
|
||||
return@setOnErrorListener true
|
||||
}
|
||||
|
||||
setVolume(alarm.volume / 100F, alarm.volume / 100F)
|
||||
prepareAsync()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "MediaPlayer Exception: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
//振动提醒
|
||||
if (alarm.repeatTimes >= 0) {
|
||||
isVibrating = true
|
||||
vibrationUtils.startVibration(alarm.vibrate, alarm.repeatTimes)
|
||||
}
|
||||
//闪光灯提醒
|
||||
if (alarm.flashTimes >= 0) {
|
||||
isFlash = true
|
||||
flashUtils.startFlashing(alarm.flash, alarm.flashTimes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +209,14 @@ class ForegroundService : Service() {
|
||||
//纯客户端模式
|
||||
if (SettingUtils.enablePureClientMode) return
|
||||
|
||||
//创建通知渠道
|
||||
createNotificationChannel()
|
||||
|
||||
//初始化振动
|
||||
vibrationUtils = VibrationUtils(this)
|
||||
|
||||
//初始化闪光灯
|
||||
flashUtils = FlashUtils(this)
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
@ -212,7 +252,7 @@ class ForegroundService : Service() {
|
||||
override fun onDestroy() {
|
||||
//非纯客户端模式
|
||||
if (!SettingUtils.enablePureClientMode) stopForegroundService()
|
||||
|
||||
flashUtils.release()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@ -292,6 +332,14 @@ class ForegroundService : Service() {
|
||||
isRunning = false
|
||||
alarmPlayer?.release()
|
||||
alarmPlayer = null
|
||||
//停止振动
|
||||
if (vibrationUtils.isVibrating) {
|
||||
vibrationUtils.stopVibration()
|
||||
}
|
||||
//停止闪光灯
|
||||
if (flashUtils.isFlashing) {
|
||||
flashUtils.stopFlashing()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
handleException(e, "stopForegroundService")
|
||||
}
|
||||
@ -354,4 +402,4 @@ class ForegroundService : Service() {
|
||||
isRunning = false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,18 +6,29 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.TextUtils
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.GridLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.idormy.sms.forwarder.App
|
||||
import com.idormy.sms.forwarder.App.Companion.APP_TAG_MAP
|
||||
import com.idormy.sms.forwarder.App.Companion.BATTERY_TAG_MAP
|
||||
import com.idormy.sms.forwarder.App.Companion.CALL_TAG_MAP
|
||||
import com.idormy.sms.forwarder.App.Companion.COMMON_TAG_MAP
|
||||
import com.idormy.sms.forwarder.App.Companion.LOCATION_TAG_MAP
|
||||
import com.idormy.sms.forwarder.App.Companion.NETWORK_TAG_MAP
|
||||
import com.idormy.sms.forwarder.App.Companion.SMS_TAG_MAP
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.webview.AgentWebActivity
|
||||
import com.idormy.sms.forwarder.core.webview.AgentWebFragment
|
||||
@ -35,6 +46,8 @@ import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog.SingleButton
|
||||
import com.xuexiang.xui.widget.imageview.preview.PreviewBuilder
|
||||
import com.xuexiang.xutil.XUtil
|
||||
import com.xuexiang.xutil.common.StringUtils
|
||||
import com.xuexiang.xutil.resource.ResUtils.getColor
|
||||
import com.xuexiang.xutil.resource.ResUtils.getDrawable
|
||||
import com.xuexiang.xutil.resource.ResUtils.getString
|
||||
import java.net.Inet4Address
|
||||
import java.net.Inet6Address
|
||||
@ -338,41 +351,76 @@ class CommonUtils private constructor() {
|
||||
XUtil.exitApp()
|
||||
}
|
||||
|
||||
/*fun switchLanguage(oldLocale: Locale, newLocale: Locale) {
|
||||
val oldLang = if (TAG_LANG.contains(oldLocale.toString())) oldLocale.toString() else "en"
|
||||
val newLang = if (TAG_LANG.contains(newLocale.toString())) newLocale.toString() else "en"
|
||||
Log.i(App.TAG, "switchLanguage: oldLang=$oldLang, newLang=$newLang")
|
||||
// 动态创建标签按钮并设置点击事件(将标签插入指定输入框)
|
||||
fun createTagButtons(context: Context, gridLayout: GridLayout, editText: EditText, scene: String = "basic", excludeButtons: Array<String> = emptyArray()) {
|
||||
// 将排除的按钮转换成一个集合,方便查找
|
||||
val excludeSet = excludeButtons.toSet()
|
||||
|
||||
//替换自定义模板标签
|
||||
var smsTemplate = SettingUtils.smsTemplate
|
||||
//替换Rule.sms_template中的标签
|
||||
var ruleColumn = "sms_template"
|
||||
//替换Sender.json_setting中的标签
|
||||
var senderColumn = "json_setting"
|
||||
// 清空GridLayout中的所有视图
|
||||
gridLayout.removeAllViews()
|
||||
|
||||
for (i in TAG_LIST.indices) {
|
||||
val oldTag = TAG_LIST[i][oldLang].toString()
|
||||
val newTag = TAG_LIST[i][newLang].toString()
|
||||
if (oldTag == newTag) continue
|
||||
// 根据场景动态拼接所有按钮数据
|
||||
val allButtons = when (scene) {
|
||||
"sms" -> SMS_TAG_MAP
|
||||
"call" -> CALL_TAG_MAP
|
||||
"app" -> APP_TAG_MAP
|
||||
else -> CALL_TAG_MAP + SMS_TAG_MAP + APP_TAG_MAP
|
||||
}.toMutableMap()
|
||||
|
||||
smsTemplate = smsTemplate.replace(oldTag, newTag)
|
||||
ruleColumn = "REPLACE($ruleColumn, '$oldTag', '$newTag')"
|
||||
senderColumn = "REPLACE($senderColumn, '$oldTag', '$newTag')"
|
||||
if (SettingUtils.enableLocation) {
|
||||
allButtons += LOCATION_TAG_MAP
|
||||
}
|
||||
if (scene == "all") {
|
||||
allButtons += BATTERY_TAG_MAP
|
||||
allButtons += NETWORK_TAG_MAP
|
||||
}
|
||||
allButtons += COMMON_TAG_MAP
|
||||
|
||||
val btnBackground = getDrawable(R.drawable.rounded_button)
|
||||
val btnTextColor = getColor(android.R.color.white)
|
||||
|
||||
// 遍历所有按钮数据,过滤掉需要排除的按钮
|
||||
allButtons.forEach { (tag, lable) ->
|
||||
if (excludeSet.isNotEmpty() && excludeSet.contains(tag)) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val button = TextView(context).apply {
|
||||
text = lable
|
||||
setOnClickListener {
|
||||
insertOrReplaceText2Cursor(editText, tag)
|
||||
}
|
||||
|
||||
// 设置紧凑样式
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_SP, 9f)
|
||||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
setPadding(5, 5, 5, 5)
|
||||
gravity = android.view.Gravity.CENTER
|
||||
background = btnBackground
|
||||
setTextColor(btnTextColor)
|
||||
|
||||
// 布局参数
|
||||
layoutParams = GridLayout.LayoutParams().apply {
|
||||
height = GridLayout.LayoutParams.WRAP_CONTENT
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
width = 0
|
||||
columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f)
|
||||
} else {
|
||||
width = GridLayout.LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
setMargins(8, 8, 8, 8)
|
||||
}
|
||||
}
|
||||
|
||||
gridLayout.addView(button)
|
||||
}
|
||||
|
||||
SettingUtils.smsTemplate = smsTemplate
|
||||
}
|
||||
|
||||
val updateRuleSql = "UPDATE Rule SET sms_template = $ruleColumn WHERE sms_template != ''"
|
||||
Log.d(App.TAG, "updateRuleSql: $updateRuleSql")
|
||||
Core.rule.replaceTags(updateRuleSql)
|
||||
|
||||
val updateSenderSql = "UPDATE Sender SET json_setting = $senderColumn WHERE type NOT IN (4, 5, 6, 7, 8, 14)"
|
||||
Log.d(App.TAG, "updateSenderSql: $updateSenderSql")
|
||||
Core.sender.replaceTags(updateSenderSql)
|
||||
}*/
|
||||
}
|
||||
|
||||
init {
|
||||
throw UnsupportedOperationException("u can't instantiate me...")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
116
app/src/main/java/com/idormy/sms/forwarder/utils/FlashUtils.kt
Normal file
116
app/src/main/java/com/idormy/sms/forwarder/utils/FlashUtils.kt
Normal file
@ -0,0 +1,116 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package com.idormy.sms.forwarder.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.Camera
|
||||
import android.hardware.camera2.CameraAccessException
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
||||
class FlashUtils(context: Context) {
|
||||
private var cameraManager: CameraManager? = null
|
||||
private var cameraId: String? = null
|
||||
private var legacyCamera: Camera? = null
|
||||
private var legacyParams: Camera.Parameters? = null
|
||||
private var handler: Handler? = null
|
||||
private val duration = 100L // 闪烁持续时间
|
||||
var isFlashing = false
|
||||
private set
|
||||
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
try {
|
||||
cameraId = cameraManager?.cameraIdList?.get(0) // 获取后置摄像头 ID
|
||||
} catch (e: CameraAccessException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
legacyCamera = Camera.open()
|
||||
legacyParams = legacyCamera?.parameters
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照模式控制闪光灯
|
||||
* @param pattern 例如 "XXOOXXOO" (X-开,O-关)
|
||||
* @param repeatTimes 闪烁的重复次数,0 表示无限循环
|
||||
*/
|
||||
fun startFlashing(pattern: String, repeatTimes: Int) {
|
||||
if (isFlashing) return
|
||||
isFlashing = true
|
||||
handler = Handler(Looper.getMainLooper())
|
||||
|
||||
val sequence = pattern.toCharArray()
|
||||
var index = 0
|
||||
var repeatCount = 0
|
||||
|
||||
val runnable = object : Runnable {
|
||||
override fun run() {
|
||||
if (!isFlashing) return
|
||||
|
||||
val shouldFlash = sequence[index] == 'X' || sequence[index] == '1'
|
||||
setFlashlight(shouldFlash)
|
||||
index++
|
||||
|
||||
if (index >= sequence.size) {
|
||||
index = 0
|
||||
repeatCount++
|
||||
if (repeatTimes != 0 && repeatCount >= repeatTimes) {
|
||||
stopFlashing()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
handler?.postDelayed(this, duration)
|
||||
}
|
||||
}
|
||||
|
||||
handler?.post(runnable)
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭闪光灯并停止模式
|
||||
*/
|
||||
fun stopFlashing() {
|
||||
isFlashing = false
|
||||
handler?.removeCallbacksAndMessages(null)
|
||||
setFlashlight(false) // 确保停止后灯是关闭的
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置闪光灯状态,兼容 Android 4.4+
|
||||
*/
|
||||
private fun setFlashlight(enable: Boolean) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
cameraManager?.setTorchMode(cameraId!!, enable)
|
||||
} else {
|
||||
legacyParams?.flashMode = if (enable) Camera.Parameters.FLASH_MODE_TORCH else Camera.Parameters.FLASH_MODE_OFF
|
||||
legacyCamera?.parameters = legacyParams
|
||||
if (enable) legacyCamera?.startPreview() else legacyCamera?.stopPreview()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放旧 API 资源
|
||||
*/
|
||||
fun release() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
legacyCamera?.stopPreview()
|
||||
legacyCamera?.release()
|
||||
legacyCamera = null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -14,6 +14,7 @@ import android.provider.Settings
|
||||
import android.telephony.SmsManager
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import android.text.TextUtils
|
||||
import androidx.annotation.RequiresPermission
|
||||
import androidx.core.app.ActivityCompat
|
||||
@ -28,8 +29,16 @@ import com.xuexiang.xutil.XUtil
|
||||
import com.xuexiang.xutil.app.IntentUtils
|
||||
import com.xuexiang.xutil.data.DateUtils
|
||||
import com.xuexiang.xutil.resource.ResUtils.getString
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.json.JSONObject
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import kotlin.math.min
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class PhoneUtils private constructor() {
|
||||
@ -37,6 +46,14 @@ class PhoneUtils private constructor() {
|
||||
companion object {
|
||||
const val TAG = "PhoneUtils"
|
||||
|
||||
/** 获取 sim 卡槽数量,注意不是 sim 卡的数量。*/
|
||||
fun getSimSlotCount() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
||||
(App.context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).activeModemCount
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
(App.context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).phoneCount
|
||||
else
|
||||
-1
|
||||
|
||||
//获取多卡信息
|
||||
@SuppressLint("Range")
|
||||
fun getSimMultiInfo(): MutableMap<Int, SimInfo> {
|
||||
@ -330,7 +347,7 @@ class PhoneUtils private constructor() {
|
||||
|
||||
//获取联系人列表
|
||||
fun getContactInfoList(
|
||||
limit: Int, offset: Int, phoneNumber: String?, name: String?
|
||||
limit: Int, offset: Int, phoneNumber: String?, name: String?, isFuzzy: Boolean = true
|
||||
): MutableList<ContactInfo> {
|
||||
val contactInfoList: MutableList<ContactInfo> = mutableListOf()
|
||||
|
||||
@ -339,7 +356,11 @@ class PhoneUtils private constructor() {
|
||||
val selectionArgs = ArrayList<String>()
|
||||
if (!TextUtils.isEmpty(phoneNumber)) {
|
||||
selection += " and replace(replace(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ",' ',''),'-','') like ?"
|
||||
selectionArgs.add("%$phoneNumber%")
|
||||
if (isFuzzy) {
|
||||
selectionArgs.add("%$phoneNumber%")
|
||||
} else {
|
||||
selectionArgs.add("%$phoneNumber")
|
||||
}
|
||||
}
|
||||
if (!TextUtils.isEmpty(name)) {
|
||||
selection += " and " + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " like ?"
|
||||
@ -383,11 +404,100 @@ class PhoneUtils private constructor() {
|
||||
return contactInfoList
|
||||
}
|
||||
|
||||
// 获取号码归属地
|
||||
fun getPhoneArea(phoneNumber: String): String {
|
||||
val client = OkHttpClient()
|
||||
val url = "https://cx.shouji.360.cn/phonearea.php?number=$phoneNumber"
|
||||
val request = Request.Builder().url(url).build()
|
||||
|
||||
var result = getString(R.string.unknown_area) // 默认值
|
||||
|
||||
// 使用协程来执行网络请求
|
||||
runBlocking {
|
||||
val job = CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val response = client.newCall(request).execute()
|
||||
if (response.isSuccessful) {
|
||||
val responseData = response.body()?.string()
|
||||
Log.i(TAG, "getPhoneArea: $responseData")
|
||||
if (responseData != null) {
|
||||
val jsonObject = JSONObject(responseData)
|
||||
val data = jsonObject.getJSONObject("data")
|
||||
val province = data.getString("province")
|
||||
val city = data.getString("city")
|
||||
val sp = data.getString("sp")
|
||||
result = "$province $city $sp"
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
job.join() // 等待协程执行完毕
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
//获取联系人姓名
|
||||
fun getContactByNumber(phoneNumber: String?): MutableList<ContactInfo> {
|
||||
val contactInfoList = mutableListOf<ContactInfo>()
|
||||
if (TextUtils.isEmpty(phoneNumber)) return contactInfoList
|
||||
return getContactInfoList(1, 0, phoneNumber, null)
|
||||
|
||||
// 去除国际区号、空格、括号、横线等字符
|
||||
val normalizedInputNumber = if (phoneNumber!!.startsWith("+") && phoneNumber.length > 4) {
|
||||
phoneNumber.substring(4).replace("[^0-9]".toRegex(), "")
|
||||
} else {
|
||||
phoneNumber.replace("[^0-9]".toRegex(), "")
|
||||
}
|
||||
|
||||
contactInfoList.addAll(getContactInfoList(99, 0, normalizedInputNumber, null, false))
|
||||
if (contactInfoList.isEmpty() || contactInfoList.size == 1) {
|
||||
return contactInfoList
|
||||
}
|
||||
|
||||
// 计算每个联系人的匹配长度和优先级
|
||||
val scoredContacts = contactInfoList.map { contact ->
|
||||
//去除空格、括号、横线等字符
|
||||
val normalizedContactNumber = contact.phoneNumber.replace("[^0-9]".toRegex(), "")
|
||||
val matchLength = calculateMatchLength(normalizedInputNumber, normalizedContactNumber)
|
||||
// 优先级规则:
|
||||
// 1. 完全匹配(输入手机号与联系人手机号完全一致):优先级 2
|
||||
// 2. 匹配长度等于输入手机号长度:优先级 1
|
||||
// 3. 其他情况:优先级 0
|
||||
val priority = when {
|
||||
normalizedInputNumber == normalizedContactNumber -> 2
|
||||
matchLength == normalizedInputNumber.length -> 1
|
||||
else -> 0
|
||||
}
|
||||
contact to Pair(matchLength, priority)
|
||||
}.sortedWith(compareByDescending<Pair<ContactInfo, Pair<Int, Int>>> { it.second.first } // 按匹配长度降序
|
||||
.thenByDescending { it.second.second }) // 按优先级降序
|
||||
|
||||
// 返回匹配长度最长且优先级最高的联系人列表
|
||||
val maxMatchLength = scoredContacts.first().second.first
|
||||
val maxPriority = scoredContacts.first().second.second
|
||||
return scoredContacts
|
||||
.filter { it.second.first == maxMatchLength && it.second.second == maxPriority }
|
||||
.map { it.first }
|
||||
.toMutableList()
|
||||
}
|
||||
|
||||
// 计算从右向左的匹配长度
|
||||
private fun calculateMatchLength(number1: String, number2: String): Int {
|
||||
var matchLength = 0
|
||||
val minLength = min(number1.length, number2.length)
|
||||
|
||||
// 从右向左逐位比较
|
||||
for (i in 1..minLength) {
|
||||
if (number1[number1.length - i] == number2[number2.length - i]) {
|
||||
matchLength++
|
||||
} else {
|
||||
break // 遇到不匹配的字符,停止比较
|
||||
}
|
||||
}
|
||||
|
||||
return matchLength
|
||||
}
|
||||
|
||||
//获取通话记录转发内容
|
||||
@ -581,4 +691,4 @@ class PhoneUtils private constructor() {
|
||||
init {
|
||||
throw UnsupportedOperationException("u can't instantiate me...")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import com.idormy.sms.forwarder.workers.UpdateLogsWorker
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xutil.XUtil
|
||||
import com.xuexiang.xutil.resource.ResUtils.getString
|
||||
import java.util.Calendar
|
||||
|
||||
object SendUtils {
|
||||
private const val TAG = "SendUtils"
|
||||
@ -97,6 +98,19 @@ object SendUtils {
|
||||
senderLogic(0, msgInfo, rule, senderIndex, msgId)
|
||||
return
|
||||
}
|
||||
//免打扰(禁用转发)日期段
|
||||
Log.d(TAG, "silentDayOfWeek = ${rule.silentDayOfWeek}")
|
||||
val silentDayOfWeek = rule.silentDayOfWeek.split(",").filter { it.isNotEmpty() }.map { it.toInt() }
|
||||
if (silentDayOfWeek.isNotEmpty()) {
|
||||
val dayOfWeek = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
|
||||
if (silentDayOfWeek.contains(dayOfWeek)) {
|
||||
Log.d(TAG, "免打扰(禁用转发)日期段")
|
||||
updateLogs(logId, 0, getString(R.string.silent_time_period))
|
||||
senderLogic(0, msgInfo, rule, senderIndex, msgId)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//免打扰(禁用转发)时间段
|
||||
Log.d(TAG, "silentPeriodStart = ${rule.silentPeriodStart}, silentPeriodEnd = ${rule.silentPeriodEnd}")
|
||||
if (rule.silentPeriodStart != rule.silentPeriodEnd) {
|
||||
|
@ -80,7 +80,7 @@ class SettingUtils private constructor() {
|
||||
//是否不在最近任务列表中显示
|
||||
var enableExcludeFromRecents: Boolean by SharedPreference(SP_ENABLE_EXCLUDE_FROM_RECENTS, false)
|
||||
|
||||
//是否转发应用通知
|
||||
//是否启用Cactus增强保活措施
|
||||
var enableCactus: Boolean by SharedPreference(SP_ENABLE_CACTUS, false)
|
||||
|
||||
//是否播放静音音乐
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.idormy.sms.forwarder.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class VibrationUtils(context: Context) {
|
||||
|
||||
private val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private var currentRepeat = 0
|
||||
var isVibrating = false
|
||||
private set
|
||||
|
||||
fun startVibration(patternString: String, repeatTimes: Int) {
|
||||
isVibrating = true
|
||||
currentRepeat = 0
|
||||
val parsedPattern = parsePattern(patternString)
|
||||
vibratePattern(parsedPattern, 0, repeatTimes)
|
||||
}
|
||||
|
||||
fun stopVibration() {
|
||||
isVibrating = false
|
||||
vibrator.cancel()
|
||||
}
|
||||
|
||||
private fun parsePattern(pattern: String): List<Triple<Long, Boolean, Int>> {
|
||||
val parsedPattern = mutableListOf<Triple<Long, Boolean, Int>>()
|
||||
var currentChar = pattern[0]
|
||||
var currentLength = 1L
|
||||
|
||||
for (i in 1 until pattern.length) {
|
||||
if (pattern[i] == currentChar) {
|
||||
currentLength++
|
||||
} else {
|
||||
parsedPattern.add(createTriple(currentChar, currentLength))
|
||||
currentChar = pattern[i]
|
||||
currentLength = 1L
|
||||
}
|
||||
}
|
||||
parsedPattern.add(createTriple(currentChar, currentLength))
|
||||
return parsedPattern
|
||||
}
|
||||
|
||||
private fun createTriple(char: Char, length: Long): Triple<Long, Boolean, Int> {
|
||||
val duration = 100L * length
|
||||
val intensity = when (char) {
|
||||
'=' -> 255
|
||||
'-' -> 128
|
||||
'_' -> 0
|
||||
else -> 0
|
||||
}
|
||||
return Triple(duration, intensity > 0, intensity)
|
||||
}
|
||||
|
||||
private fun vibratePattern(parsedPattern: List<Triple<Long, Boolean, Int>>, index: Int, repeatTimes: Int) {
|
||||
if (isVibrating && index < parsedPattern.size) {
|
||||
val (duration, shouldVibrate, intensity) = parsedPattern[index]
|
||||
if (shouldVibrate) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val effect = VibrationEffect.createOneShot(duration, intensity)
|
||||
vibrator.vibrate(effect)
|
||||
} else {
|
||||
vibrator.vibrate(duration)
|
||||
}
|
||||
}
|
||||
handler.postDelayed({
|
||||
if (isVibrating) {
|
||||
vibrator.cancel()
|
||||
if (index + 1 < parsedPattern.size) {
|
||||
vibratePattern(parsedPattern, index + 1, repeatTimes)
|
||||
} else {
|
||||
currentRepeat++
|
||||
if (repeatTimes == 0 || currentRepeat < repeatTimes) {
|
||||
vibratePattern(parsedPattern, 0, repeatTimes) // Restart pattern
|
||||
} else {
|
||||
stopVibration()
|
||||
}
|
||||
}
|
||||
}
|
||||
}, duration)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,14 +3,16 @@ package com.idormy.sms.forwarder.utils.mail
|
||||
import android.text.Html
|
||||
import android.text.Spanned
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.sun.mail.util.MailSSLSocketFactory
|
||||
import jakarta.mail.Authenticator
|
||||
import jakarta.mail.PasswordAuthentication
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||
import java.io.File
|
||||
import java.security.PrivateKey
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.Properties
|
||||
import javax.mail.Authenticator
|
||||
import javax.mail.PasswordAuthentication
|
||||
|
||||
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
class EmailSender(
|
||||
@ -32,7 +34,6 @@ class EmailSender(
|
||||
private val listener: EmailTaskListener? = null,
|
||||
// 安全选项
|
||||
private val openSSL: Boolean = false, //是否开启ssl验证 默认关闭
|
||||
private val sslFactory: String = "javax.net.ssl.SSLSocketFactory", //SSL构建类名
|
||||
private val startTls: Boolean = false, //是否开启starttls加密方式 默认关闭
|
||||
// 邮件加密方式: S/MIME、OpenPGP、Plain(不传证书)
|
||||
private val encryptionProtocol: String = "S/MIME",
|
||||
@ -58,7 +59,11 @@ class EmailSender(
|
||||
// 设置是否启用 SSL 连接
|
||||
if (openSSL) {
|
||||
put("mail.smtp.ssl.enable", "true")
|
||||
put("mail.smtp.socketFactory.class", sslFactory)
|
||||
// 使用 TLSv1.2 协议 & 信任所有主机
|
||||
val sf = MailSSLSocketFactory("TLSv1.2")
|
||||
sf.setTrustedHosts("*")
|
||||
put("mail.smtp.ssl.socketFactory", sf)
|
||||
put("mail.smtp.ssl.protocols", "TLSv1.2")
|
||||
}
|
||||
// 设置是否启用 TLS 连接
|
||||
if (startTls) {
|
||||
@ -171,4 +176,4 @@ class EmailSender(
|
||||
return PasswordAuthentication(userName, password)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,18 @@
|
||||
package com.idormy.sms.forwarder.utils.mail
|
||||
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import jakarta.activation.DataHandler
|
||||
import jakarta.activation.FileDataSource
|
||||
import jakarta.mail.Authenticator
|
||||
import jakarta.mail.Message
|
||||
import jakarta.mail.Session
|
||||
import jakarta.mail.Transport
|
||||
import jakarta.mail.internet.InternetAddress
|
||||
import jakarta.mail.internet.MimeBodyPart
|
||||
import jakarta.mail.internet.MimeMessage
|
||||
import jakarta.mail.internet.MimeMultipart
|
||||
import jakarta.mail.internet.MimeUtility
|
||||
import jakarta.mail.util.ByteArrayDataSource
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
@ -22,18 +34,6 @@ import java.io.InputStream
|
||||
import java.security.Security
|
||||
import java.util.Date
|
||||
import java.util.Properties
|
||||
import javax.activation.DataHandler
|
||||
import javax.activation.FileDataSource
|
||||
import javax.mail.Authenticator
|
||||
import javax.mail.Message
|
||||
import javax.mail.Session
|
||||
import javax.mail.Transport
|
||||
import javax.mail.internet.InternetAddress
|
||||
import javax.mail.internet.MimeBodyPart
|
||||
import javax.mail.internet.MimeMessage
|
||||
import javax.mail.internet.MimeMultipart
|
||||
import javax.mail.internet.MimeUtility
|
||||
import javax.mail.util.ByteArrayDataSource
|
||||
|
||||
|
||||
@Suppress("PrivatePropertyName")
|
||||
@ -244,4 +244,3 @@ class PgpUtils(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,17 @@
|
||||
package com.idormy.sms.forwarder.utils.mail
|
||||
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import jakarta.activation.DataHandler
|
||||
import jakarta.activation.FileDataSource
|
||||
import jakarta.mail.Authenticator
|
||||
import jakarta.mail.Message
|
||||
import jakarta.mail.Session
|
||||
import jakarta.mail.Transport
|
||||
import jakarta.mail.internet.InternetAddress
|
||||
import jakarta.mail.internet.MimeBodyPart
|
||||
import jakarta.mail.internet.MimeMessage
|
||||
import jakarta.mail.internet.MimeMultipart
|
||||
import jakarta.mail.internet.MimeUtility
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.bouncycastle.cert.jcajce.JcaCertStore
|
||||
@ -24,17 +35,7 @@ import java.security.Security
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.Date
|
||||
import java.util.Properties
|
||||
import javax.activation.DataHandler
|
||||
import javax.activation.FileDataSource
|
||||
import javax.mail.Authenticator
|
||||
import javax.mail.Message
|
||||
import javax.mail.Session
|
||||
import javax.mail.Transport
|
||||
import javax.mail.internet.InternetAddress
|
||||
import javax.mail.internet.MimeBodyPart
|
||||
import javax.mail.internet.MimeMessage
|
||||
import javax.mail.internet.MimeMultipart
|
||||
import javax.mail.internet.MimeUtility
|
||||
|
||||
|
||||
@Suppress("PrivatePropertyName")
|
||||
class SmimeUtils(
|
||||
@ -249,4 +250,4 @@ class SmimeUtils(
|
||||
return encryptedMessage
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -67,17 +67,27 @@ class BarkUtils {
|
||||
if (!TextUtils.isEmpty(setting.level)) msgMap["level"] = setting.level
|
||||
if (!TextUtils.isEmpty(setting.sound)) msgMap["sound"] = setting.sound
|
||||
if (!TextUtils.isEmpty(setting.badge)) msgMap["badge"] = setting.badge
|
||||
if (!TextUtils.isEmpty(setting.url)) msgMap["url"] = setting.url
|
||||
if (!TextUtils.isEmpty(setting.url)) {
|
||||
val replacedUrl = msgInfo.getContentForSend(setting.url)
|
||||
msgMap["url"] = replacedUrl
|
||||
}
|
||||
|
||||
//自动复制验证码
|
||||
val pattern = Regex("(?<!回复)(验证码|授权码|校验码|检验码|确认码|激活码|动态码|安全码|(验证)?代码|校验代码|检验代码|激活代码|确认代码|动态代码|安全代码|登入码|认证码|识别码|短信口令|动态密码|交易码|上网密码|动态口令|随机码|驗證碼|授權碼|校驗碼|檢驗碼|確認碼|激活碼|動態碼|(驗證)?代碼|校驗代碼|檢驗代碼|確認代碼|激活代碼|動態代碼|登入碼|認證碼|識別碼|一次性密码|[Cc][Oo][Dd][Ee]|[Vv]erification)")
|
||||
if (pattern.containsMatchIn(content)) {
|
||||
var code = content.replace("(.*)((代|授权|验证|动态|校验)码|[【\\[].*[】\\]]|[Cc][Oo][Dd][Ee]|[Vv]erification\\s?([Cc]ode)?)\\s?(G-|<#>)?([::\\s是为]|[Ii][Ss]){0,3}[\\((\\[【{「]?(([0-9\\s]{4,7})|([\\dA-Za-z]{5,6})(?!([Vv]erification)?([Cc][Oo][Dd][Ee])|:))[」}】\\])\\)]?(?=([^0-9a-zA-Z]|\$))(.*)".toRegex(), "$7").trim()
|
||||
code = code.replace("\\D*[\\((\\[【{「]?([0-9]{3}\\s?[0-9]{1,3})[」}】\\])\\)]?(?=.*((代|授权|验证|动态|校验)码|[【\\[].*[】\\]]|[Cc][Oo][Dd][Ee]|[Vv]erification\\s?([Cc]ode)?))(.*)".toRegex(), "$1").trim()
|
||||
if (code.isNotEmpty()) {
|
||||
msgMap["copy"] = code
|
||||
msgMap["automaticallyCopy"] = 1
|
||||
if (!TextUtils.isEmpty(setting.call)) msgMap["call"] = setting.call
|
||||
|
||||
//自动复制
|
||||
if (TextUtils.isEmpty(setting.autoCopy)) {
|
||||
val pattern = Regex("(?<!回复)(验证码|授权码|校验码|检验码|确认码|激活码|动态码|安全码|(验证)?代码|校验代码|检验代码|激活代码|确认代码|动态代码|安全代码|登入码|认证码|识别码|短信口令|动态密码|交易码|上网密码|动态口令|随机码|驗證碼|授權碼|校驗碼|檢驗碼|確認碼|激活碼|動態碼|(驗證)?代碼|校驗代碼|檢驗代碼|確認代碼|激活代碼|動態代碼|登入碼|認證碼|識別碼|一次性密码|[Cc][Oo][Dd][Ee]|[Vv]erification)")
|
||||
if (pattern.containsMatchIn(content)) {
|
||||
var code = content.replace("(.*)((代|授权|验证|动态|校验)码|[【\\[].*[】\\]]|[Cc][Oo][Dd][Ee]|[Vv]erification\\s?([Cc]ode)?)\\s?(G-|<#>)?([::\\s是为]|[Ii][Ss]){0,3}[\\((\\[【{「]?(([0-9\\s]{4,7})|([\\dA-Za-z]{5,6})(?!([Vv]erification)?([Cc][Oo][Dd][Ee])|:))[」}】\\])\\)]?(?=([^0-9a-zA-Z]|\$))(.*)".toRegex(), "$7").trim()
|
||||
code = code.replace("\\D*[\\((\\[【{「]?([0-9]{3}\\s?[0-9]{1,3})[」}】\\])\\)]?(?=.*((代|授权|验证|动态|校验)码|[【\\[].*[】\\]]|[Cc][Oo][Dd][Ee]|[Vv]erification\\s?([Cc]ode)?))(.*)".toRegex(), "$1").trim()
|
||||
if (code.isNotEmpty()) {
|
||||
msgMap["copy"] = code
|
||||
msgMap["autoCopy"] = 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msgMap["copy"] = msgInfo.getContentForSend(setting.autoCopy)
|
||||
msgMap["autoCopy"] = 1
|
||||
}
|
||||
|
||||
val requestMsg: String = Gson().toJson(msgMap)
|
||||
@ -161,4 +171,4 @@ class BarkUtils {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +137,14 @@ class EmailUtils {
|
||||
setting.fromEmail += setting.mailType
|
||||
}
|
||||
|
||||
"@icloud.com" -> {
|
||||
setting.host = "smtp.mail.me.com"
|
||||
setting.port = "587"
|
||||
setting.ssl = false
|
||||
setting.startTls = true
|
||||
setting.fromEmail += setting.mailType
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
@ -346,4 +354,4 @@ class EmailUtils {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,14 @@ class ServerchanUtils {
|
||||
msgInfo.getContentForSend(SettingUtils.smsTemplate)
|
||||
}
|
||||
|
||||
val requestUrl: String = String.format("https://sctapi.ftqq.com/%s.send", setting.sendKey) //推送地址
|
||||
// 兼容Server酱³Sendkey,使用正则表达式提取数字部分
|
||||
val matchResult = Regex("^sctp(\\d+)t", RegexOption.IGNORE_CASE).find(setting.sendKey)
|
||||
val requestUrl = if (matchResult != null && matchResult.groups[1] != null) {
|
||||
"https://${matchResult.groups[1]?.value}.push.ft07.com/send/${setting.sendKey}.send"
|
||||
} else {
|
||||
String.format("https://sctapi.ftqq.com/%s.send", setting.sendKey) // 默认推送地址
|
||||
}
|
||||
|
||||
Log.i(TAG, "requestUrl:$requestUrl")
|
||||
|
||||
val request = XHttp.post(requestUrl)
|
||||
|
@ -58,13 +58,29 @@ class TelegramUtils private constructor() {
|
||||
|
||||
val request = if (setting.method == "GET") {
|
||||
requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8")
|
||||
if (setting.parseMode.isNotEmpty() && setting.parseMode != "TEXT") {
|
||||
requestUrl += "&parse_mode=" + setting.parseMode
|
||||
}
|
||||
Log.i(TAG, "requestUrl:$requestUrl")
|
||||
XHttp.get(requestUrl)
|
||||
} else {
|
||||
val bodyMap: MutableMap<String, Any> = mutableMapOf()
|
||||
bodyMap["chat_id"] = setting.chatId
|
||||
bodyMap["text"] = content
|
||||
bodyMap["parse_mode"] = "HTML"
|
||||
when (setting.parseMode) {
|
||||
"MarkdownV2" -> {
|
||||
bodyMap["parse_mode"] = "MarkdownV2"
|
||||
bodyMap["text"] = escapeMarkdownV2(content)
|
||||
}
|
||||
|
||||
"HTML" -> {
|
||||
bodyMap["parse_mode"] = "HTML"
|
||||
bodyMap["text"] = content
|
||||
}
|
||||
|
||||
else -> {
|
||||
bodyMap["text"] = content
|
||||
}
|
||||
}
|
||||
bodyMap["disable_web_page_preview"] = "true"
|
||||
val requestMsg: String = Gson().toJson(bodyMap)
|
||||
Log.i(TAG, "requestMsg:$requestMsg")
|
||||
@ -155,5 +171,18 @@ class TelegramUtils private constructor() {
|
||||
}
|
||||
return buffer.toString()
|
||||
}
|
||||
|
||||
// 用于转义 MarkdownV2 特殊字符的方法
|
||||
private fun escapeMarkdownV2(text: String): String {
|
||||
// TODO: MarkdownV2 要求转义以下字符,实测不能全部转义(丢失格式)
|
||||
//val specialChars = listOf('_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!')
|
||||
val specialChars = listOf('-')
|
||||
var escapedText = text
|
||||
for (char in specialChars) {
|
||||
// 将每个字符替换为带反斜杠的形式
|
||||
escapedText = escapedText.replace(char.toString(), "\\$char")
|
||||
}
|
||||
return escapedText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,10 +93,19 @@ class WebhookUtils {
|
||||
|
||||
//通过`Content-Type=applicaton/json`指定请求体为`json`格式
|
||||
var isJson = false
|
||||
//通过`Content-Type=text/plain、text/html、text/css、text/javascript、text/xml`指定请求体为`文本`格式
|
||||
var isText = false
|
||||
var mediaType = "text/plain"
|
||||
for ((key, value) in setting.headers.entries) {
|
||||
if (key.equals("Content-Type", ignoreCase = true) && value.contains("application/json")) {
|
||||
isJson = true
|
||||
break
|
||||
if (key.equals("Content-Type", ignoreCase = true)) {
|
||||
if (value.contains("application/json")) {
|
||||
isJson = true
|
||||
break
|
||||
} else if (value.startsWith("text/")) {
|
||||
isText = true
|
||||
mediaType = value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +147,7 @@ class WebhookUtils {
|
||||
}
|
||||
Log.d(TAG, "method = GET, Url = $requestUrl")
|
||||
XHttp.get(requestUrl).keepJson(true)
|
||||
} else if (webParams.isNotEmpty() && (isJson || webParams.startsWith("{"))) {
|
||||
} else if (webParams.isNotEmpty() && (isJson || isText || webParams.startsWith("{"))) {
|
||||
webParams = msgInfo.replaceTemplate(webParams, "", "Gson")
|
||||
val bodyMsg = webParams.replace("[from]", from)
|
||||
.replace("[content]", escapeJson(content))
|
||||
@ -155,10 +164,18 @@ class WebhookUtils {
|
||||
.replace("[timestamp]", timestamp.toString())
|
||||
.replace("[sign]", sign)
|
||||
Log.d(TAG, "method = ${setting.method}, Url = $requestUrl, bodyMsg = $bodyMsg")
|
||||
when (setting.method) {
|
||||
"PUT" -> XHttp.put(requestUrl).keepJson(true).upJson(bodyMsg)
|
||||
"PATCH" -> XHttp.patch(requestUrl).keepJson(true).upJson(bodyMsg)
|
||||
else -> XHttp.post(requestUrl).keepJson(true).upJson(bodyMsg)
|
||||
if (isText) {
|
||||
when (setting.method) {
|
||||
"PUT" -> XHttp.put(requestUrl).keepJson(true).upString(bodyMsg, mediaType)
|
||||
"PATCH" -> XHttp.patch(requestUrl).keepJson(true).upString(bodyMsg, mediaType)
|
||||
else -> XHttp.post(requestUrl).keepJson(true).upString(bodyMsg, mediaType)
|
||||
}
|
||||
} else {
|
||||
when (setting.method) {
|
||||
"PUT" -> XHttp.put(requestUrl).keepJson(true).upJson(bodyMsg)
|
||||
"PATCH" -> XHttp.patch(requestUrl).keepJson(true).upJson(bodyMsg)
|
||||
else -> XHttp.post(requestUrl).keepJson(true).upJson(bodyMsg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (webParams.isEmpty()) {
|
||||
|
@ -6,17 +6,19 @@ import android.widget.CompoundButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.AppCompatCheckBox
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.http.api.ApiService.IGetService
|
||||
import com.idormy.sms.forwarder.core.http.callback.NoTipCallBack
|
||||
import com.idormy.sms.forwarder.core.http.entity.TipInfo
|
||||
import com.idormy.sms.forwarder.utils.AppUtils
|
||||
import com.idormy.sms.forwarder.utils.SharedPreference
|
||||
import com.xuexiang.constant.TimeConstants
|
||||
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.xui.widget.dialog.BaseDialog
|
||||
import com.xuexiang.xutil.resource.ResUtils.getString
|
||||
import com.zzhoujay.richtext.RichText
|
||||
|
||||
/**
|
||||
@ -163,18 +165,33 @@ class GuideTipsDialog(context: Context?, tips: List<TipInfo>) :
|
||||
*/
|
||||
@JvmStatic
|
||||
fun showTipsForce(context: Context?) {
|
||||
val request = XHttp.custom().cacheMode(CacheMode.FIRST_CACHE)
|
||||
.cacheTime(TimeConstants.DAY.toLong()).cacheKey("getTips")
|
||||
request.apiCall(request.create(
|
||||
IGetService::class.java
|
||||
).tips, object : NoTipCallBack<List<TipInfo>>() {
|
||||
@Throws(Throwable::class)
|
||||
override fun onSuccess(response: List<TipInfo>?) {
|
||||
if (!response.isNullOrEmpty()) {
|
||||
GuideTipsDialog(context, response).show()
|
||||
XHttp.get(getString(R.string.url_tips))
|
||||
.keepJson(true)
|
||||
.ignoreHttpsCert()
|
||||
.timeStamp(true) //url自动追加时间戳,避免缓存
|
||||
.execute(object : SimpleCallBack<String>() {
|
||||
override fun onError(e: ApiException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
override fun onSuccess(json: String) {
|
||||
try {
|
||||
val gson = Gson()
|
||||
val jsonObject = gson.fromJson(json, JsonObject::class.java)
|
||||
if (jsonObject.isJsonObject
|
||||
&& jsonObject.has("Code") && jsonObject["Code"].asInt == 0
|
||||
&& jsonObject.has("Data") && jsonObject["Data"].isJsonArray
|
||||
) {
|
||||
val dataJsonArray = jsonObject["Data"].asJsonArray
|
||||
val listType = object : TypeToken<List<TipInfo>>() {}.type
|
||||
val tips = gson.fromJson<List<TipInfo>>(dataJsonArray, listType)
|
||||
GuideTipsDialog(context, tips).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun setIsIgnoreTips(isIgnore: Boolean): Boolean {
|
||||
@ -190,4 +207,4 @@ class GuideTipsDialog(context: Context?, tips: List<TipInfo>) :
|
||||
initViews()
|
||||
updateTips(tips)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
app/src/main/res/drawable/rounded_button.xml
Normal file
20
app/src/main/res/drawable/rounded_button.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 按下时的背景 -->
|
||||
<item android:state_pressed="true">
|
||||
<shape>
|
||||
<solid android:color="#1E88E5" /> <!-- 按下时的深蓝背景色 -->
|
||||
<corners android:radius="3dp" /> <!-- 圆角半径 -->
|
||||
<stroke android:width="1dp" android:color="#1565C0" /> <!-- 边框深蓝色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 默认背景 -->
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="#2196F3" /> <!-- 默认浅蓝背景色 -->
|
||||
<corners android:radius="3dp" /> <!-- 圆角半径 -->
|
||||
<stroke android:width="1dp" android:color="#1E88E5" /> <!-- 边框蓝色 -->
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
@ -376,65 +376,13 @@
|
||||
android:inputType="textMultiLine"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_sms_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_content" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender_app"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_sender_app" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_uid"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_uid" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_title_app"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_title_app" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content_app"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_content_app" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -509,52 +457,184 @@
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="180dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/silent_time_period"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/silent_time_period_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp,TooManyViews" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:id="@+id/tv_silent_period"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/silent_time_period"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center" />
|
||||
|
||||
<TextView
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/btn_silent_period"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/silent_time_period_tips"
|
||||
android:layout_marginStart="5dp"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="@string/select"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp,TooManyViews" />
|
||||
app:sb_color_unpressed="@color/colorPrimary"
|
||||
app:sb_ripple_color="@color/white"
|
||||
app:sb_ripple_duration="500"
|
||||
app:sb_shape_type="rectangle"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_silent_period"
|
||||
android:layout_width="0dp"
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center" />
|
||||
android:layout_marginTop="3dp">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/btn_silent_period"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="@string/select"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
app:sb_color_unpressed="@color/colorPrimary"
|
||||
app:sb_ripple_color="@color/white"
|
||||
app:sb_ripple_duration="500"
|
||||
app:sb_shape_type="rectangle"
|
||||
tools:ignore="SmallSp" />
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/mon"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/mon"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/tue"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/tue"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/wed"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/wed"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/thu"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/thu"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/fri"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/fri"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/sat"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/sat"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/sun"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/sun"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:ignore="SmallSp" />
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -592,4 +672,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -140,6 +140,28 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/BarStyle.Switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:text="@string/bark_call"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_call"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
@ -271,36 +293,60 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_auto_copy_template"
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/auto_copy"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
android:text="@string/custom_template_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||
android:id="@+id/et_auto_copy_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<GridLayout
|
||||
android:id="@+id/gl_auto_copy_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -405,4 +451,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -253,35 +253,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -319,4 +297,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -230,35 +230,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -443,4 +421,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -149,35 +149,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_nickname"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender_to_nickname"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra_to_nickname"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time_to_nickname"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name_to_nickname"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -520,35 +498,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -586,4 +542,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -158,35 +158,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -230,41 +208,13 @@
|
||||
android:text=""
|
||||
tools:ignore="RtlHardcoded,SpeakableTextPresentCheck" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_message_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_content" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -302,4 +252,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -235,35 +235,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name_to_title"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -307,41 +285,13 @@
|
||||
android:text=""
|
||||
tools:ignore="RtlHardcoded,SpeakableTextPresentCheck" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_message_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_content" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -379,4 +329,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -112,35 +112,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -205,4 +183,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -286,35 +286,13 @@
|
||||
android:singleLine="true"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_title_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -352,4 +330,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -102,6 +102,44 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/parse_mode"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/rg_parse_mode"
|
||||
style="@style/rg_style"
|
||||
android:layout_marginStart="5dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_parse_mode_text"
|
||||
style="@style/rg_rb_style"
|
||||
android:text="@string/parse_mode_text" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_parse_mode_html"
|
||||
style="@style/rg_rb_style"
|
||||
android:checked="true"
|
||||
android:text="@string/parse_mode_html" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_parse_mode_markdown"
|
||||
style="@style/rg_rb_style"
|
||||
android:text="@string/parse_mode_markdown" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
@ -306,4 +344,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -1226,7 +1226,7 @@
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/enabe_cactus_tips"
|
||||
android:text="@string/enable_cactus_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
@ -1567,6 +1567,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_sim2"
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -1741,41 +1742,13 @@
|
||||
android:text=""
|
||||
tools:ignore="RtlHardcoded,SpeakableTextPresentCheck" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_sms_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_content" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="3dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -1975,4 +1948,4 @@
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -86,101 +86,350 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_play_settings"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_volume"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.picker.XSeekBar
|
||||
android:id="@+id/xsb_volume"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
app:xsb_max="100"
|
||||
app:xsb_min="1" />
|
||||
android:text="@string/alarm_play_settings"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_enable_music"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_alarm_settings_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_play_times"
|
||||
android:textStyle="bold" />
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<com.xuexiang.xui.widget.picker.XSeekBar
|
||||
android:id="@+id/xsb_loop_times"
|
||||
android:layout_width="0dp"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
app:xsb_max="30"
|
||||
app:xsb_min="0" />
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_volume"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.picker.XSeekBar
|
||||
android:id="@+id/xsb_volume"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
app:xsb_max="100"
|
||||
app:xsb_min="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_play_times"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.picker.XSeekBar
|
||||
android:id="@+id/xsb_play_times"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
app:xsb_max="30"
|
||||
app:xsb_min="0" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_music"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
||||
android:id="@+id/et_music_path"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/alarm_music_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/btn_file_picker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="@string/select_file"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
app:sb_color_unpressed="@color/colorPrimary"
|
||||
app:sb_ripple_color="@color/white"
|
||||
app:sb_ripple_duration="500"
|
||||
app:sb_shape_type="rectangle"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_vibrate_settings"
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_music"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
||||
android:id="@+id/et_music_path"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/alarm_music_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
android:text="@string/alarm_vibrate_settings"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/btn_file_picker"
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_enable_vibrate"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_vibrate_settings_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="@string/select_file"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
app:sb_color_unpressed="@color/colorPrimary"
|
||||
app:sb_ripple_color="@color/white"
|
||||
app:sb_ripple_duration="500"
|
||||
app:sb_shape_type="rectangle"
|
||||
tools:ignore="SmallSp" />
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_vibration_effect"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
||||
android:id="@+id/et_vibration_effect"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/alarm_vibration_effect_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_vibration_effect_1"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/alarm_vibration_effect_1" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_vibration_effect_2"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/alarm_vibration_effect_2" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_vibration_effect_3"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/alarm_vibration_effect_3" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_repeat_times"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.picker.XSeekBar
|
||||
android:id="@+id/xsb_repeat_times"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
app:xsb_max="30"
|
||||
app:xsb_min="0" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_flash_settings"
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/alarm_flash_settings"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_enable_flash"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_flash_settings_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_flash_effect"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
||||
android:id="@+id/et_flash_effect"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/alarm_flash_effect_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_flash_effect_1"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/alarm_flash_effect_1" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_flash_effect_2"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/alarm_flash_effect_2" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_repeat_times"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.picker.XSeekBar
|
||||
android:id="@+id/xsb_flash_times"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
app:xsb_max="30"
|
||||
app:xsb_min="0" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -220,4 +469,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -161,65 +161,13 @@
|
||||
android:inputType="textMultiLine"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
<GridLayout
|
||||
android:id="@+id/gl_sms_template"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender"
|
||||
style="@style/insertButtonStyle"
|
||||
android:text="@string/insert_sender" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_content" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_extra"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_extra" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_sender_app"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_sender_app" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_uid"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_uid" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_title_app"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_title_app" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_content_app"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_content_app" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_time"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_time" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||
android:id="@+id/bt_insert_device_name"
|
||||
style="@style/insertButtonStyle"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/insert_device_name" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center"
|
||||
android:columnCount="4"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -357,4 +305,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -1,5 +1,35 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<string name="insert_tag_from">Phone Number</string>
|
||||
<string name="insert_tag_sms">SMS Content</string>
|
||||
<string name="insert_tag_package_name">Package Name</string>
|
||||
<string name="insert_tag_app_name">App Name</string>
|
||||
<string name="insert_tag_title">Inform Title</string>
|
||||
<string name="insert_tag_msg">Inform Content</string>
|
||||
<string name="insert_tag_card_slot">SIM Label</string>
|
||||
<string name="insert_tag_card_subid">SIM SubId</string>
|
||||
<string name="insert_tag_receive_time">Receive Time</string>
|
||||
<string name="insert_tag_current_time">Current Time</string>
|
||||
<string name="insert_tag_device_name">Device Name</string>
|
||||
<string name="insert_tag_app_version">SmsF Version</string>
|
||||
<string name="insert_tag_call_type">Call Type</string>
|
||||
<string name="insert_tag_location">Location</string>
|
||||
<string name="insert_tag_location_longitude">Longitude</string>
|
||||
<string name="insert_tag_location_latitude">Latitude</string>
|
||||
<string name="insert_tag_location_address">Address</string>
|
||||
<string name="insert_tag_battery_pct">Battery Percentage</string>
|
||||
<string name="insert_tag_battery_status">Battery Status</string>
|
||||
<string name="insert_tag_battery_plugged">Charging Method</string>
|
||||
<string name="insert_tag_battery_info">Complete Battery Info</string>
|
||||
<string name="insert_tag_battery_info_simple">Simplified Battery Info</string>
|
||||
<string name="insert_tag_uid">UID</string>
|
||||
<string name="insert_tag_ipv4">Public IPv4</string>
|
||||
<string name="insert_tag_ipv6">Public IPv6</string>
|
||||
<string name="insert_tag_ip_list">IP List</string>
|
||||
<string name="insert_tag_net_type">Network Status</string>
|
||||
<string name="insert_tag_contact_name">Contact Name</string>
|
||||
<string name="insert_tag_phone_area">Phone Area</string>
|
||||
|
||||
<string name="type_param_sms">Sms</string>
|
||||
<string name="type_param_call">Call</string>
|
||||
<string name="type_param_app">App</string>
|
||||
@ -58,6 +88,7 @@
|
||||
<string name="url_help">https://gitee.com/pp/SmsForwarder/wikis/pages</string>
|
||||
<string name="url_donation_link">https://gitee.com/pp/SmsForwarder.wiki/raw/master/%E6%89%93%E8%B5%8F%E5%90%8D%E5%8D%95.md</string>
|
||||
<string name="url_wechat_miniprogram">https://gitee.com/pp/SmsForwarder/raw/main/pic/wechat_miniprogram.jpg</string>
|
||||
<string name="url_tips">https://gitee.com/pp/SmsForwarder.wiki/raw/master/tips_en.json</string>
|
||||
|
||||
<string name="lab_yes">Yes</string>
|
||||
<string name="lab_no">No</string>
|
||||
@ -186,6 +217,13 @@
|
||||
<string name="switch_rule_status">Enable This Forwarding Rule</string>
|
||||
<string name="invalid_match_value">The matched value cannot be null</string>
|
||||
<string name="invalid_call_type">The call type is incorrect, you can only enter any number from 1 to 6.</string>
|
||||
<string name="mon">MON</string>
|
||||
<string name="tue">TUE</string>
|
||||
<string name="wed">WED</string>
|
||||
<string name="thu">THU</string>
|
||||
<string name="fri">FRI</string>
|
||||
<string name="sat">SAT</string>
|
||||
<string name="sun">SUN</string>
|
||||
<!--SenderActivity-->
|
||||
<string name="delete_sender_title">Delete confirmation</string>
|
||||
<string name="delete_sender_tips">Are you sure to delete this sender?</string>
|
||||
@ -215,8 +253,8 @@
|
||||
<string name="invalid_wework_agent">CoreID, AgentID, and Secret cannot be empty</string>
|
||||
<string name="invalid_dingtalk_inner_robot">AgentId, AppKey, AppSecret, and UserIds cannot be empty</string>
|
||||
<string name="invalid_phone_num">The receiving phone number cannot be empty</string>
|
||||
<string name="invalid_multi_match">Malformed multiple match rule line %s</string>
|
||||
<string name="invalid_regex_replace">Incorrect format on line %s of regex replacement</string>
|
||||
<string name="invalid_multi_match">Malformed multiple match rule line %d</string>
|
||||
<string name="invalid_regex_replace">Incorrect format on line %d of regex replacement</string>
|
||||
<string name="invalid_message_card">The Message Card Json is invalid.</string>
|
||||
<string name="email_host">Host</string>
|
||||
<string name="smtp_port">Port</string>
|
||||
@ -271,6 +309,10 @@
|
||||
<string name="TelegramApiToken">ApiToken or Custom Proxy Address (startwith http)</string>
|
||||
<string name="TelegramChatId">ChatId</string>
|
||||
<string name="Method" formatted="false">Method</string>
|
||||
<string name="parse_mode">Parse Mode</string>
|
||||
<string name="parse_mode_text">Text</string>
|
||||
<string name="parse_mode_html">Html</string>
|
||||
<string name="parse_mode_markdown">MarkdownV2</string>
|
||||
|
||||
<string name="SmsSimSlot">SIM Slot</string>
|
||||
<string name="same_source">Same source</string>
|
||||
@ -310,17 +352,10 @@
|
||||
<string name="custom_template">Custom templates</string>
|
||||
<string name="custom_template_tips">Tip: Insert labels as needed; Leave blank to apply default template</string>
|
||||
<string name="insert_sender">Phone</string>
|
||||
<string name="insert_sender_app">PackageName</string>
|
||||
<string name="insert_uid">UID</string>
|
||||
<string name="insert_content">SMS</string>
|
||||
<string name="insert_title_app">InformTitle</string>
|
||||
<string name="insert_content_app">InformContent</string>
|
||||
<string name="insert_extra">SIM</string>
|
||||
<string name="insert_time">Time</string>
|
||||
<string name="insert_device_name">Device</string>
|
||||
<string name="battery_setting">Battery Optimization</string>
|
||||
<string name="battery_setting_tips">Set it to manual management, including automatic startup, associated startup, and background running</string>
|
||||
<string name="unknown_number">Unknown Number</string>
|
||||
<string name="unknown_area">Unknown Area</string>
|
||||
<string name="unsupport">Your phone does not support this setting</string>
|
||||
<string name="isIgnored">Set successfully!</string>
|
||||
<string name="isIgnored2">Can not directly operate the system power saving optimization Settings</string>
|
||||
@ -357,6 +392,7 @@
|
||||
<string name="appicon">App Icon</string>
|
||||
<string name="user_app">User App</string>
|
||||
<string name="system_app">System App</string>
|
||||
<string name="tips_get_installed_apps">Please grant GET_INSTALLED_APPS permission</string>
|
||||
<string name="tips_notification">Please grant Notification permission, in order to keep the App alive!</string>
|
||||
<string name="tips_notification_listener">Please grant Notification reading permission to SmsForwarder, before other Apps\'s notification could be forwarded. Forwarding automatically canceled!</string>
|
||||
<string name="pushplus_website">Official website</string>
|
||||
@ -403,6 +439,7 @@
|
||||
<string name="GotifyWebServer">WebServer</string>
|
||||
<string name="GotifyWebServerTips"><![CDATA[eg.: https://push.ppps.cn/message?token=<apptoken>]]></string>
|
||||
<string name="title_template">Title Template</string>
|
||||
<string name="auto_copy">Auto Copy</string>
|
||||
<string name="priority">Priority(1 – 9)</string>
|
||||
<string name="dingtalk_robot">Dingtalk Group Bot</string>
|
||||
<string name="dingtalk_inner_robot">Dingtalk Inner Bot</string>
|
||||
@ -446,7 +483,7 @@
|
||||
<string name="interval_label">Increasing Interval</string>
|
||||
<string name="timeout_label">Single Timeout</string>
|
||||
<string name="seconds">secs</string>
|
||||
<string name="seconds_n">%s sec</string>
|
||||
<string name="seconds_n">%d sec</string>
|
||||
<string name="retry_label">Max Retries</string>
|
||||
<string name="test_sender_sms">[%s] Congratulations, the sender test is successful, please continue to add forwarding rules!</string>
|
||||
<string name="test_sender_name">Test Channel</string>
|
||||
@ -512,7 +549,7 @@
|
||||
<string name="no">No</string>
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="tip_can_not_get_sim_infos">Please confirm that the app permission [Get mobile phone information] is [Always allow]</string>
|
||||
<string name="tip_can_not_get_sim_info">The SIM card information in the card slot %s has not been obtained</string>
|
||||
<string name="tip_can_not_get_sim_info">The SIM card information in the card slot %d has not been obtained</string>
|
||||
<string name="auto_check">Auto check</string>
|
||||
<string name="check_update">Check</string>
|
||||
<string name="join_preview_program">Join Preview Program</string>
|
||||
@ -540,6 +577,7 @@
|
||||
<string name="bark_group_tips">Opt., e.g. SmsForwarder</string>
|
||||
<string name="bark_icon">Message Icon</string>
|
||||
<string name="bark_icon_tips">Opt., fill in Url, the picture should not be too big</string>
|
||||
<string name="bark_call">Keep Reminding</string>
|
||||
<string name="bark_sound">Message Sound</string>
|
||||
<string name="bark_sound_tips">Opt., e.g. minuet.caf</string>
|
||||
<string name="bark_badge">Message Badge</string>
|
||||
@ -803,7 +841,7 @@
|
||||
<string name="debug_mode_tips">Save Log.* to file for troubleshooting; export to download directory.</string>
|
||||
<string name="optional_components">Opt.:</string>
|
||||
<string name="enable_cactus">Enable Cactus Keep Alive</string>
|
||||
<string name="enabe_cactus_tips">Dual foreground service/JobScheduler/WorkManager/1px/silent music</string>
|
||||
<string name="enable_cactus_tips">Dual foreground service/JobScheduler/WorkManager/1px/silent music</string>
|
||||
<string name="load_app_list">Get installed app info async at startup</string>
|
||||
<string name="load_app_list_tips">Used to speed up entering the application list/editing forwarding rules drop-down selection/replacement {{APP_NAME}}</string>
|
||||
<string name="load_app_list_toast">A type must be selected when enabling asynchronous loading of the list of installed apps</string>
|
||||
@ -964,8 +1002,8 @@
|
||||
<string name="task_rule_tips">Control the enable/disable of "Rules"</string>
|
||||
<string name="task_sender">Channels On/Off</string>
|
||||
<string name="task_sender_tips">Control the enable/disable of "Senders"</string>
|
||||
<string name="task_alarm">Alarm</string>
|
||||
<string name="task_alarm_tips">Alarm</string>
|
||||
<string name="task_alarm">Alarm Reminder</string>
|
||||
<string name="task_alarm_tips">Play music/vibrate phone to remind</string>
|
||||
<string name="task_resend">Resend Message</string>
|
||||
<string name="task_resend_tips">Resend forwarded records since N hours ago, 0=ALL</string>
|
||||
<string name="task_resend_desc" formatted="false">Resend forwarding records since %s hours ago for %s</string>
|
||||
@ -1115,11 +1153,24 @@
|
||||
|
||||
<string name="start_alarm">Start Alarm</string>
|
||||
<string name="stop_alarm">Stop Alarm</string>
|
||||
<string name="alarm_play_settings">Playback Settings</string>
|
||||
<string name="alarm_play_settings">Play Music</string>
|
||||
<string name="alarm_music">Specify Music</string>
|
||||
<string name="alarm_music_tips">Opt., download mp3/ogg/wav to the Download directory.</string>
|
||||
<string name="alarm_volume">Alarm Volume</string>
|
||||
<string name="alarm_play_times">Play Times(0=Infinite)</string>
|
||||
<string name="alarm_vibrate_settings">Vibrate Phone</string>
|
||||
<string name="alarm_repeat_times">Repeat Times(0=Infinite)</string>
|
||||
<string name="alarm_vibration_effect">Vibration Effect</string>
|
||||
<string name="alarm_vibration_effect_tips">Syntax: =[strong], -[weak], _[no], 100ms each</string>
|
||||
<string name="alarm_vibration_effect_1">Strong vibration</string>
|
||||
<string name="alarm_vibration_effect_2">Weak vibration</string>
|
||||
<string name="alarm_vibration_effect_3">No vibration</string>
|
||||
<string name="alarm_flash_settings">Flash Phone</string>
|
||||
<string name="alarm_flash_effect">Flash Effect</string>
|
||||
<string name="alarm_flash_effect_tips">Syntax: 1 or X [turn on flash], 0 or O [turn off flash], each time 100ms</string>
|
||||
<string name="alarm_flash_effect_1">Turn on flash 100ms</string>
|
||||
<string name="alarm_flash_effect_2">Turn off flash 100ms</string>
|
||||
<string name="alarm_settings_error">At least one of Play Music/Vibrate Phone/Flash Phone must be enabled</string>
|
||||
|
||||
<string name="invalid_tag" formatted="false">%s tag is invalid: %s</string>
|
||||
<string name="invalid_task_name">Please input task name.</string>
|
||||
@ -1142,4 +1193,5 @@
|
||||
<string name="bluetooth_not_supported">Bluetooth not supported.</string>
|
||||
<string name="start_discovery">Discovery</string>
|
||||
<string name="invalid_bluetooth_mac_address">Bluetooth Mac Address is invalid, eg. AA:BB:CC:DD:EE:FF</string>
|
||||
<string name="auto_start_redmi"><![CDATA[RedMi: Authorization Management -> Self-Start Management -> Allow Apps to Self-Start]]></string>
|
||||
</resources>
|
||||
|
@ -1,5 +1,35 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<string name="insert_tag_from">来源号码</string>
|
||||
<string name="insert_tag_sms">短信内容</string>
|
||||
<string name="insert_tag_package_name">APP包名</string>
|
||||
<string name="insert_tag_app_name">APP应用名</string>
|
||||
<string name="insert_tag_title">通知标题</string>
|
||||
<string name="insert_tag_msg">通知内容</string>
|
||||
<string name="insert_tag_card_slot">卡槽备注</string>
|
||||
<string name="insert_tag_card_subid">卡槽主键</string>
|
||||
<string name="insert_tag_receive_time">接收时间</string>
|
||||
<string name="insert_tag_current_time">当前时间</string>
|
||||
<string name="insert_tag_device_name">设备名称</string>
|
||||
<string name="insert_tag_app_version">SmsF版本</string>
|
||||
<string name="insert_tag_call_type">通话类型</string>
|
||||
<string name="insert_tag_location">定位信息</string>
|
||||
<string name="insert_tag_location_longitude">定位经度</string>
|
||||
<string name="insert_tag_location_latitude">定位纬度</string>
|
||||
<string name="insert_tag_location_address">定位地址</string>
|
||||
<string name="insert_tag_battery_pct">电池电量</string>
|
||||
<string name="insert_tag_battery_status">电池状态</string>
|
||||
<string name="insert_tag_battery_plugged">充电方式</string>
|
||||
<string name="insert_tag_battery_info">电池完整信息</string>
|
||||
<string name="insert_tag_battery_info_simple">电池简单信息</string>
|
||||
<string name="insert_tag_uid">用户UID</string>
|
||||
<string name="insert_tag_ipv4">公网IPv4</string>
|
||||
<string name="insert_tag_ipv6">公网IPv6</string>
|
||||
<string name="insert_tag_ip_list">IP地址列表</string>
|
||||
<string name="insert_tag_net_type">网络状态</string>
|
||||
<string name="insert_tag_contact_name">来源姓名</string>
|
||||
<string name="insert_tag_phone_area">来源归属</string>
|
||||
|
||||
<string name="type_param_sms">短信</string>
|
||||
<string name="type_param_call">通话</string>
|
||||
<string name="type_param_app">应用</string>
|
||||
@ -58,6 +88,7 @@
|
||||
<string name="url_help">https://gitee.com/pp/SmsForwarder/wikis/pages</string>
|
||||
<string name="url_donation_link">https://gitee.com/pp/SmsForwarder.wiki/raw/master/%E6%89%93%E8%B5%8F%E5%90%8D%E5%8D%95.md</string>
|
||||
<string name="url_wechat_miniprogram">https://gitee.com/pp/SmsForwarder/raw/main/pic/wechat_miniprogram.jpg</string>
|
||||
<string name="url_tips">https://gitee.com/pp/SmsForwarder.wiki/raw/master/tips.json</string>
|
||||
|
||||
<string name="lab_yes">是</string>
|
||||
<string name="lab_no">否</string>
|
||||
@ -187,6 +218,13 @@
|
||||
<string name="switch_rule_status">启用该条转发规则</string>
|
||||
<string name="invalid_match_value">匹配的值不可为空</string>
|
||||
<string name="invalid_call_type">通话类型不正确,只能填写1到6的任意一个数字</string>
|
||||
<string name="mon">周一</string>
|
||||
<string name="tue">周二</string>
|
||||
<string name="wed">周三</string>
|
||||
<string name="thu">周四</string>
|
||||
<string name="fri">周五</string>
|
||||
<string name="sat">周六</string>
|
||||
<string name="sun">周日</string>
|
||||
<!--SenderActivity-->
|
||||
<string name="delete_sender_title">发送通道操作确认</string>
|
||||
<string name="delete_sender_tips">删除发送通道后会级联删除其相关的转发规则、转发日志的所有记录!\n\n确定删除该条发送通道?</string>
|
||||
@ -216,8 +254,8 @@
|
||||
<string name="invalid_wework_agent">企业ID、AgentID、Secret都不能为空</string>
|
||||
<string name="invalid_dingtalk_inner_robot">AgentId、AppKey、AppSecret、UserIds都不能为空</string>
|
||||
<string name="invalid_phone_num">接收手机号不能为空</string>
|
||||
<string name="invalid_multi_match">多重匹配规则的第 %s 行格式有误</string>
|
||||
<string name="invalid_regex_replace">正则替换内容的第 %s 行格式有误</string>
|
||||
<string name="invalid_multi_match">多重匹配规则的第 %d 行格式有误</string>
|
||||
<string name="invalid_regex_replace">正则替换内容的第 %d 行格式有误</string>
|
||||
<string name="invalid_message_card">自定义消息卡片Json不合法</string>
|
||||
<string name="email_host">主机</string>
|
||||
<string name="smtp_port">端口</string>
|
||||
@ -272,6 +310,10 @@
|
||||
<string name="TelegramApiToken">ApiToken 或 自定义代理地址(http开头)</string>
|
||||
<string name="TelegramChatId">被通知人(或群组)的ChatId</string>
|
||||
<string name="Method" formatted="false">请求方式</string>
|
||||
<string name="parse_mode">解析模式</string>
|
||||
<string name="parse_mode_text">Text</string>
|
||||
<string name="parse_mode_html">Html</string>
|
||||
<string name="parse_mode_markdown">MarkdownV2</string>
|
||||
|
||||
<string name="SmsSimSlot">发送卡槽</string>
|
||||
<string name="same_source">原进原出</string>
|
||||
@ -311,17 +353,10 @@
|
||||
<string name="custom_template">转发信息模版</string>
|
||||
<string name="custom_template_tips">Tip:按需插入内容标签;留空使用默认模版</string>
|
||||
<string name="insert_sender">来源号码</string>
|
||||
<string name="insert_sender_app">APP包名</string>
|
||||
<string name="insert_uid">UID</string>
|
||||
<string name="insert_content">短信内容</string>
|
||||
<string name="insert_title_app">通知标题</string>
|
||||
<string name="insert_content_app">通知内容</string>
|
||||
<string name="insert_extra">卡槽信息</string>
|
||||
<string name="insert_time">接收时间</string>
|
||||
<string name="insert_device_name">设备名称</string>
|
||||
<string name="battery_setting">忽略电池优化设置</string>
|
||||
<string name="battery_setting_tips">请设置为手动管理:允许自启动、允许关联启动、允许后台运行</string>
|
||||
<string name="unknown_number">未知号码</string>
|
||||
<string name="unknown_area">未知归属地</string>
|
||||
<string name="unsupport">您的手机不支持此设置</string>
|
||||
<string name="isIgnored">已将省电优化设置为无限制(不优化)!</string>
|
||||
<string name="isIgnored2">本界面无法直接操作系统的省电优化设置</string>
|
||||
@ -358,6 +393,7 @@
|
||||
<string name="appicon">应用图标</string>
|
||||
<string name="user_app">用户应用</string>
|
||||
<string name="system_app">系统应用</string>
|
||||
<string name="tips_get_installed_apps">请先授予获取应用列表权限</string>
|
||||
<string name="tips_notification">请先授予发送通知权限,有利于《短信转发器》保活!</string>
|
||||
<string name="tips_notification_listener">请先授予《短信转发器》通知使用权,否则无法转发APP通知,已经自动关闭转发!</string>
|
||||
<string name="pushplus_website">官网地址</string>
|
||||
@ -404,6 +440,7 @@
|
||||
<string name="GotifyWebServer">WebServer</string>
|
||||
<string name="GotifyWebServerTips"><![CDATA[例:https://push.ppps.cn/message?token=<apptoken>]]></string>
|
||||
<string name="title_template">标题模板</string>
|
||||
<string name="auto_copy">自动复制</string>
|
||||
<string name="priority">优先级(1 – 9)</string>
|
||||
<string name="dingtalk_robot">钉钉群机器人</string>
|
||||
<string name="dingtalk_inner_robot">钉钉企业机器人</string>
|
||||
@ -447,7 +484,7 @@
|
||||
<string name="interval_label">递增间隔</string>
|
||||
<string name="timeout_label">单次超时</string>
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s秒</string>
|
||||
<string name="seconds_n">%d秒</string>
|
||||
<string name="retry_label">最多重试</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,该发送通道测试成功,请继续添加转发规则!</string>
|
||||
<string name="test_sender_name">测试通道</string>
|
||||
@ -513,7 +550,7 @@
|
||||
<string name="no">No</string>
|
||||
<string name="refresh">刷新</string>
|
||||
<string name="tip_can_not_get_sim_infos">无法获取卡槽信息,请确认应用权限【获取手机信息】为【始终允许】</string>
|
||||
<string name="tip_can_not_get_sim_info">未获取到卡槽%s中的SIM卡信息</string>
|
||||
<string name="tip_can_not_get_sim_info">未获取到卡槽%d中的SIM卡信息</string>
|
||||
<string name="auto_check">启动时检查</string>
|
||||
<string name="check_update">检查更新</string>
|
||||
<string name="join_preview_program">加入SmsF预览体验计划</string>
|
||||
@ -541,6 +578,7 @@
|
||||
<string name="bark_group_tips">可选,例:短信转发器</string>
|
||||
<string name="bark_icon">消息图标</string>
|
||||
<string name="bark_icon_tips">可选,填写Url,图片不要太大</string>
|
||||
<string name="bark_call">持续提醒</string>
|
||||
<string name="bark_sound">消息声音</string>
|
||||
<string name="bark_sound_tips">可选,例:minuet.caf</string>
|
||||
<string name="bark_badge">消息角标</string>
|
||||
@ -695,7 +733,7 @@
|
||||
<string name="api_location_tips">远程查询手机定位,方便找回手机/防止老少走丢</string>
|
||||
<string name="api_location_permission_tips">请先在【通用设置】中【启用GPS定位功能】</string>
|
||||
<string name="location_longitude">经度:%s</string>
|
||||
<string name="location_latitude">维度:%s</string>
|
||||
<string name="location_latitude">纬度:%s</string>
|
||||
<string name="location_address">地址:%s</string>
|
||||
<string name="location_time">时间:%s</string>
|
||||
<string name="location_provider">供应商:%s</string>
|
||||
@ -804,7 +842,7 @@
|
||||
<string name="debug_mode_tips">将Log.*写入文件,以便排查问题;可导出到下载目录</string>
|
||||
<string name="optional_components">可选组件:</string>
|
||||
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
|
||||
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
||||
<string name="enable_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
||||
<string name="load_app_list">启动时异步获取已安装App列表</string>
|
||||
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP_NAME}}</string>
|
||||
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
|
||||
@ -965,8 +1003,8 @@
|
||||
<string name="task_rule_tips">控制【转发规则】的启用/禁用</string>
|
||||
<string name="task_sender">启停通道</string>
|
||||
<string name="task_sender_tips">控制【发送通道】的启用/禁用</string>
|
||||
<string name="task_alarm">声音警报</string>
|
||||
<string name="task_alarm_tips">声音警报</string>
|
||||
<string name="task_alarm">警报提醒</string>
|
||||
<string name="task_alarm_tips">播放音乐/振动手机提醒</string>
|
||||
<string name="task_resend">重发消息</string>
|
||||
<string name="task_resend_tips">自动重发N小时以来的转发记录,0=全部</string>
|
||||
<string name="task_resend_desc" formatted="false">自动重发%s小时以来%s的转发记录</string>
|
||||
@ -1060,7 +1098,7 @@
|
||||
<string name="calc_type_distance">根据GPS坐标计算距离</string>
|
||||
<string name="calc_type_address">根据地址关键字判断</string>
|
||||
<string name="longitude">经度</string>
|
||||
<string name="latitude">维度</string>
|
||||
<string name="latitude">纬度</string>
|
||||
<string name="distance1">以经纬度为中心,</string>
|
||||
<string name="distance2">米半径建立电子围栏</string>
|
||||
<string name="current_coordinates">当前坐标</string>
|
||||
@ -1116,11 +1154,24 @@
|
||||
|
||||
<string name="start_alarm">启动警报</string>
|
||||
<string name="stop_alarm">停止警报</string>
|
||||
<string name="alarm_play_settings">播放设置</string>
|
||||
<string name="alarm_play_settings">播放音乐</string>
|
||||
<string name="alarm_music">指定音乐</string>
|
||||
<string name="alarm_music_tips">可选,下载 mp3/ogg/wav 到 Download 目录</string>
|
||||
<string name="alarm_volume">播放音量</string>
|
||||
<string name="alarm_play_times">播放次数(0=无限)</string>
|
||||
<string name="alarm_vibrate_settings">振动手机</string>
|
||||
<string name="alarm_repeat_times">重复次数(0=无限)</string>
|
||||
<string name="alarm_vibration_effect">振动效果</string>
|
||||
<string name="alarm_vibration_effect_tips">语法:=[强振动], -[弱震动], _[不振动], 每次100ms</string>
|
||||
<string name="alarm_vibration_effect_1">强振动 100ms</string>
|
||||
<string name="alarm_vibration_effect_2">弱振动 100ms</string>
|
||||
<string name="alarm_vibration_effect_3">不振动 100ms</string>
|
||||
<string name="alarm_flash_settings">闪烁手机</string>
|
||||
<string name="alarm_flash_effect">闪光效果</string>
|
||||
<string name="alarm_flash_effect_tips">语法:1或X[开启闪光灯], 0或O[关闭闪光灯], 每次100ms</string>
|
||||
<string name="alarm_flash_effect_1">开启闪光灯 100ms</string>
|
||||
<string name="alarm_flash_effect_2">关闭闪光灯 100ms</string>
|
||||
<string name="alarm_settings_error">播放音乐/振动手机/闪烁手机必须至少开启一个</string>
|
||||
|
||||
<string name="invalid_tag" formatted="false">%s 标签无效:%s</string>
|
||||
<string name="invalid_task_name">请输入任务名称</string>
|
||||
@ -1143,4 +1194,5 @@
|
||||
<string name="bluetooth_not_supported">不支持蓝牙设备</string>
|
||||
<string name="start_discovery">搜索设备</string>
|
||||
<string name="invalid_bluetooth_mac_address">蓝牙设备MAC地址无效,例如:AA:BB:CC:DD:EE:FF</string>
|
||||
<string name="auto_start_redmi"><![CDATA[红米手机:授权管理 -> 自启动管理 -> 允许应用自启动]]></string>
|
||||
</resources>
|
||||
|
@ -1,5 +1,35 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<string name="insert_tag_from">來源號碼</string>
|
||||
<string name="insert_tag_sms">簡訊內容</string>
|
||||
<string name="insert_tag_package_name">APP包名</string>
|
||||
<string name="insert_tag_app_name">APP應用名</string>
|
||||
<string name="insert_tag_title">通知標題</string>
|
||||
<string name="insert_tag_msg">通知內容</string>
|
||||
<string name="insert_tag_card_slot">卡槽備註</string>
|
||||
<string name="insert_tag_card_subid">卡槽主鍵</string>
|
||||
<string name="insert_tag_receive_time">接收時間</string>
|
||||
<string name="insert_tag_current_time">當前時間</string>
|
||||
<string name="insert_tag_device_name">設備名稱</string>
|
||||
<string name="insert_tag_app_version">SmsF版本</string>
|
||||
<string name="insert_tag_call_type">通話類型</string>
|
||||
<string name="insert_tag_location">定位資訊</string>
|
||||
<string name="insert_tag_location_longitude">定位經度</string>
|
||||
<string name="insert_tag_location_latitude">定位緯度</string>
|
||||
<string name="insert_tag_location_address">定位地址</string>
|
||||
<string name="insert_tag_battery_pct">電池電量</string>
|
||||
<string name="insert_tag_battery_status">電池狀態</string>
|
||||
<string name="insert_tag_battery_plugged">充電方式</string>
|
||||
<string name="insert_tag_battery_info">電池完整資訊</string>
|
||||
<string name="insert_tag_battery_info_simple">電池簡單資訊</string>
|
||||
<string name="insert_tag_uid">用戶UID</string>
|
||||
<string name="insert_tag_ipv4">公網IPv4</string>
|
||||
<string name="insert_tag_ipv6">公網IPv6</string>
|
||||
<string name="insert_tag_ip_list">IP地址列表</string>
|
||||
<string name="insert_tag_net_type">網路狀態</string>
|
||||
<string name="insert_tag_contact_name">來源姓名</string>
|
||||
<string name="insert_tag_phone_area">来源歸屬</string>
|
||||
|
||||
<string name="type_param_sms">簡訊</string>
|
||||
<string name="type_param_call">通話</string>
|
||||
<string name="type_param_app">應用</string>
|
||||
@ -58,6 +88,7 @@
|
||||
<string name="url_help">https://gitee.com/pp/SmsForwarder/wikis/pages</string>
|
||||
<string name="url_donation_link">https://gitee.com/pp/SmsForwarder.wiki/raw/master/%E6%89%93%E8%B5%8F%E5%90%8D%E5%8D%95.md</string>
|
||||
<string name="url_wechat_miniprogram">https://gitee.com/pp/SmsForwarder/raw/main/pic/wechat_miniprogram.jpg</string>
|
||||
<string name="url_tips">https://gitee.com/pp/SmsForwarder.wiki/raw/master/tips_tc.json</string>
|
||||
|
||||
<string name="lab_yes">是</string>
|
||||
<string name="lab_no">否</string>
|
||||
@ -187,6 +218,13 @@
|
||||
<string name="switch_rule_status">啟用該條轉發規則</string>
|
||||
<string name="invalid_match_value">匹配的值不可為空</string>
|
||||
<string name="invalid_call_type">通話類型不正確,只能填寫1到6的任意一個數字</string>
|
||||
<string name="mon">星期一</string>
|
||||
<string name="tue">星期二</string>
|
||||
<string name="wed">星期三</string>
|
||||
<string name="thu">星期四</string>
|
||||
<string name="fri">星期五</string>
|
||||
<string name="sat">星期六</string>
|
||||
<string name="sun">星期日</string>
|
||||
<!--SenderActivity-->
|
||||
<string name="delete_sender_title">發送通道操作確認</string>
|
||||
<string name="delete_sender_tips">刪除發送通道後會級聯刪除其相關的轉發規則、轉發日誌的所有記錄!\n\n確定刪除該條發送通道?</string>
|
||||
@ -216,8 +254,8 @@
|
||||
<string name="invalid_wework_agent">企業ID、AgentID、Secret都不能為空</string>
|
||||
<string name="invalid_dingtalk_inner_robot">AgentId、AppKey、AppSecret、UserIds都不能為空</string>
|
||||
<string name="invalid_phone_num">接收手機號不能為空</string>
|
||||
<string name="invalid_multi_match">多重匹配規則的第 %s 行格式有誤</string>
|
||||
<string name="invalid_regex_replace">正則替換內容的第 %s 行格式有誤</string>
|
||||
<string name="invalid_multi_match">多重匹配規則的第 %d 行格式有誤</string>
|
||||
<string name="invalid_regex_replace">正則替換內容的第 %d 行格式有誤</string>
|
||||
<string name="invalid_message_card">自定義消息卡片Json不合法</string>
|
||||
<string name="email_host">主機</string>
|
||||
<string name="smtp_port">端口</string>
|
||||
@ -272,6 +310,10 @@
|
||||
<string name="TelegramApiToken">ApiToken 或 自定義代理地址(http開頭)</string>
|
||||
<string name="TelegramChatId">被通知人(或群組)的ChatId</string>
|
||||
<string name="Method" formatted="false">請求方式</string>
|
||||
<string name="parse_mode">解析模式</string>
|
||||
<string name="parse_mode_text">Text</string>
|
||||
<string name="parse_mode_html">Html</string>
|
||||
<string name="parse_mode_markdown">MarkdownV2</string>
|
||||
|
||||
<string name="SmsSimSlot">發送卡槽</string>
|
||||
<string name="same_source">原進原出</string>
|
||||
@ -311,17 +353,10 @@
|
||||
<string name="custom_template">轉發信息模版</string>
|
||||
<string name="custom_template_tips">Tip:按需插入內容標籤;留空使用默認模版</string>
|
||||
<string name="insert_sender">來源號碼</string>
|
||||
<string name="insert_sender_app">APP包名</string>
|
||||
<string name="insert_uid">UID</string>
|
||||
<string name="insert_content">簡訊內容</string>
|
||||
<string name="insert_title_app">通知標題</string>
|
||||
<string name="insert_content_app">通知內容</string>
|
||||
<string name="insert_extra">卡槽信息</string>
|
||||
<string name="insert_time">接收時間</string>
|
||||
<string name="insert_device_name">裝置名稱</string>
|
||||
<string name="battery_setting">忽略電池優化設置</string>
|
||||
<string name="battery_setting_tips">請設置為手動管理:允許自啟動、允許關聯啟動、允許後台運行</string>
|
||||
<string name="unknown_number">未知號碼</string>
|
||||
<string name="unknown_area">未知歸屬地</string>
|
||||
<string name="unsupport">您的手機不支持此設置</string>
|
||||
<string name="isIgnored">已將省電優化設置為無限制(不優化)!</string>
|
||||
<string name="isIgnored2">本界面無法直接操作系統的省電優化設置</string>
|
||||
@ -358,6 +393,7 @@
|
||||
<string name="appicon">應用圖標</string>
|
||||
<string name="user_app">用戶應用</string>
|
||||
<string name="system_app">系統應用</string>
|
||||
<string name="tips_get_installed_apps">請先授予獲取應用列表權限</string>
|
||||
<string name="tips_notification">請先授予發送通知權限,有利於《簡訊轉發器》保活!</string>
|
||||
<string name="tips_notification_listener">請先授予《簡訊轉發器》通知使用權,否則無法轉發應用程式通知,已經自動關閉轉發!</string>
|
||||
<string name="pushplus_website">官網地址</string>
|
||||
@ -404,6 +440,7 @@
|
||||
<string name="GotifyWebServer">WebServer</string>
|
||||
<string name="GotifyWebServerTips"><![CDATA[例:https://push.ppps.cn/message?token=<apptoken>]]></string>
|
||||
<string name="title_template">標題模板</string>
|
||||
<string name="auto_copy">自動複製</string>
|
||||
<string name="priority">優先級(1 – 9)</string>
|
||||
<string name="dingtalk_robot">釘釘群機器人</string>
|
||||
<string name="dingtalk_inner_robot">釘釘企業機器人</string>
|
||||
@ -447,7 +484,7 @@
|
||||
<string name="interval_label">遞增間隔</string>
|
||||
<string name="timeout_label">單次超時</string>
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s秒</string>
|
||||
<string name="seconds_n">%d秒</string>
|
||||
<string name="retry_label">最多重試</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,該發送通道測試成功,請繼續添加轉發規則!</string>
|
||||
<string name="test_sender_name">測試通道</string>
|
||||
@ -513,7 +550,7 @@
|
||||
<string name="no">No</string>
|
||||
<string name="refresh">刷新</string>
|
||||
<string name="tip_can_not_get_sim_infos">無法獲取卡槽信息,請確認應用權限【獲取手機信息】為【始終允許】</string>
|
||||
<string name="tip_can_not_get_sim_info">未獲取到卡槽%s中的SIM卡信息</string>
|
||||
<string name="tip_can_not_get_sim_info">未獲取到卡槽%d中的SIM卡信息</string>
|
||||
<string name="auto_check">啟動時檢查</string>
|
||||
<string name="check_update">檢查更新</string>
|
||||
<string name="join_preview_program">加入SmsF預覽體驗計劃</string>
|
||||
@ -541,6 +578,7 @@
|
||||
<string name="bark_group_tips">可選,例:簡訊轉發器</string>
|
||||
<string name="bark_icon">消息圖標</string>
|
||||
<string name="bark_icon_tips">可選,填寫Url,圖片不要太大</string>
|
||||
<string name="bark_call">持續提醒</string>
|
||||
<string name="bark_sound">消息聲音</string>
|
||||
<string name="bark_sound_tips">可選,例:minuet.caf</string>
|
||||
<string name="bark_badge">消息角標</string>
|
||||
@ -804,7 +842,7 @@
|
||||
<string name="debug_mode_tips">將 Log.* 寫入檔案,以便排查問題;可匯出至下載目錄</string>
|
||||
<string name="optional_components">可選組件:</string>
|
||||
<string name="enable_cactus">啟用 Cactus 增強保活措施(會增加耗電)</string>
|
||||
<string name="enabe_cactus_tips">雙進程前台服務/JobScheduler/WorkManager/1像素/無聲音樂</string>
|
||||
<string name="enable_cactus_tips">雙進程前台服務/JobScheduler/WorkManager/1像素/無聲音樂</string>
|
||||
<string name="load_app_list">啟動時異步獲取已安裝App列表</string>
|
||||
<string name="load_app_list_tips">用於加速進入應用列表/編輯轉發規則下拉選擇/替換{{APP_NAME}}</string>
|
||||
<string name="load_app_list_toast">開啟異步獲取已安裝App列表時必選一個類型</string>
|
||||
@ -965,8 +1003,8 @@
|
||||
<string name="task_rule_tips">控制【轉發規則】的啟用/禁用</string>
|
||||
<string name="task_sender">啟停通道</string>
|
||||
<string name="task_sender_tips">控制【發送通道】的啟用/禁用</string>
|
||||
<string name="task_alarm">聲音警報</string>
|
||||
<string name="task_alarm_tips">聲音警報</string>
|
||||
<string name="task_alarm">警報提醒</string>
|
||||
<string name="task_alarm_tips">播放音樂/震動手機發出提醒</string>
|
||||
<string name="task_resend">重發消息</string>
|
||||
<string name="task_resend_tips">自動重發N小時以來的轉發記錄,0=全部</string>
|
||||
<string name="task_resend_desc" formatted="false">自動重發%s小時以來%s的轉發記錄</string>
|
||||
@ -1116,11 +1154,25 @@
|
||||
|
||||
<string name="start_alarm">啟動警報</string>
|
||||
<string name="stop_alarm">停止警報</string>
|
||||
<string name="alarm_play_settings">播放設置</string>
|
||||
<string name="alarm_play_settings">播放音樂</string>
|
||||
<string name="alarm_music">指定音樂</string>
|
||||
<string name="alarm_music_tips">可選,下載 mp3/ogg/wav 到 Download 目錄</string>
|
||||
<string name="alarm_volume">播放音量</string>
|
||||
<string name="alarm_play_times">播放次數(0=無限)</string>
|
||||
<string name="alarm_vibrate_settings">振動手機</string>
|
||||
<string name="alarm_repeat_times">重複次數(0=無限)</string>
|
||||
<string name="alarm_vibration_effect">振動效果</string>
|
||||
<string name="alarm_vibration_effect_tips">語法:=[強振動], -[弱振動], _[不振動], 每次100ms</string>
|
||||
<string name="alarm_vibration_effect_1">強振動 100ms</string>
|
||||
<string name="alarm_vibration_effect_2">弱振動 100ms</string>
|
||||
<string name="alarm_vibration_effect_3">不振動 100ms</string>
|
||||
<string name="alarm_flash_settings">閃爍手機</string>
|
||||
<string name="alarm_flash_effect">閃光效果</string>
|
||||
<string name="alarm_flash_effect_tips">語法:1或X[開啟閃光燈],0或O[關閉閃光燈],每次300毫秒</string>
|
||||
<string name="alarm_flash_effect_1">開啟閃光燈 300毫秒</string>
|
||||
<string name="alarm_flash_effect_2">關閉閃光燈 300毫秒</string>
|
||||
<string name="alarm_settings_error">播放音樂/振動手機/閃爍手機必須至少開啟一個</string>
|
||||
|
||||
|
||||
<string name="invalid_tag" formatted="false">%s 標籤無效:%s</string>
|
||||
<string name="invalid_task_name">請輸入任務名稱</string>
|
||||
@ -1143,4 +1195,5 @@
|
||||
<string name="bluetooth_not_supported">不支援藍牙裝置</string>
|
||||
<string name="start_discovery">搜索裝置</string>
|
||||
<string name="invalid_bluetooth_mac_address">藍牙裝置MAC地址無效,例如:AA:BB:CC:DD:EE:FF</string>
|
||||
<string name="auto_start_redmi"><![CDATA[紅米手機:授權管理 -> 自啟動管理 -> 允許應用自啟動]]></string>
|
||||
</resources>
|
||||
|
@ -127,6 +127,7 @@
|
||||
<item>\@sina.cn</item>
|
||||
<item>\@139.com</item>
|
||||
<item>\@189.cn</item>
|
||||
<item>\@icloud.com</item>
|
||||
<item>@string/other_mail_type</item><!--注意这里不能修改-->
|
||||
</string-array>
|
||||
|
||||
@ -142,4 +143,4 @@
|
||||
<item>UTF-32BE</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
</resources>
|
||||
|
@ -26,6 +26,38 @@
|
||||
<string name="tag_ipv6" translatable="false">{{IPV6}}</string>
|
||||
<string name="tag_ip_list" translatable="false">{{IP_LIST}}</string>
|
||||
<string name="tag_net_type" translatable="false">{{NET_TYPE}}</string>
|
||||
<string name="tag_contact_name" translatable="false">{{CONTACT_NAME}}</string>
|
||||
<string name="tag_phone_area" translatable="false">{{PHONE_AREA}}</string>
|
||||
|
||||
<string name="insert_tag_from">来源号码</string>
|
||||
<string name="insert_tag_sms">短信内容</string>
|
||||
<string name="insert_tag_package_name">APP包名</string>
|
||||
<string name="insert_tag_app_name">APP应用名</string>
|
||||
<string name="insert_tag_title">通知标题</string>
|
||||
<string name="insert_tag_msg">通知内容</string>
|
||||
<string name="insert_tag_card_slot">卡槽备注</string>
|
||||
<string name="insert_tag_card_subid">卡槽主键</string>
|
||||
<string name="insert_tag_receive_time">接收时间</string>
|
||||
<string name="insert_tag_current_time">当前时间</string>
|
||||
<string name="insert_tag_device_name">设备名称</string>
|
||||
<string name="insert_tag_app_version">SmsF版本</string>
|
||||
<string name="insert_tag_call_type">通话类型</string>
|
||||
<string name="insert_tag_location">定位信息</string>
|
||||
<string name="insert_tag_location_longitude">定位经度</string>
|
||||
<string name="insert_tag_location_latitude">定位纬度</string>
|
||||
<string name="insert_tag_location_address">定位地址</string>
|
||||
<string name="insert_tag_battery_pct">电池电量</string>
|
||||
<string name="insert_tag_battery_status">电池状态</string>
|
||||
<string name="insert_tag_battery_plugged">充电方式</string>
|
||||
<string name="insert_tag_battery_info">电池完整信息</string>
|
||||
<string name="insert_tag_battery_info_simple">电池简单信息</string>
|
||||
<string name="insert_tag_uid">用户UID</string>
|
||||
<string name="insert_tag_ipv4">公网IPv4</string>
|
||||
<string name="insert_tag_ipv6">公网IPv6</string>
|
||||
<string name="insert_tag_ip_list">IP地址列表</string>
|
||||
<string name="insert_tag_net_type">网络状态</string>
|
||||
<string name="insert_tag_contact_name">来源姓名</string>
|
||||
<string name="insert_tag_phone_area">来源归属</string>
|
||||
|
||||
<string name="type_param_sms">短信</string>
|
||||
<string name="type_param_call">通话</string>
|
||||
@ -85,6 +117,7 @@
|
||||
<string name="url_help">https://gitee.com/pp/SmsForwarder/wikis/pages</string>
|
||||
<string name="url_donation_link">https://gitee.com/pp/SmsForwarder.wiki/raw/master/%E6%89%93%E8%B5%8F%E5%90%8D%E5%8D%95.md</string>
|
||||
<string name="url_wechat_miniprogram">https://gitee.com/pp/SmsForwarder/raw/main/pic/wechat_miniprogram.jpg</string>
|
||||
<string name="url_tips">https://gitee.com/pp/SmsForwarder.wiki/raw/master/tips.json</string>
|
||||
|
||||
<string name="lab_yes">是</string>
|
||||
<string name="lab_no">否</string>
|
||||
@ -214,6 +247,13 @@
|
||||
<string name="switch_rule_status">启用该条转发规则</string>
|
||||
<string name="invalid_match_value">匹配的值不可为空</string>
|
||||
<string name="invalid_call_type">通话类型不正确,只能填写1到6的任意一个数字</string>
|
||||
<string name="mon">周一</string>
|
||||
<string name="tue">周二</string>
|
||||
<string name="wed">周三</string>
|
||||
<string name="thu">周四</string>
|
||||
<string name="fri">周五</string>
|
||||
<string name="sat">周六</string>
|
||||
<string name="sun">周日</string>
|
||||
<!--SenderActivity-->
|
||||
<string name="delete_sender_title">发送通道操作确认</string>
|
||||
<string name="delete_sender_tips">删除发送通道后会级联删除其相关的转发规则、转发日志的所有记录!\n\n确定删除该条发送通道?</string>
|
||||
@ -243,8 +283,8 @@
|
||||
<string name="invalid_wework_agent">企业ID、AgentID、Secret都不能为空</string>
|
||||
<string name="invalid_dingtalk_inner_robot">AgentId、AppKey、AppSecret、UserIds都不能为空</string>
|
||||
<string name="invalid_phone_num">接收手机号不能为空</string>
|
||||
<string name="invalid_multi_match">多重匹配规则的第 %s 行格式有误</string>
|
||||
<string name="invalid_regex_replace">正则替换内容的第 %s 行格式有误</string>
|
||||
<string name="invalid_multi_match">多重匹配规则的第 %d 行格式有误</string>
|
||||
<string name="invalid_regex_replace">正则替换内容的第 %d 行格式有误</string>
|
||||
<string name="invalid_message_card">自定义消息卡片Json不合法</string>
|
||||
<string name="email_host">主机</string>
|
||||
<string name="smtp_port">端口</string>
|
||||
@ -299,6 +339,10 @@
|
||||
<string name="TelegramApiToken">ApiToken 或 自定义代理地址(http开头)</string>
|
||||
<string name="TelegramChatId">被通知人(或群组)的ChatId</string>
|
||||
<string name="Method" formatted="false">请求方式</string>
|
||||
<string name="parse_mode">解析模式</string>
|
||||
<string name="parse_mode_text">Text</string>
|
||||
<string name="parse_mode_html">Html</string>
|
||||
<string name="parse_mode_markdown">MarkdownV2</string>
|
||||
|
||||
<string name="SmsSimSlot">发送卡槽</string>
|
||||
<string name="same_source">原进原出</string>
|
||||
@ -338,17 +382,10 @@
|
||||
<string name="custom_template">转发信息模版</string>
|
||||
<string name="custom_template_tips">Tip:按需插入内容标签;留空使用默认模版</string>
|
||||
<string name="insert_sender">来源号码</string>
|
||||
<string name="insert_sender_app">APP包名</string>
|
||||
<string name="insert_uid">UID</string>
|
||||
<string name="insert_content">短信内容</string>
|
||||
<string name="insert_title_app">通知标题</string>
|
||||
<string name="insert_content_app">通知内容</string>
|
||||
<string name="insert_extra">卡槽信息</string>
|
||||
<string name="insert_time">接收时间</string>
|
||||
<string name="insert_device_name">设备名称</string>
|
||||
<string name="battery_setting">忽略电池优化设置</string>
|
||||
<string name="battery_setting_tips">请设置为手动管理:允许自启动、允许关联启动、允许后台运行</string>
|
||||
<string name="unknown_number">未知号码</string>
|
||||
<string name="unknown_area">未知归属地</string>
|
||||
<string name="unsupport">您的手机不支持此设置</string>
|
||||
<string name="isIgnored">已将省电优化设置为无限制(不优化)!</string>
|
||||
<string name="isIgnored2">本界面无法直接操作系统的省电优化设置</string>
|
||||
@ -385,6 +422,7 @@
|
||||
<string name="appicon">应用图标</string>
|
||||
<string name="user_app">用户应用</string>
|
||||
<string name="system_app">系统应用</string>
|
||||
<string name="tips_get_installed_apps">请先授予获取应用列表权限</string>
|
||||
<string name="tips_notification">请先授予发送通知权限,有利于《短信转发器》保活!</string>
|
||||
<string name="tips_notification_listener">请先授予《短信转发器》通知使用权,否则无法转发APP通知,已经自动关闭转发!</string>
|
||||
<string name="pushplus_website">官网地址</string>
|
||||
@ -431,6 +469,7 @@
|
||||
<string name="GotifyWebServer">WebServer</string>
|
||||
<string name="GotifyWebServerTips"><![CDATA[例:https://push.ppps.cn/message?token=<apptoken>]]></string>
|
||||
<string name="title_template">标题模板</string>
|
||||
<string name="auto_copy">自动复制</string>
|
||||
<string name="priority">优先级(1 – 9)</string>
|
||||
<string name="dingtalk_robot">钉钉群机器人</string>
|
||||
<string name="dingtalk_inner_robot">钉钉企业机器人</string>
|
||||
@ -474,7 +513,7 @@
|
||||
<string name="interval_label">递增间隔</string>
|
||||
<string name="timeout_label">单次超时</string>
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s秒</string>
|
||||
<string name="seconds_n">%d秒</string>
|
||||
<string name="retry_label">最多重试</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,该发送通道测试成功,请继续添加转发规则!</string>
|
||||
<string name="test_sender_name">测试通道</string>
|
||||
@ -540,7 +579,7 @@
|
||||
<string name="no">No</string>
|
||||
<string name="refresh">刷新</string>
|
||||
<string name="tip_can_not_get_sim_infos">无法获取卡槽信息,请确认应用权限【获取手机信息】为【始终允许】</string>
|
||||
<string name="tip_can_not_get_sim_info">未获取到卡槽%s中的SIM卡信息</string>
|
||||
<string name="tip_can_not_get_sim_info">未获取到卡槽%d中的SIM卡信息</string>
|
||||
<string name="auto_check">启动时检查</string>
|
||||
<string name="check_update">检查更新</string>
|
||||
<string name="join_preview_program">加入SmsF预览体验计划</string>
|
||||
@ -568,6 +607,7 @@
|
||||
<string name="bark_group_tips">可选,例:短信转发器</string>
|
||||
<string name="bark_icon">消息图标</string>
|
||||
<string name="bark_icon_tips">可选,填写Url,图片不要太大</string>
|
||||
<string name="bark_call">持续提醒</string>
|
||||
<string name="bark_sound">消息声音</string>
|
||||
<string name="bark_sound_tips">可选,例:minuet.caf</string>
|
||||
<string name="bark_badge">消息角标</string>
|
||||
@ -722,7 +762,7 @@
|
||||
<string name="api_location_tips">远程查询手机定位,方便找回手机/防止老少走丢</string>
|
||||
<string name="api_location_permission_tips">请先在【通用设置】中【启用GPS定位功能】</string>
|
||||
<string name="location_longitude">经度:%s</string>
|
||||
<string name="location_latitude">维度:%s</string>
|
||||
<string name="location_latitude">纬度:%s</string>
|
||||
<string name="location_address">地址:%s</string>
|
||||
<string name="location_time">时间:%s</string>
|
||||
<string name="location_provider">供应商:%s</string>
|
||||
@ -831,7 +871,7 @@
|
||||
<string name="debug_mode_tips">将Log.*写入文件,以便排查问题;可导出到下载目录</string>
|
||||
<string name="optional_components">可选组件:</string>
|
||||
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
|
||||
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
||||
<string name="enable_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
||||
<string name="load_app_list">启动时异步获取已安装App列表</string>
|
||||
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP_NAME}}</string>
|
||||
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
|
||||
@ -992,8 +1032,8 @@
|
||||
<string name="task_rule_tips">控制【转发规则】的启用/禁用</string>
|
||||
<string name="task_sender">启停通道</string>
|
||||
<string name="task_sender_tips">控制【发送通道】的启用/禁用</string>
|
||||
<string name="task_alarm">声音警报</string>
|
||||
<string name="task_alarm_tips">播放音乐提醒</string>
|
||||
<string name="task_alarm">警报提醒</string>
|
||||
<string name="task_alarm_tips">播放音乐/振动手机提醒</string>
|
||||
<string name="task_resend">重发消息</string>
|
||||
<string name="task_resend_tips">自动重发N小时以来的转发记录,0=全部</string>
|
||||
<string name="task_resend_desc" formatted="false">自动重发%s小时以来%s的转发记录</string>
|
||||
@ -1087,7 +1127,7 @@
|
||||
<string name="calc_type_distance">根据GPS坐标计算距离</string>
|
||||
<string name="calc_type_address">根据地址关键字判断</string>
|
||||
<string name="longitude">经度</string>
|
||||
<string name="latitude">维度</string>
|
||||
<string name="latitude">纬度</string>
|
||||
<string name="distance1">以经纬度为中心,</string>
|
||||
<string name="distance2">米半径建立电子围栏</string>
|
||||
<string name="current_coordinates">当前坐标</string>
|
||||
@ -1143,11 +1183,24 @@
|
||||
|
||||
<string name="start_alarm">启动警报</string>
|
||||
<string name="stop_alarm">停止警报</string>
|
||||
<string name="alarm_play_settings">播放设置</string>
|
||||
<string name="alarm_play_settings">播放音乐</string>
|
||||
<string name="alarm_music">指定音乐</string>
|
||||
<string name="alarm_music_tips">可选,下载 mp3/ogg/wav 到 Download 目录</string>
|
||||
<string name="alarm_volume">播放音量</string>
|
||||
<string name="alarm_play_times">播放次数(0=无限)</string>
|
||||
<string name="alarm_vibrate_settings">振动手机</string>
|
||||
<string name="alarm_repeat_times">重复次数(0=无限)</string>
|
||||
<string name="alarm_vibration_effect">振动效果</string>
|
||||
<string name="alarm_vibration_effect_tips">语法:=[强振动], -[弱震动], _[不振动], 每次100ms</string>
|
||||
<string name="alarm_vibration_effect_1">强振动 100ms</string>
|
||||
<string name="alarm_vibration_effect_2">弱振动 100ms</string>
|
||||
<string name="alarm_vibration_effect_3">不振动 100ms</string>
|
||||
<string name="alarm_flash_settings">闪烁手机</string>
|
||||
<string name="alarm_flash_effect">闪光效果</string>
|
||||
<string name="alarm_flash_effect_tips">语法:1或X[开启闪光灯], 0或O[关闭闪光灯], 每次100ms</string>
|
||||
<string name="alarm_flash_effect_1">开启闪光灯 100ms</string>
|
||||
<string name="alarm_flash_effect_2">关闭闪光灯 100ms</string>
|
||||
<string name="alarm_settings_error">播放音乐/振动手机/闪烁手机必须至少开启一个</string>
|
||||
|
||||
<string name="invalid_tag" formatted="false">%s 标签无效:%s</string>
|
||||
<string name="invalid_task_name">请输入任务名称</string>
|
||||
@ -1170,4 +1223,5 @@
|
||||
<string name="bluetooth_not_supported">不支持蓝牙设备</string>
|
||||
<string name="start_discovery">搜索设备</string>
|
||||
<string name="invalid_bluetooth_mac_address">蓝牙设备MAC地址无效,例如:AA:BB:CC:DD:EE:FF</string>
|
||||
<string name="auto_start_redmi"><![CDATA[红米手机:授权管理 -> 自启动管理 -> 允许应用自启动]]></string>
|
||||
</resources>
|
||||
|
@ -6,7 +6,7 @@
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
|
BIN
pic/sponsor.gif
Normal file
BIN
pic/sponsor.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
@ -2,8 +2,8 @@ import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
def build_versions = [:]
|
||||
build_versions.version_code = 53
|
||||
build_versions.version_name = "3.3.2"
|
||||
build_versions.version_code = 54
|
||||
build_versions.version_name = "3.3.3"
|
||||
build_versions.min_sdk = 19
|
||||
build_versions.target_sdk = 33
|
||||
build_versions.build_tools = "33.0.1"
|
||||
@ -38,13 +38,13 @@ versions.kotlin = '1.7.21'
|
||||
|
||||
//========xlibrary start========//
|
||||
|
||||
versions.xui = "dev~1.2.2-SNAPSHOT"
|
||||
versions.xui = "1.2.2_250201"
|
||||
versions.xupdate = "2.1.5"
|
||||
versions.xaop = "dab6b77b2f" //1.1.0
|
||||
versions.xaop = "1.1.0"
|
||||
versions.xutil = "2.0.0"
|
||||
versions.xhttp2 = "9115cfcd5a" //2.0.9
|
||||
versions.xhttp2 = "2.0.10"
|
||||
versions.xpage = "3.3.0"
|
||||
versions.xrouter = "1.0.1"
|
||||
versions.xrouter = "1.1.0"
|
||||
|
||||
//========xlibrary end========//
|
||||
|
||||
@ -132,18 +132,18 @@ deps.leakcanary = "com.squareup.leakcanary:leakcanary-android:$versions.leakcana
|
||||
|
||||
def xlibrary = [:]
|
||||
|
||||
xlibrary.xui = "com.github.pppscn:XUI:$versions.xui" //com.github.xuexiangjys:XUI
|
||||
xlibrary.xupdate = "com.github.xuexiangjys:XUpdate:$versions.xupdate"
|
||||
xlibrary.xaop_runtime = "com.github.pppscn.XAOP:xaop-runtime:$versions.xaop" //com.github.xuexiangjys.XAOP
|
||||
xlibrary.xaop_plugin = "com.github.pppscn.XAOP:xaop-plugin:$versions.xaop" //com.github.xuexiangjys.XAOP
|
||||
xlibrary.xutil_core = "com.github.xuexiangjys.XUtil:xutil-core:$versions.xutil"
|
||||
xlibrary.xutil_sub = "com.github.xuexiangjys.XUtil:xutil-sub:$versions.xutil"
|
||||
xlibrary.xhttp2 = "com.github.pppscn:XHttp2:$versions.xhttp2" //com.github.xuexiangjys:XHttp2
|
||||
xlibrary.xpage_lib = "com.github.xuexiangjys.XPage:xpage-lib:$versions.xpage"
|
||||
xlibrary.xpage_compiler = "com.github.xuexiangjys.XPage:xpage-compiler:$versions.xpage"
|
||||
xlibrary.xrouter_runtime = "com.github.xuexiangjys.XRouter:xrouter-runtime:$versions.xrouter"
|
||||
xlibrary.xrouter_compiler = "com.github.xuexiangjys.XRouter:xrouter-compiler:$versions.xrouter"
|
||||
xlibrary.xrouter_plugin = "com.github.xuexiangjys.XRouter:xrouter-plugin:$versions.xrouter"
|
||||
xlibrary.xui = "com.github.pppscn:XUI:$versions.xui"
|
||||
xlibrary.xupdate = "com.github.pppscn:XUpdate:$versions.xupdate"
|
||||
xlibrary.xaop_runtime = "com.github.pppscn.XAOP:xaop-runtime:$versions.xaop"
|
||||
xlibrary.xaop_plugin = "com.github.pppscn.XAOP:xaop-plugin:$versions.xaop"
|
||||
xlibrary.xutil_core = "com.github.pppscn.XUtil:xutil-core:$versions.xutil"
|
||||
xlibrary.xutil_sub = "com.github.pppscn.XUtil:xutil-sub:$versions.xutil"
|
||||
xlibrary.xhttp2 = "com.github.pppscn:XHttp2:$versions.xhttp2"
|
||||
xlibrary.xpage_lib = "com.github.pppscn.XPage:xpage-lib:$versions.xpage"
|
||||
xlibrary.xpage_compiler = "com.github.pppscn.XPage:xpage-compiler:$versions.xpage"
|
||||
xlibrary.xrouter_runtime = "com.github.pppscn.XRouter:xrouter-runtime:$versions.xrouter"
|
||||
xlibrary.xrouter_compiler = "com.github.pppscn.XRouter:xrouter-compiler:$versions.xrouter"
|
||||
xlibrary.xrouter_plugin = "com.github.pppscn.XRouter:xrouter-plugin:$versions.xrouter"
|
||||
|
||||
deps.xlibrary = xlibrary
|
||||
|
||||
@ -219,4 +219,4 @@ project.buildscript.configurations.each { configuration ->
|
||||
//kotlin插件
|
||||
configuration.dependencies.add(dependencies.create("org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user