Skip to content

Commit

Permalink
新增:远程查询手机定位(方便找回手机/防止老少走丢) #256
Browse files Browse the repository at this point in the history
  • Loading branch information
pppscn committed Feb 9, 2023
1 parent 3f28080 commit 7bc7bfa
Show file tree
Hide file tree
Showing 19 changed files with 616 additions and 146 deletions.
5 changes: 3 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,11 @@ dependencies {

//国密算法SM4 的JAVA实现(基于BC实现)
api 'org.bouncycastle:bcprov-jdk15on:1.70'

//Location 是一个通过 Android 自带的 LocationManager 来实现的定位功能:/~https://github.com/jenly1314/Location
implementation 'com.github.pppscn:location:1.0.0'
}
//自动添加X-Library依赖
apply from: 'x-library.gradle'
//walle多渠道打包
//apply from: 'multiple-channel.gradle'


3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
<uses-permission
android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<application
android:name=".App"
Expand Down
25 changes: 25 additions & 0 deletions app/src/main/java/com/idormy/sms/forwarder/entity/LocationInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.idormy.sms.forwarder.entity

import com.idormy.sms.forwarder.R
import com.xuexiang.xui.utils.ResUtils
import java.io.Serializable

data class LocationInfo(
var longitude: Double = 0.0,
var latitude: Double = 0.0,
var address: String = "",
var time: String = "",
var provider: String = ""
) : Serializable {

override fun toString(): String {
var msg = ""
msg += "\n" + String.format(ResUtils.getString(R.string.location_longitude), longitude)
msg += "\n" + String.format(ResUtils.getString(R.string.location_latitude), latitude)
if (address != "") msg += "\n" + String.format(ResUtils.getString(R.string.location_address), address)
if (time != "") msg += "\n" + String.format(ResUtils.getString(R.string.location_time), time)
if (provider != "") msg += "\n" + String.format(ResUtils.getString(R.string.location_provider), provider)
return msg
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,12 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
XToastUtils.error(getString(R.string.click_test_button_first))
return
}
if (serverConfig != null && ((item.name == ResUtils.getString(R.string.api_sms_send) && !serverConfig!!.enableApiSmsSend) || (item.name == ResUtils.getString(R.string.api_sms_query) && !serverConfig!!.enableApiSmsQuery) || (item.name == ResUtils.getString(R.string.api_call_query) && !serverConfig!!.enableApiCallQuery) || (item.name == ResUtils.getString(R.string.api_contact_query) && !serverConfig!!.enableApiContactQuery) || (item.name == ResUtils.getString(R.string.api_battery_query) && !serverConfig!!.enableApiBatteryQuery) || (item.name == ResUtils.getString(R.string.api_wol) && !serverConfig!!.enableApiWol))) {
if (serverConfig != null && ((item.name == ResUtils.getString(R.string.api_sms_send) && !serverConfig!!.enableApiSmsSend) || (item.name == ResUtils.getString(R.string.api_sms_query) && !serverConfig!!.enableApiSmsQuery) || (item.name == ResUtils.getString(R.string.api_call_query) && !serverConfig!!.enableApiCallQuery) || (item.name == ResUtils.getString(R.string.api_contact_query) && !serverConfig!!.enableApiContactQuery) || (item.name == ResUtils.getString(R.string.api_battery_query) && !serverConfig!!.enableApiBatteryQuery) || (item.name == ResUtils.getString(R.string.api_wol) && !serverConfig!!.enableApiWol) || (item.name == ResUtils.getString(R.string.api_location) && !serverConfig!!.enableApiLocation))) {
XToastUtils.error(getString(R.string.disabled_on_the_server))
return
}
@Suppress("UNCHECKED_CAST") PageOption.to(Class.forName(item.classPath) as Class<XPageFragment>) //跳转的fragment
.setNewActivity(true).open(this)
@Suppress("UNCHECKED_CAST")
PageOption.to(Class.forName(item.classPath) as Class<XPageFragment>).setNewActivity(true).open(this)
} catch (e: Exception) {
e.printStackTrace()
XToastUtils.error(e.message.toString())
Expand Down
106 changes: 64 additions & 42 deletions app/src/main/java/com/idormy/sms/forwarder/fragment/ServerFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand Down Expand Up @@ -224,6 +225,18 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
HttpServerUtils.enableApiWol = isChecked
}

binding!!.sbApiLocation.isChecked = HttpServerUtils.enableApiLocation
binding!!.sbApiLocation.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
HttpServerUtils.enableApiLocation = isChecked
if (ServiceUtils.isServiceRunning("com.idormy.sms.forwarder.service.HttpService")) {
Log.d("ServerFragment", "onClick: 重启服务")
appContext?.stopService(Intent(appContext, HttpService::class.java))
Thread.sleep(500)
appContext?.startService(Intent(appContext, HttpService::class.java))
refreshButtonText()
}
}

}

