mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 01:17:41 +08:00
parent
5741cdfe96
commit
3dd2e41123
@ -112,12 +112,12 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//启动前台服务
|
//启动前台服务
|
||||||
Intent(this, ForegroundService::class.java).also {
|
val serviceIntent = Intent(this, ForegroundService::class.java)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
serviceIntent.action = "START"
|
||||||
startForegroundService(it)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
} else {
|
startForegroundService(serviceIntent)
|
||||||
startService(it)
|
} else {
|
||||||
}
|
startService(serviceIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
//网络状态监听
|
//网络状态监听
|
||||||
|
@ -104,12 +104,12 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
|
|
||||||
//启动前台服务
|
//启动前台服务
|
||||||
if (!ForegroundService.isRunning) {
|
if (!ForegroundService.isRunning) {
|
||||||
Intent(this, ForegroundService::class.java).also {
|
val serviceIntent = Intent(this, ForegroundService::class.java)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
serviceIntent.action = "START"
|
||||||
startForegroundService(it)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
} else {
|
startForegroundService(serviceIntent)
|
||||||
startService(it)
|
} else {
|
||||||
}
|
startService(serviceIntent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -204,6 +204,7 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.nav_app_list -> openNewPage(AppListFragment::class.java)
|
R.id.nav_app_list -> openNewPage(AppListFragment::class.java)
|
||||||
//R.id.nav_logcat -> openNewPage(LogcatFragment::class.java)
|
//R.id.nav_logcat -> openNewPage(LogcatFragment::class.java)
|
||||||
R.id.nav_help -> AgentWebActivity.goWeb(this, getString(R.string.url_help))
|
R.id.nav_help -> AgentWebActivity.goWeb(this, getString(R.string.url_help))
|
||||||
@ -232,12 +233,15 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
getString(R.string.menu_rules) -> binding!!.includeMain.toolbar.inflateMenu(
|
getString(R.string.menu_rules) -> binding!!.includeMain.toolbar.inflateMenu(
|
||||||
R.menu.menu_rules
|
R.menu.menu_rules
|
||||||
)
|
)
|
||||||
|
|
||||||
getString(R.string.menu_senders) -> binding!!.includeMain.toolbar.inflateMenu(
|
getString(R.string.menu_senders) -> binding!!.includeMain.toolbar.inflateMenu(
|
||||||
R.menu.menu_senders
|
R.menu.menu_senders
|
||||||
)
|
)
|
||||||
|
|
||||||
getString(R.string.menu_settings) -> binding!!.includeMain.toolbar.inflateMenu(
|
getString(R.string.menu_settings) -> binding!!.includeMain.toolbar.inflateMenu(
|
||||||
R.menu.menu_settings
|
R.menu.menu_settings
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> binding!!.includeMain.toolbar.inflateMenu(R.menu.menu_logs)
|
else -> binding!!.includeMain.toolbar.inflateMenu(R.menu.menu_logs)
|
||||||
}
|
}
|
||||||
item.isChecked = true
|
item.isChecked = true
|
||||||
@ -255,13 +259,6 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
LiveEventBus.get(EVENT_UPDATE_RULE_TYPE, String::class.java).observe(this) { type: String ->
|
LiveEventBus.get(EVENT_UPDATE_RULE_TYPE, String::class.java).observe(this) { type: String ->
|
||||||
ruleType = type
|
ruleType = type
|
||||||
}
|
}
|
||||||
|
|
||||||
//更新通知栏文案
|
|
||||||
LiveEventBus.get(EVENT_UPDATE_NOTIFY, String::class.java).observe(this) { notify: String ->
|
|
||||||
cactusUpdateNotification {
|
|
||||||
setContent(notify)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,6 +284,7 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
R.id.action_notifications -> {
|
R.id.action_notifications -> {
|
||||||
showTipsForce(this)
|
showTipsForce(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_clear_logs -> {
|
R.id.action_clear_logs -> {
|
||||||
MaterialDialog.Builder(this)
|
MaterialDialog.Builder(this)
|
||||||
.content(R.string.delete_type_log_tips)
|
.content(R.string.delete_type_log_tips)
|
||||||
@ -311,6 +309,7 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_add_sender -> {
|
R.id.action_add_sender -> {
|
||||||
val dialog = BottomSheetDialog(this)
|
val dialog = BottomSheetDialog(this)
|
||||||
val view: View =
|
val view: View =
|
||||||
@ -328,6 +327,7 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
|
|||||||
dialog.show()
|
dialog.show()
|
||||||
WidgetUtils.transparentBottomSheetDialogBackground(dialog)
|
WidgetUtils.transparentBottomSheetDialogBackground(dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_add_rule -> {
|
R.id.action_add_rule -> {
|
||||||
PageOption.to(RulesEditFragment::class.java)
|
PageOption.to(RulesEditFragment::class.java)
|
||||||
.putString(KEY_RULE_TYPE, ruleType)
|
.putString(KEY_RULE_TYPE, ruleType)
|
||||||
|
@ -19,28 +19,6 @@ object Core : Configuration.Provider {
|
|||||||
val logs: LogsRepository by lazy { (app as App).logsRepository }
|
val logs: LogsRepository by lazy { (app as App).logsRepository }
|
||||||
val rule: RuleRepository by lazy { (app as App).ruleRepository }
|
val rule: RuleRepository by lazy { (app as App).ruleRepository }
|
||||||
val sender: SenderRepository by lazy { (app as App).senderRepository }
|
val sender: SenderRepository by lazy { (app as App).senderRepository }
|
||||||
/*
|
|
||||||
val telephonyManager: TelephonyManager by lazy { app.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager }
|
|
||||||
val smsManager: SmsManager by lazy { app.getSystemService(SmsManager::class.java) }
|
|
||||||
val subscriptionManager: SubscriptionManager by lazy {
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
|
||||||
SubscriptionManager.from(app)
|
|
||||||
} else {
|
|
||||||
app.getSystemService(SubscriptionManager::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val user by lazy { app.getSystemService<UserManager>()!! }*/
|
|
||||||
|
|
||||||
|
|
||||||
/*val directBootAware: Boolean get() = directBootSupported && dataStore.canToggleLocked
|
|
||||||
val directBootSupported by lazy {
|
|
||||||
Build.VERSION.SDK_INT >= 24 && try {
|
|
||||||
app.getSystemService<DevicePolicyManager>()?.storageEncryptionStatus ==
|
|
||||||
DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER
|
|
||||||
} catch (_: RuntimeException) {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
fun init(app: Application) {
|
fun init(app: Application) {
|
||||||
this.app = app
|
this.app = app
|
||||||
@ -54,6 +32,4 @@ object Core : Configuration.Provider {
|
|||||||
setTaskExecutor { (app as App).applicationScope.launch { it.run() } }
|
setTaskExecutor { (app as App).applicationScope.launch { it.run() } }
|
||||||
}.build()
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startService() = ContextCompat.startForegroundService(app, Intent(app, ForegroundService::class.java))
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.util.Log
|
|||||||
import com.idormy.sms.forwarder.App
|
import com.idormy.sms.forwarder.App
|
||||||
import com.idormy.sms.forwarder.R
|
import com.idormy.sms.forwarder.R
|
||||||
import com.idormy.sms.forwarder.utils.CALL_TYPE_MAP
|
import com.idormy.sms.forwarder.utils.CALL_TYPE_MAP
|
||||||
|
import com.idormy.sms.forwarder.utils.HttpServerUtils
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.enableSmsTemplate
|
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.enableSmsTemplate
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.extraDeviceMark
|
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.extraDeviceMark
|
||||||
@ -58,7 +59,7 @@ data class MsgInfo(
|
|||||||
.replace(getString(R.string.tag_app_version), versionName)
|
.replace(getString(R.string.tag_app_version), versionName)
|
||||||
.replace(getString(R.string.tag_call_type), CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call))
|
.replace(getString(R.string.tag_call_type), CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call))
|
||||||
.trim()
|
.trim()
|
||||||
return replaceAppName(regexReplace(titleForSend, regexReplace), from)
|
return replaceLocationTag(replaceAppName(regexReplace(titleForSend, regexReplace), from))
|
||||||
}
|
}
|
||||||
|
|
||||||
val smsVoForSend: String
|
val smsVoForSend: String
|
||||||
@ -106,7 +107,7 @@ data class MsgInfo(
|
|||||||
.replace(getString(R.string.tag_app_version), versionName)
|
.replace(getString(R.string.tag_app_version), versionName)
|
||||||
.replace(getString(R.string.tag_call_type), CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call))
|
.replace(getString(R.string.tag_call_type), CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call))
|
||||||
.trim()
|
.trim()
|
||||||
return replaceAppName(regexReplace(smsVoForSend, regexReplace), from)
|
return replaceLocationTag(replaceAppName(regexReplace(smsVoForSend, regexReplace), from))
|
||||||
}
|
}
|
||||||
|
|
||||||
//正则替换内容
|
//正则替换内容
|
||||||
@ -154,6 +155,15 @@ data class MsgInfo(
|
|||||||
return content.replace(getString(R.string.tag_app_name), appName)
|
return content.replace(getString(R.string.tag_app_name), appName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//替换 {{定位信息}} 标签
|
||||||
|
private fun replaceLocationTag(content: String): String {
|
||||||
|
if (TextUtils.isEmpty(content)) return content
|
||||||
|
if (content.indexOf(getString(R.string.tag_location)) == -1) return content
|
||||||
|
|
||||||
|
val location = HttpServerUtils.apiLocationCache.toString()
|
||||||
|
return content.replace(getString(R.string.tag_location), location)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "MsgInfo{" +
|
return "MsgInfo{" +
|
||||||
"mobile='" + from + '\'' +
|
"mobile='" + from + '\'' +
|
||||||
|
@ -138,12 +138,12 @@ class FrpcFragment : BaseFragment<FragmentFrpcsBinding?>(), FrpcPagingAdapter.On
|
|||||||
|
|
||||||
R.id.iv_play -> {
|
R.id.iv_play -> {
|
||||||
if (!ForegroundService.isRunning) {
|
if (!ForegroundService.isRunning) {
|
||||||
Intent(requireContext(), ForegroundService::class.java).also {
|
val serviceIntent = Intent(requireContext(), ForegroundService::class.java)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
serviceIntent.action = "START"
|
||||||
requireContext().startForegroundService(it)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
} else {
|
requireContext().startForegroundService(serviceIntent)
|
||||||
requireContext().startService(it)
|
} else {
|
||||||
}
|
requireContext().startService(serviceIntent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//联系人权限
|
//定位权限
|
||||||
private fun checkLocationPermission() {
|
private fun checkLocationPermission() {
|
||||||
XXPermissions.with(this).permission(Permission.ACCESS_COARSE_LOCATION).permission(Permission.ACCESS_FINE_LOCATION).permission(Permission.ACCESS_BACKGROUND_LOCATION).request(object : OnPermissionCallback {
|
XXPermissions.with(this).permission(Permission.ACCESS_COARSE_LOCATION).permission(Permission.ACCESS_FINE_LOCATION).permission(Permission.ACCESS_BACKGROUND_LOCATION).request(object : OnPermissionCallback {
|
||||||
override fun onGranted(permissions: List<String>, all: Boolean) {
|
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||||
|
@ -18,6 +18,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.work.OneTimeWorkRequestBuilder
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
@ -32,6 +33,7 @@ import com.idormy.sms.forwarder.core.BaseFragment
|
|||||||
import com.idormy.sms.forwarder.databinding.FragmentSettingsBinding
|
import com.idormy.sms.forwarder.databinding.FragmentSettingsBinding
|
||||||
import com.idormy.sms.forwarder.entity.SimInfo
|
import com.idormy.sms.forwarder.entity.SimInfo
|
||||||
import com.idormy.sms.forwarder.receiver.BootReceiver
|
import com.idormy.sms.forwarder.receiver.BootReceiver
|
||||||
|
import com.idormy.sms.forwarder.service.ForegroundService
|
||||||
import com.idormy.sms.forwarder.utils.*
|
import com.idormy.sms.forwarder.utils.*
|
||||||
import com.idormy.sms.forwarder.workers.LoadAppListWorker
|
import com.idormy.sms.forwarder.workers.LoadAppListWorker
|
||||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||||
@ -172,6 +174,9 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
|
|
||||||
//纯客户端模式
|
//纯客户端模式
|
||||||
switchDirectlyToClient(binding!!.sbDirectlyToClient)
|
switchDirectlyToClient(binding!!.sbDirectlyToClient)
|
||||||
|
|
||||||
|
//启用 {{定位信息}} 标签
|
||||||
|
switchEnableLocationTag(binding!!.sbEnableLocationTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -918,21 +923,25 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||||
override fun afterTextChanged(s: Editable) {
|
override fun afterTextChanged(s: Editable) {
|
||||||
SettingUtils.notifyContent = etNotifyContent.text.toString().trim()
|
val notifyContent = etNotifyContent.text.toString().trim()
|
||||||
LiveEventBus.get(EVENT_UPDATE_NOTIFY, String::class.java).post(SettingUtils.notifyContent)
|
SettingUtils.notifyContent = notifyContent
|
||||||
|
val updateIntent = Intent(context, ForegroundService::class.java)
|
||||||
|
updateIntent.action = "UPDATE_NOTIFICATION"
|
||||||
|
updateIntent.putExtra("UPDATED_CONTENT", notifyContent)
|
||||||
|
context?.let { ContextCompat.startForegroundService(it, updateIntent) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置转发时启用自定义模版
|
//设置转发时启用自定义模版
|
||||||
@SuppressLint("UseSwitchCompatOrMaterialCode", "SetTextI18n")
|
@SuppressLint("UseSwitchCompatOrMaterialCode", "SetTextI18n")
|
||||||
fun switchSmsTemplate(sb_sms_template: SwitchButton) {
|
fun switchSmsTemplate(sbSmsTemplate: SwitchButton) {
|
||||||
val isOn: Boolean = SettingUtils.enableSmsTemplate
|
val isOn: Boolean = SettingUtils.enableSmsTemplate
|
||||||
sb_sms_template.isChecked = isOn
|
sbSmsTemplate.isChecked = isOn
|
||||||
val layoutSmsTemplate: LinearLayout = binding!!.layoutSmsTemplate
|
val layoutSmsTemplate: LinearLayout = binding!!.layoutSmsTemplate
|
||||||
layoutSmsTemplate.visibility = if (isOn) View.VISIBLE else View.GONE
|
layoutSmsTemplate.visibility = if (isOn) View.VISIBLE else View.GONE
|
||||||
val etSmsTemplate: EditText = binding!!.etSmsTemplate
|
val etSmsTemplate: EditText = binding!!.etSmsTemplate
|
||||||
sb_sms_template.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
|
sbSmsTemplate.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
|
||||||
layoutSmsTemplate.visibility = if (isChecked) View.VISIBLE else View.GONE
|
layoutSmsTemplate.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||||
SettingUtils.enableSmsTemplate = isChecked
|
SettingUtils.enableSmsTemplate = isChecked
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
@ -983,6 +992,40 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//启用 {{定位信息}} 标签
|
||||||
|
private fun switchEnableLocationTag(@SuppressLint("UseSwitchCompatOrMaterialCode") switchEnableLocationTag: SwitchButton) {
|
||||||
|
switchEnableLocationTag.isChecked = SettingUtils.enableLocationTag
|
||||||
|
switchEnableLocationTag.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
|
||||||
|
SettingUtils.enableLocationTag = isChecked
|
||||||
|
if (isChecked) {
|
||||||
|
XXPermissions.with(this).permission(Permission.ACCESS_COARSE_LOCATION).permission(Permission.ACCESS_FINE_LOCATION).permission(Permission.ACCESS_BACKGROUND_LOCATION).request(object : OnPermissionCallback {
|
||||||
|
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||||
|
//重启前台服务
|
||||||
|
val serviceIntent = Intent(requireContext(), ForegroundService::class.java)
|
||||||
|
serviceIntent.action = "START"
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
requireContext().startForegroundService(serviceIntent)
|
||||||
|
} else {
|
||||||
|
requireContext().startService(serviceIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDenied(permissions: List<String>, never: Boolean) {
|
||||||
|
if (never) {
|
||||||
|
XToastUtils.error(R.string.toast_denied_never)
|
||||||
|
// 如果是被永久拒绝就跳转到应用权限系统设置页面
|
||||||
|
XXPermissions.startPermissionActivity(requireContext(), permissions)
|
||||||
|
} else {
|
||||||
|
XToastUtils.error(R.string.toast_denied)
|
||||||
|
}
|
||||||
|
SettingUtils.enableLocationTag = false
|
||||||
|
switchEnableLocationTag.isChecked = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//获取当前手机品牌
|
//获取当前手机品牌
|
||||||
private fun getAutoStartTips(): String {
|
private fun getAutoStartTips(): String {
|
||||||
return when (Build.BRAND.lowercase(Locale.ROOT)) {
|
return when (Build.BRAND.lowercase(Locale.ROOT)) {
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package com.idormy.sms.forwarder.service
|
package com.idormy.sms.forwarder.service
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.*
|
import android.app.*
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.location.Criteria
|
||||||
|
import android.location.Geocoder
|
||||||
|
import android.location.Location
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
@ -16,9 +20,14 @@ import com.idormy.sms.forwarder.App
|
|||||||
import com.idormy.sms.forwarder.R
|
import com.idormy.sms.forwarder.R
|
||||||
import com.idormy.sms.forwarder.activity.MainActivity
|
import com.idormy.sms.forwarder.activity.MainActivity
|
||||||
import com.idormy.sms.forwarder.database.AppDatabase
|
import com.idormy.sms.forwarder.database.AppDatabase
|
||||||
|
import com.idormy.sms.forwarder.entity.LocationInfo
|
||||||
import com.idormy.sms.forwarder.utils.*
|
import com.idormy.sms.forwarder.utils.*
|
||||||
import com.idormy.sms.forwarder.workers.LoadAppListWorker
|
import com.idormy.sms.forwarder.workers.LoadAppListWorker
|
||||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||||
|
import com.king.location.LocationClient
|
||||||
|
import com.king.location.LocationErrorCode
|
||||||
|
import com.king.location.OnExceptionListener
|
||||||
|
import com.king.location.OnLocationListener
|
||||||
import com.xuexiang.xutil.XUtil
|
import com.xuexiang.xutil.XUtil
|
||||||
import com.xuexiang.xutil.file.FileUtils
|
import com.xuexiang.xutil.file.FileUtils
|
||||||
import frpclib.Frpclib
|
import frpclib.Frpclib
|
||||||
@ -31,45 +40,48 @@ import io.reactivex.schedulers.Schedulers
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
@SuppressLint("SimpleDateFormat")
|
||||||
@Suppress("PrivatePropertyName", "DeferredResultUnused", "OPT_IN_USAGE", "DEPRECATION")
|
@Suppress("PrivatePropertyName", "DeferredResultUnused", "OPT_IN_USAGE", "DEPRECATION")
|
||||||
class ForegroundService : Service() {
|
class ForegroundService : Service() {
|
||||||
|
|
||||||
private val TAG: String = "ForegroundService"
|
private val TAG: String = "ForegroundService"
|
||||||
|
private var notificationManager: NotificationManager? = null
|
||||||
|
|
||||||
private val compositeDisposable = CompositeDisposable()
|
private val compositeDisposable = CompositeDisposable()
|
||||||
private val frpcObserver = Observer { uid: String ->
|
private val frpcObserver = Observer { uid: String ->
|
||||||
if (Frpclib.isRunning(uid)) {
|
if (Frpclib.isRunning(uid)) {
|
||||||
return@Observer
|
return@Observer
|
||||||
}
|
}
|
||||||
AppDatabase.getInstance(App.context)
|
AppDatabase.getInstance(App.context).frpcDao().get(uid).flatMap { (uid1, _, config) ->
|
||||||
.frpcDao()
|
val error = Frpclib.runContent(uid1, config)
|
||||||
.get(uid)
|
Single.just(error)
|
||||||
.flatMap { (uid1, _, config) ->
|
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<String> {
|
||||||
val error = Frpclib.runContent(uid1, config)
|
override fun onSubscribe(d: Disposable) {
|
||||||
Single.just(error)
|
compositeDisposable.add(d)
|
||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : SingleObserver<String> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
compositeDisposable.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess(msg: String) {
|
||||||
|
if (!TextUtils.isEmpty(msg)) {
|
||||||
|
Log.e(TAG, msg)
|
||||||
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
|
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
|
||||||
|
} else {
|
||||||
|
LiveEventBus.get(EVENT_FRPC_RUNNING_SUCCESS, String::class.java).post(uid)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
override fun onSuccess(msg: String) {
|
})
|
||||||
if (!TextUtils.isEmpty(msg)) {
|
|
||||||
Log.e(TAG, msg)
|
|
||||||
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
|
|
||||||
} else {
|
|
||||||
LiveEventBus.get(EVENT_FRPC_RUNNING_SUCCESS, String::class.java).post(uid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
private var notificationManager: NotificationManager? = null
|
|
||||||
|
private val locationClient by lazy { LocationClient(App.context) }
|
||||||
|
private val geocoder by lazy { Geocoder(App.context) }
|
||||||
|
private val simpleDateFormat by lazy { SimpleDateFormat("yyyy-MM-dd HH:mm:ss") }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var isRunning = false
|
var isRunning = false
|
||||||
@ -78,13 +90,52 @@ class ForegroundService : Service() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
|
//纯客户端模式
|
||||||
|
if (SettingUtils.enablePureClientMode) return
|
||||||
|
|
||||||
|
createNotificationChannel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
|
||||||
|
//纯客户端模式
|
||||||
|
if (SettingUtils.enablePureClientMode) return START_STICKY
|
||||||
|
|
||||||
|
if (intent != null) {
|
||||||
|
when (intent.action) {
|
||||||
|
"START" -> {
|
||||||
|
startForegroundService()
|
||||||
|
}
|
||||||
|
|
||||||
|
"STOP" -> {
|
||||||
|
stopForegroundService()
|
||||||
|
}
|
||||||
|
|
||||||
|
"UPDATE_NOTIFICATION" -> {
|
||||||
|
val updatedContent = intent.getStringExtra("UPDATED_CONTENT")
|
||||||
|
updateNotification(updatedContent ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return START_STICKY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
//非纯客户端模式
|
||||||
|
if (!SettingUtils.enablePureClientMode) stopForegroundService()
|
||||||
|
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent): IBinder? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startForegroundService() {
|
||||||
|
val notification = createNotification(SettingUtils.notifyContent)
|
||||||
|
startForeground(NOTIFICATION_ID, notification)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//纯客户端模式
|
|
||||||
if (SettingUtils.enablePureClientMode) return
|
|
||||||
|
|
||||||
notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
startForeground(FRONT_NOTIFY_ID, createForegroundNotification())
|
|
||||||
|
|
||||||
//开关通知监听服务
|
//开关通知监听服务
|
||||||
if (SettingUtils.enableAppNotify && CommonUtils.isNotificationListenerServiceEnabled(this)) {
|
if (SettingUtils.enableAppNotify && CommonUtils.isNotificationListenerServiceEnabled(this)) {
|
||||||
CommonUtils.toggleNotificationListenerService(this)
|
CommonUtils.toggleNotificationListenerService(this)
|
||||||
@ -96,6 +147,7 @@ class ForegroundService : Service() {
|
|||||||
WorkManager.getInstance(XUtil.getContext()).enqueue(request)
|
WorkManager.getInstance(XUtil.getContext()).enqueue(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//启动 Frpc
|
||||||
if (FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so")) {
|
if (FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so")) {
|
||||||
//监听Frpc启动指令
|
//监听Frpc启动指令
|
||||||
LiveEventBus.get(INTENT_FRPC_APPLY_FILE, String::class.java).observeStickyForever(frpcObserver)
|
LiveEventBus.get(INTENT_FRPC_APPLY_FILE, String::class.java).observeStickyForever(frpcObserver)
|
||||||
@ -117,6 +169,65 @@ class ForegroundService : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//远程找手机
|
||||||
|
if (SettingUtils.enableLocationTag || HttpServerUtils.enableApiLocation) {
|
||||||
|
//可根据具体需求设置定位配置参数(这里只列出一些主要的参数)
|
||||||
|
val locationOption = locationClient.getLocationOption().setAccuracy(Criteria.ACCURACY_FINE)//设置位置精度:高精度
|
||||||
|
.setPowerRequirement(Criteria.POWER_LOW) //设置电量消耗:低电耗
|
||||||
|
.setMinTime(10000)//设置位置更新最小时间间隔(单位:毫秒); 默认间隔:10000毫秒,最小间隔:1000毫秒
|
||||||
|
.setMinDistance(0)//设置位置更新最小距离(单位:米);默认距离:0米
|
||||||
|
.setOnceLocation(false)//设置是否只定位一次,默认为 false,当设置为 true 时,则只定位一次后,会自动停止定位
|
||||||
|
.setLastKnownLocation(false)//设置是否获取最后一次缓存的已知位置,默认为 true
|
||||||
|
//设置定位配置参数
|
||||||
|
locationClient.setLocationOption(locationOption)
|
||||||
|
locationClient.startLocation()
|
||||||
|
|
||||||
|
//设置定位监听
|
||||||
|
locationClient.setOnLocationListener(object : OnLocationListener() {
|
||||||
|
override fun onLocationChanged(location: Location) {
|
||||||
|
//位置信息
|
||||||
|
Log.d(TAG, "onLocationChanged(location = ${location})")
|
||||||
|
|
||||||
|
val locationInfo = LocationInfo(
|
||||||
|
location.longitude, location.latitude, "", simpleDateFormat.format(Date(location.time)), location.provider.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
//根据坐标经纬度获取位置地址信息(WGS-84坐标系)
|
||||||
|
val list = geocoder.getFromLocation(location.latitude, location.longitude, 1)
|
||||||
|
if (list?.isNotEmpty() == true) {
|
||||||
|
locationInfo.address = list[0].getAddressLine(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "locationInfo = $locationInfo")
|
||||||
|
HttpServerUtils.apiLocationCache = locationInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProviderEnabled(provider: String) {
|
||||||
|
super.onProviderEnabled(provider)
|
||||||
|
Log.d(TAG, "onProviderEnabled(provider = ${provider})")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProviderDisabled(provider: String) {
|
||||||
|
super.onProviderDisabled(provider)
|
||||||
|
Log.d(TAG, "onProviderDisabled(provider = ${provider})")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
//设置异常监听
|
||||||
|
locationClient.setOnExceptionListener(object : OnExceptionListener {
|
||||||
|
override fun onException(@LocationErrorCode errorCode: Int, e: Exception) {
|
||||||
|
//定位出现异常
|
||||||
|
Log.w(TAG, "onException(errorCode = ${errorCode}, e = ${e})")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (locationClient.isStarted()) {//如果已经开始定位,则先停止定位
|
||||||
|
locationClient.stopLocation()
|
||||||
|
}
|
||||||
|
locationClient.startLocation()
|
||||||
|
}
|
||||||
|
|
||||||
isRunning = true
|
isRunning = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@ -125,34 +236,25 @@ class ForegroundService : Service() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
private fun stopForegroundService() {
|
||||||
isRunning = true
|
|
||||||
return START_STICKY
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
//纯客户端模式
|
|
||||||
if (SettingUtils.enablePureClientMode) {
|
|
||||||
super.onDestroy()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
//如果已经开始定位,则先停止定位
|
||||||
|
if (HttpServerUtils.enableApiLocation && locationClient.isStarted()) {
|
||||||
|
locationClient.stopLocation()
|
||||||
|
}
|
||||||
|
|
||||||
stopForeground(true)
|
stopForeground(true)
|
||||||
|
stopSelf()
|
||||||
compositeDisposable.dispose()
|
compositeDisposable.dispose()
|
||||||
isRunning = false
|
isRunning = false
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
isRunning = true
|
||||||
}
|
}
|
||||||
super.onDestroy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder? {
|
private fun createNotificationChannel() {
|
||||||
return null
|
notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||||
}
|
|
||||||
|
|
||||||
private fun createForegroundNotification(): Notification {
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val importance = NotificationManager.IMPORTANCE_HIGH
|
val importance = NotificationManager.IMPORTANCE_HIGH
|
||||||
val notificationChannel = NotificationChannel(FRONT_CHANNEL_ID, FRONT_CHANNEL_NAME, importance)
|
val notificationChannel = NotificationChannel(FRONT_CHANNEL_ID, FRONT_CHANNEL_NAME, importance)
|
||||||
@ -165,20 +267,19 @@ class ForegroundService : Service() {
|
|||||||
notificationManager!!.createNotificationChannel(notificationChannel)
|
notificationManager!!.createNotificationChannel(notificationChannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val builder = NotificationCompat.Builder(this, FRONT_CHANNEL_ID)
|
}
|
||||||
builder.setSmallIcon(R.drawable.ic_forwarder)
|
|
||||||
builder.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_menu_frpc))
|
private fun createNotification(content: String): Notification {
|
||||||
// TODO: 部分机型标题会重复待排除
|
val notificationIntent = Intent(this, MainActivity::class.java)
|
||||||
// if (DeviceUtils.getDeviceBrand().contains("Xiaomi")) {
|
|
||||||
builder.setContentTitle(getString(R.string.app_name))
|
|
||||||
//}
|
|
||||||
builder.setContentText(SettingUtils.notifyContent)
|
|
||||||
builder.setWhen(System.currentTimeMillis())
|
|
||||||
val activityIntent = Intent(this, MainActivity::class.java)
|
|
||||||
val flags = if (Build.VERSION.SDK_INT >= 30) PendingIntent.FLAG_IMMUTABLE else PendingIntent.FLAG_UPDATE_CURRENT
|
val flags = if (Build.VERSION.SDK_INT >= 30) PendingIntent.FLAG_IMMUTABLE else PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
val pendingIntent = PendingIntent.getActivity(this, 0, activityIntent, flags)
|
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, flags)
|
||||||
builder.setContentIntent(pendingIntent)
|
|
||||||
return builder.build()
|
return NotificationCompat.Builder(this, FRONT_CHANNEL_ID).setContentTitle(getString(R.string.app_name)).setContentText(content).setSmallIcon(R.drawable.ic_forwarder).setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_menu_frpc)).setContentIntent(pendingIntent).setWhen(System.currentTimeMillis()).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateNotification(updatedContent: String) {
|
||||||
|
val notification = createNotification(updatedContent)
|
||||||
|
notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,40 +1,24 @@
|
|||||||
package com.idormy.sms.forwarder.service
|
package com.idormy.sms.forwarder.service
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.location.Criteria
|
|
||||||
import android.location.Geocoder
|
|
||||||
import android.location.Location
|
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.idormy.sms.forwarder.App
|
|
||||||
import com.idormy.sms.forwarder.entity.LocationInfo
|
|
||||||
import com.idormy.sms.forwarder.utils.HTTP_SERVER_PORT
|
import com.idormy.sms.forwarder.utils.HTTP_SERVER_PORT
|
||||||
import com.idormy.sms.forwarder.utils.HTTP_SERVER_TIME_OUT
|
import com.idormy.sms.forwarder.utils.HTTP_SERVER_TIME_OUT
|
||||||
import com.idormy.sms.forwarder.utils.HttpServerUtils
|
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||||
import com.king.location.LocationClient
|
|
||||||
import com.king.location.LocationErrorCode
|
|
||||||
import com.king.location.OnExceptionListener
|
|
||||||
import com.king.location.OnLocationListener
|
|
||||||
import com.yanzhenjie.andserver.AndServer
|
import com.yanzhenjie.andserver.AndServer
|
||||||
import com.yanzhenjie.andserver.Server
|
import com.yanzhenjie.andserver.Server
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@SuppressLint("SimpleDateFormat")
|
@Suppress("PrivatePropertyName")
|
||||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
|
||||||
class HttpService : Service(), Server.ServerListener {
|
class HttpService : Service(), Server.ServerListener {
|
||||||
|
|
||||||
private val TAG: String = "HttpService"
|
private val TAG: String = "HttpService"
|
||||||
private val server by lazy {
|
private val server by lazy {
|
||||||
AndServer.webServer(this).port(HTTP_SERVER_PORT).listener(this).timeout(HTTP_SERVER_TIME_OUT, TimeUnit.SECONDS).build()
|
AndServer.webServer(this).port(HTTP_SERVER_PORT).listener(this).timeout(HTTP_SERVER_TIME_OUT, TimeUnit.SECONDS).build()
|
||||||
}
|
}
|
||||||
private val locationClient by lazy { LocationClient(App.context) }
|
|
||||||
private val geocoder by lazy { Geocoder(App.context) }
|
|
||||||
private val simpleDateFormat by lazy { SimpleDateFormat("yyyy-MM-dd HH:mm:ss") }
|
|
||||||
|
|
||||||
override fun onBind(p0: Intent?): IBinder? {
|
override fun onBind(p0: Intent?): IBinder? {
|
||||||
return null
|
return null
|
||||||
@ -48,69 +32,6 @@ class HttpService : Service(), Server.ServerListener {
|
|||||||
|
|
||||||
Log.i(TAG, "onCreate: ")
|
Log.i(TAG, "onCreate: ")
|
||||||
server.startup()
|
server.startup()
|
||||||
|
|
||||||
//远程找手机
|
|
||||||
if (HttpServerUtils.enableApiLocation) {
|
|
||||||
//可根据具体需求设置定位配置参数(这里只列出一些主要的参数)
|
|
||||||
val locationOption = locationClient.getLocationOption().setAccuracy(Criteria.ACCURACY_FINE)//设置位置精度:高精度
|
|
||||||
.setPowerRequirement(Criteria.POWER_LOW) //设置电量消耗:低电耗
|
|
||||||
.setMinTime(10000)//设置位置更新最小时间间隔(单位:毫秒); 默认间隔:10000毫秒,最小间隔:1000毫秒
|
|
||||||
.setMinDistance(0)//设置位置更新最小距离(单位:米);默认距离:0米
|
|
||||||
.setOnceLocation(false)//设置是否只定位一次,默认为 false,当设置为 true 时,则只定位一次后,会自动停止定位
|
|
||||||
.setLastKnownLocation(false)//设置是否获取最后一次缓存的已知位置,默认为 true
|
|
||||||
//设置定位配置参数
|
|
||||||
locationClient.setLocationOption(locationOption)
|
|
||||||
locationClient.startLocation()
|
|
||||||
|
|
||||||
//设置定位监听
|
|
||||||
locationClient.setOnLocationListener(object : OnLocationListener() {
|
|
||||||
override fun onLocationChanged(location: Location) {
|
|
||||||
//位置信息
|
|
||||||
Log.d(TAG, "onLocationChanged(location = ${location})")
|
|
||||||
|
|
||||||
val locationInfo = LocationInfo(
|
|
||||||
location.longitude,
|
|
||||||
location.latitude,
|
|
||||||
"",
|
|
||||||
simpleDateFormat.format(Date(location.time)),
|
|
||||||
location.provider.toString()
|
|
||||||
)
|
|
||||||
|
|
||||||
//根据坐标经纬度获取位置地址信息(WGS-84坐标系)
|
|
||||||
val list = geocoder.getFromLocation(location.latitude, location.longitude, 1)
|
|
||||||
if (list?.isNotEmpty() == true) {
|
|
||||||
locationInfo.address = list[0].getAddressLine(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "locationInfo = $locationInfo")
|
|
||||||
HttpServerUtils.apiLocationCache = locationInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onProviderEnabled(provider: String) {
|
|
||||||
super.onProviderEnabled(provider)
|
|
||||||
Log.d(TAG, "onProviderEnabled(provider = ${provider})")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onProviderDisabled(provider: String) {
|
|
||||||
super.onProviderDisabled(provider)
|
|
||||||
Log.d(TAG, "onProviderDisabled(provider = ${provider})")
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
//设置异常监听
|
|
||||||
locationClient.setOnExceptionListener(object : OnExceptionListener {
|
|
||||||
override fun onException(@LocationErrorCode errorCode: Int, e: Exception) {
|
|
||||||
//定位出现异常
|
|
||||||
Log.w(TAG, "onException(errorCode = ${errorCode}, e = ${e})")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (locationClient.isStarted()) {//如果已经开始定位,则先停止定位
|
|
||||||
locationClient.stopLocation()
|
|
||||||
}
|
|
||||||
locationClient.startLocation()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
@ -126,10 +47,6 @@ class HttpService : Service(), Server.ServerListener {
|
|||||||
|
|
||||||
Log.i(TAG, "onDestroy: ")
|
Log.i(TAG, "onDestroy: ")
|
||||||
server.shutdown()
|
server.shutdown()
|
||||||
|
|
||||||
if (HttpServerUtils.enableApiLocation && locationClient.isStarted()) {//如果已经开始定位,则先停止定位
|
|
||||||
locationClient.stopLocation()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onException(e: Exception?) {
|
override fun onException(e: Exception?) {
|
||||||
|
@ -86,6 +86,7 @@ const val SP_SMS_TEMPLATE = "sms_template"
|
|||||||
|
|
||||||
const val SP_ENABLE_HELP_TIP = "enable_help_tip"
|
const val SP_ENABLE_HELP_TIP = "enable_help_tip"
|
||||||
const val SP_PURE_CLIENT_MODE = "enable_pure_client_mode"
|
const val SP_PURE_CLIENT_MODE = "enable_pure_client_mode"
|
||||||
|
const val SP_LOCATION_TAG = "enable_location_tag"
|
||||||
|
|
||||||
const val SP_ENABLE_CACTUS = "enable_cactus"
|
const val SP_ENABLE_CACTUS = "enable_cactus"
|
||||||
const val CACTUS_TIMER = "cactus_timer"
|
const val CACTUS_TIMER = "cactus_timer"
|
||||||
@ -324,6 +325,7 @@ var SENDER_FRAGMENT_LIST = listOf(
|
|||||||
|
|
||||||
//前台服务
|
//前台服务
|
||||||
const val FRONT_NOTIFY_ID = 0x1010
|
const val FRONT_NOTIFY_ID = 0x1010
|
||||||
|
const val NOTIFICATION_ID = 101
|
||||||
const val FRONT_CHANNEL_ID = "com.idormy.sms.forwarder"
|
const val FRONT_CHANNEL_ID = "com.idormy.sms.forwarder"
|
||||||
const val FRONT_CHANNEL_NAME = "SmsForwarder Foreground Service"
|
const val FRONT_CHANNEL_NAME = "SmsForwarder Foreground Service"
|
||||||
|
|
||||||
@ -349,7 +351,6 @@ const val KEY_URL = "key_url"
|
|||||||
//主页监听时间
|
//主页监听时间
|
||||||
const val EVENT_UPDATE_LOGS_TYPE = "key_logs_type"
|
const val EVENT_UPDATE_LOGS_TYPE = "key_logs_type"
|
||||||
const val EVENT_UPDATE_RULE_TYPE = "key_status"
|
const val EVENT_UPDATE_RULE_TYPE = "key_status"
|
||||||
const val EVENT_UPDATE_NOTIFY = "key_notify"
|
|
||||||
|
|
||||||
const val KEY_SENDER_ID = "key_sender_id"
|
const val KEY_SENDER_ID = "key_sender_id"
|
||||||
const val KEY_SENDER_TYPE = "key_sender_type"
|
const val KEY_SENDER_TYPE = "key_sender_type"
|
||||||
|
@ -157,6 +157,9 @@ class SettingUtils private constructor() {
|
|||||||
//是否纯客户端模式
|
//是否纯客户端模式
|
||||||
var enablePureClientMode: Boolean by SharedPreference(SP_PURE_CLIENT_MODE, false)
|
var enablePureClientMode: Boolean by SharedPreference(SP_PURE_CLIENT_MODE, false)
|
||||||
|
|
||||||
|
//是否启用定位标签
|
||||||
|
var enableLocationTag: Boolean by SharedPreference(SP_LOCATION_TAG, false)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -344,6 +344,40 @@
|
|||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
style="@style/settingBarStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/enable_location_tag"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="RelativeOverlap" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/enable_location_tag_tips"
|
||||||
|
android:textSize="9sp"
|
||||||
|
tools:ignore="SmallSp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||||
|
android:id="@+id/sb_enable_location_tag"
|
||||||
|
style="@style/SwitchButtonStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/settingBarStyle"
|
style="@style/settingBarStyle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -607,6 +607,7 @@
|
|||||||
<string name="tag_title">{{TITLE}}</string>
|
<string name="tag_title">{{TITLE}}</string>
|
||||||
<string name="tag_scheme">{{SCHEME}}</string>
|
<string name="tag_scheme">{{SCHEME}}</string>
|
||||||
<string name="tag_call_type">{{CALL_TYPE}}</string>
|
<string name="tag_call_type">{{CALL_TYPE}}</string>
|
||||||
|
<string name="tag_location">{{LOCATION}}</string>
|
||||||
<string name="rule_sms">SMS</string>
|
<string name="rule_sms">SMS</string>
|
||||||
<string name="rule_call">CALL</string>
|
<string name="rule_call">CALL</string>
|
||||||
<string name="rule_app">APP</string>
|
<string name="rule_app">APP</string>
|
||||||
@ -1057,4 +1058,7 @@
|
|||||||
<string name="number">Number</string>
|
<string name="number">Number</string>
|
||||||
<string name="country_iso">Country</string>
|
<string name="country_iso">Country</string>
|
||||||
<string name="subscription_id">Subscription ID</string>
|
<string name="subscription_id">Subscription ID</string>
|
||||||
|
|
||||||
|
<string name="enable_location_tag">Enable {{LOCATION}} Tag</string>
|
||||||
|
<string name="enable_location_tag_tips">Insert location info into forwarded msg.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -608,6 +608,7 @@
|
|||||||
<string name="tag_title">{{通知标题}}</string>
|
<string name="tag_title">{{通知标题}}</string>
|
||||||
<string name="tag_scheme">{{通知Scheme}}</string>
|
<string name="tag_scheme">{{通知Scheme}}</string>
|
||||||
<string name="tag_call_type">{{通话类型}}</string>
|
<string name="tag_call_type">{{通话类型}}</string>
|
||||||
|
<string name="tag_location">{{定位信息}}</string>
|
||||||
<string name="rule_sms">短信</string>
|
<string name="rule_sms">短信</string>
|
||||||
<string name="rule_call">来电</string>
|
<string name="rule_call">来电</string>
|
||||||
<string name="rule_app">应用</string>
|
<string name="rule_app">应用</string>
|
||||||
@ -1058,4 +1059,7 @@
|
|||||||
<string name="number">手机号码</string>
|
<string name="number">手机号码</string>
|
||||||
<string name="country_iso">国家代码</string>
|
<string name="country_iso">国家代码</string>
|
||||||
<string name="subscription_id">订阅标识</string>
|
<string name="subscription_id">订阅标识</string>
|
||||||
|
|
||||||
|
<string name="enable_location_tag">启用 {{定位信息}} 标签</string>
|
||||||
|
<string name="enable_location_tag_tips">在转发信息中插入手机的当前定位信息</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user