@SingleClick
Expand All @@ -235,6 +248,7 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
checkReadSmsPermission()
checkCallPermission()
checkContactsPermission()
checkLocationPermission()
if (ServiceUtils.isServiceRunning("com.idormy.sms.forwarder.service.HttpService")) {
appContext?.stopService(Intent(appContext, HttpService::class.java))
} else {
Expand Down Expand Up @@ -292,28 +306,21 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
XToastUtils.error(String.format(getString(R.string.download_first), downloadPath))
return
}
MaterialDialog.Builder(requireContext())
.title(getString(R.string.select_web_client_directory))
.content(String.format(getString(R.string.root_directory), downloadPath))
.items(dirList)
.itemsCallbackSingleChoice(0) { _: MaterialDialog?, _: View?, _: Int, text: CharSequence ->
val webPath = "$downloadPath/$text"
binding!!.etWebPath.setText(webPath)
HttpServerUtils.serverWebPath = webPath

XToastUtils.info(getString(R.string.restarting_httpserver))
if (ServiceUtils.isServiceRunning("com.idormy.sms.forwarder.service.HttpService")) {
appContext?.stopService(Intent(appContext, HttpService::class.java))
appContext?.startService(Intent(appContext, HttpService::class.java))
} else {
appContext?.startService(Intent(appContext, HttpService::class.java))
}
refreshButtonText()
true // allow selection
MaterialDialog.Builder(requireContext()).title(getString(R.string.select_web_client_directory)).content(String.format(getString(R.string.root_directory), downloadPath)).items(dirList).itemsCallbackSingleChoice(0) { _: MaterialDialog?, _: View?, _: Int, text: CharSequence ->
val webPath = "$downloadPath/$text"
binding!!.etWebPath.setText(webPath)
HttpServerUtils.serverWebPath = webPath

XToastUtils.info(getString(R.string.restarting_httpserver))
if (ServiceUtils.isServiceRunning("com.idormy.sms.forwarder.service.HttpService")) {
appContext?.stopService(Intent(appContext, HttpService::class.java))
appContext?.startService(Intent(appContext, HttpService::class.java))
} else {
appContext?.startService(Intent(appContext, HttpService::class.java))
}
.positiveText(R.string.select)
.negativeText(R.string.cancel)
.show()
refreshButtonText()
true // allow selection
}.positiveText(R.string.select).negativeText(R.string.cancel).show()
}
else -> {}
}
Expand Down Expand Up @@ -342,8 +349,7 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
private fun checkSendSmsPermission() {
XXPermissions.with(this)
// 发送短信
.permission(Permission.SEND_SMS)
.request(object : OnPermissionCallback {
.permission(Permission.SEND_SMS).request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) {
}

Expand All @@ -369,8 +375,7 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
// 发送短信
.permission(Permission.SEND_SMS)
// 读取短信
.permission(Permission.READ_SMS)
.request(object : OnPermissionCallback {
.permission(Permission.READ_SMS).request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) {
}

Expand All @@ -396,8 +401,7 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
// 读取手机号码
.permission(Permission.READ_PHONE_NUMBERS)
// 读取通话记录
.permission(Permission.READ_CALL_LOG)
.request(object : OnPermissionCallback {
.permission(Permission.READ_CALL_LOG).request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) {
}

Expand All @@ -417,24 +421,42 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe

//联系人权限
private fun checkContactsPermission() {
XXPermissions.with(this)
.permission(*Permission.Group.CONTACTS)
.request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) {
XXPermissions.with(this).permission(*Permission.Group.CONTACTS).request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) {
}

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)
}
HttpServerUtils.enableApiContactQuery = false
binding!!.sbApiQueryContacts.isChecked = false
}
})
}

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)
}
HttpServerUtils.enableApiContactQuery = false
binding!!.sbApiQueryContacts.isChecked = false
//联系人权限
private fun checkLocationPermission() {
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 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)
}
})
HttpServerUtils.enableApiLocation = false
binding!!.sbApiLocation.isChecked = false
}
})
}

override fun onDestroy() {
Expand Down
Loading

0 comments on commit 7bc7bfa

Please sign in to comment.