新增:监听其他APP通知信息
This commit is contained in:
parent
27d35cb276
commit
e8ea004bc4
|
@ -260,6 +260,7 @@
|
||||||
+ https://github.com/xuexiangjys/XUpdateAPI (在线升级)
|
+ https://github.com/xuexiangjys/XUpdateAPI (在线升级)
|
||||||
+ https://github.com/mailhu/emailkit (邮件发送)
|
+ https://github.com/mailhu/emailkit (邮件发送)
|
||||||
+ https://github.com/alibaba/fastjson (Json解析)
|
+ https://github.com/alibaba/fastjson (Json解析)
|
||||||
|
+ https://github.com/lilongweidev/NotifyListenerDemo (手机通知服务)
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
|
|
308
app/build.gradle
308
app/build.gradle
|
@ -1,154 +1,154 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
def keyProps = new Properties()
|
def keyProps = new Properties()
|
||||||
def keyPropsFile = rootProject.file('keystore/keystore.properties')
|
def keyPropsFile = rootProject.file('keystore/keystore.properties')
|
||||||
if (keyPropsFile.exists()) {
|
if (keyPropsFile.exists()) {
|
||||||
keyProps.load(new FileInputStream(keyPropsFile))
|
keyProps.load(new FileInputStream(keyPropsFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取version.properties
|
// 读取version.properties
|
||||||
def versionProps = new Properties()
|
def versionProps = new Properties()
|
||||||
def versionPropsFile = rootProject.file('version.properties')
|
def versionPropsFile = rootProject.file('version.properties')
|
||||||
if (versionPropsFile.exists()) {
|
if (versionPropsFile.exists()) {
|
||||||
versionProps.load(new FileInputStream(versionPropsFile))
|
versionProps.load(new FileInputStream(versionPropsFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
buildToolsVersion '30.0.3'
|
buildToolsVersion '30.0.3'
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility 1.8
|
sourceCompatibility 1.8
|
||||||
targetCompatibility 1.8
|
targetCompatibility 1.8
|
||||||
}
|
}
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.idormy.sms.forwarder"
|
applicationId "com.idormy.sms.forwarder"
|
||||||
minSdkVersion 23
|
minSdkVersion 21
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode versionProps['versionCode'].toInteger()
|
versionCode versionProps['versionCode'].toInteger()
|
||||||
versionName versionProps['versionName']
|
versionName versionProps['versionName']
|
||||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
}
|
}
|
||||||
lintOptions {
|
lintOptions {
|
||||||
checkReleaseBuilds false
|
checkReleaseBuilds false
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
keyAlias keyProps['keyAlias']
|
keyAlias keyProps['keyAlias']
|
||||||
keyPassword keyProps['keyPassword']
|
keyPassword keyProps['keyPassword']
|
||||||
storeFile keyProps['storeFile'] ? file(keyProps['storeFile']) : null
|
storeFile keyProps['storeFile'] ? file(keyProps['storeFile']) : null
|
||||||
storePassword keyProps['storePassword']
|
storePassword keyProps['storePassword']
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
keyAlias keyProps['keyAlias']
|
keyAlias keyProps['keyAlias']
|
||||||
keyPassword keyProps['keyPassword']
|
keyPassword keyProps['keyPassword']
|
||||||
storeFile keyProps['storeFile'] ? file(keyProps['storeFile']) : null
|
storeFile keyProps['storeFile'] ? file(keyProps['storeFile']) : null
|
||||||
storePassword keyProps['storePassword']
|
storePassword keyProps['storePassword']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//apk file name
|
//apk file name
|
||||||
android.applicationVariants.all { variant ->
|
android.applicationVariants.all { variant ->
|
||||||
variant.outputs.all {
|
variant.outputs.all {
|
||||||
//def date = new Date().format("yyyyMMdd" , TimeZone.getTimeZone("Asia/Shanghai"))
|
//def date = new Date().format("yyyyMMdd" , TimeZone.getTimeZone("Asia/Shanghai"))
|
||||||
def date = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08"))
|
def date = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08"))
|
||||||
if (variant.buildType.name == 'debug') {
|
if (variant.buildType.name == 'debug') {
|
||||||
outputFileName = "SmsForwarder_debug_${date}_${versionName}.apk"
|
outputFileName = "SmsForwarder_debug_${date}_${versionName}.apk"
|
||||||
}
|
}
|
||||||
if (variant.buildType.name == 'release') {
|
if (variant.buildType.name == 'release') {
|
||||||
outputFileName = "SmsForwarder_release_${date}_${versionName}.apk"
|
outputFileName = "SmsForwarder_release_${date}_${versionName}.apk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
task upgradeVersion {
|
task upgradeVersion {
|
||||||
group 'help'
|
group 'help'
|
||||||
description '构建新版本'
|
description '构建新版本'
|
||||||
doLast {
|
doLast {
|
||||||
println("---自动升级版本号---\n")
|
println("---自动升级版本号---\n")
|
||||||
String oldVersionCode = versionProps['versionCode']
|
String oldVersionCode = versionProps['versionCode']
|
||||||
String oldVersionName = versionProps['versionName']
|
String oldVersionName = versionProps['versionName']
|
||||||
if (oldVersionCode == null || oldVersionName == null ||
|
if (oldVersionCode == null || oldVersionName == null ||
|
||||||
oldVersionCode.isEmpty() || oldVersionName.isEmpty()) {
|
oldVersionCode.isEmpty() || oldVersionName.isEmpty()) {
|
||||||
println("error:版本号不能为空")
|
println("error:版本号不能为空")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
versionProps['versionCode'] = String.valueOf(versionProps['versionCode'].toInteger() + 1)
|
versionProps['versionCode'] = String.valueOf(versionProps['versionCode'].toInteger() + 1)
|
||||||
String str = versionProps['versionName'].toString()
|
String str = versionProps['versionName'].toString()
|
||||||
versionProps['versionName'] = str.substring(0, str.lastIndexOf('.') + 1) +
|
versionProps['versionName'] = str.substring(0, str.lastIndexOf('.') + 1) +
|
||||||
(str.substring(str.lastIndexOf('.') + 1).toInteger() + 1)
|
(str.substring(str.lastIndexOf('.') + 1).toInteger() + 1)
|
||||||
String tip =
|
String tip =
|
||||||
"版本号从$oldVersionName($oldVersionCode)升级到${versionProps['versionName']}(${versionProps['versionCode']})"
|
"版本号从$oldVersionName($oldVersionCode)升级到${versionProps['versionName']}(${versionProps['versionCode']})"
|
||||||
println(tip)
|
println(tip)
|
||||||
|
|
||||||
def writer = new FileWriter(versionPropsFile)
|
def writer = new FileWriter(versionPropsFile)
|
||||||
versionProps.store(writer, null)
|
versionProps.store(writer, null)
|
||||||
writer.flush()
|
writer.flush()
|
||||||
writer.close()
|
writer.close()
|
||||||
def tag = "v${versionProps['versionName']}"
|
def tag = "v${versionProps['versionName']}"
|
||||||
cmdExecute("git pull")
|
cmdExecute("git pull")
|
||||||
cmdExecute("git add version.properties")
|
cmdExecute("git add version.properties")
|
||||||
cmdExecute("git commit -m \"版本号升级为:$tag\"")
|
cmdExecute("git commit -m \"版本号升级为:$tag\"")
|
||||||
cmdExecute("git push origin")
|
cmdExecute("git push origin")
|
||||||
cmdExecute("git tag $tag")
|
cmdExecute("git tag $tag")
|
||||||
cmdExecute("git push origin $tag")
|
cmdExecute("git push origin $tag")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmdExecute(String cmd) {
|
void cmdExecute(String cmd) {
|
||||||
println "\n执行$cmd"
|
println "\n执行$cmd"
|
||||||
println cmd.execute().text
|
println cmd.execute().text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.+'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
|
||||||
//okhttp
|
//okhttp
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
|
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
|
||||||
implementation 'com.squareup.okio:okio:2.10.0'
|
implementation 'com.squareup.okio:okio:2.10.0'
|
||||||
|
|
||||||
//fastjson
|
//fastjson
|
||||||
implementation "com.alibaba:fastjson:1.2.78"
|
implementation "com.alibaba:fastjson:1.2.78"
|
||||||
|
|
||||||
//友盟统计SDK
|
//友盟统计SDK
|
||||||
implementation 'com.umeng.umsdk:common:9.4.4'// 必选
|
implementation 'com.umeng.umsdk:common:9.4.4'// 必选
|
||||||
implementation 'com.umeng.umsdk:asms:1.4.1'// 必选
|
implementation 'com.umeng.umsdk:asms:1.4.1'// 必选
|
||||||
implementation 'com.umeng.umsdk:apm:1.4.2' // 错误分析升级为独立SDK,看crash数据请一定集成,可选
|
implementation 'com.umeng.umsdk:apm:1.4.2' // 错误分析升级为独立SDK,看crash数据请一定集成,可选
|
||||||
|
|
||||||
//XUpdate
|
//XUpdate
|
||||||
implementation 'com.github.xuexiangjys:XUpdate:2.1.0'
|
implementation 'com.github.xuexiangjys:XUpdate:2.1.0'
|
||||||
implementation 'com.github.xuexiangjys.XUpdateAPI:xupdate-easy:1.0.0'
|
implementation 'com.github.xuexiangjys.XUpdateAPI:xupdate-easy:1.0.0'
|
||||||
implementation 'com.github.xuexiangjys.XUpdateAPI:xupdate-downloader-aria:1.0.0'
|
implementation 'com.github.xuexiangjys.XUpdateAPI:xupdate-downloader-aria:1.0.0'
|
||||||
|
|
||||||
//EmailKit
|
//EmailKit
|
||||||
implementation 'com.github.mailhu:emailkit:4.2.2'
|
implementation 'com.github.mailhu:emailkit:4.2.2'
|
||||||
|
|
||||||
//Lombok
|
//Lombok
|
||||||
//noinspection AnnotationProcessorOnCompilePath
|
//noinspection AnnotationProcessorOnCompilePath
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.20'
|
compileOnly 'org.projectlombok:lombok:1.18.20'
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||||
|
|
||||||
//RxJava
|
//RxJava
|
||||||
implementation 'io.reactivex.rxjava3:rxjava:3.1.1'
|
implementation 'io.reactivex.rxjava3:rxjava:3.1.1'
|
||||||
|
|
||||||
//AndroidAsync
|
//AndroidAsync
|
||||||
implementation 'com.koushikdutta.async:androidasync:3.1.0'
|
implementation 'com.koushikdutta.async:androidasync:3.1.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,120 +1,143 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="com.idormy.sms.forwarder">
|
package="com.idormy.sms.forwarder">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<!-- 授予应用程序访问系统开机事件的权限 -->
|
<!-- 授予应用程序访问系统开机事件的权限 -->
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
tools:ignore="ScopedStorage" />
|
tools:ignore="ScopedStorage" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||||
<uses-permission android:name="android.permission.READ_SMS" />
|
<uses-permission android:name="android.permission.READ_SMS" />
|
||||||
<uses-permission android:name="android.permission.SEND_SMS" />
|
<uses-permission android:name="android.permission.SEND_SMS" />
|
||||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
|
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
|
||||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
<!--Android 9(API 级别 28)或更高版本并使用前台服务,则其必须请求 FOREGROUND_SERVICE 权限-->
|
<!--Android 9(API 级别 28)或更高版本并使用前台服务,则其必须请求 FOREGROUND_SERVICE 权限-->
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.BATTERY_STATS"
|
android:name="android.permission.BATTERY_STATS"
|
||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
<uses-permission
|
||||||
<application
|
android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
|
||||||
android:name=".MyApplication"
|
tools:ignore="ProtectedPermissions" />
|
||||||
android:allowBackup="true"
|
<uses-permission android:name="android.permission.ACTION_NOTIFICATION_LISTENER_SETTINGS" />
|
||||||
android:icon="@mipmap/ic_launcher"
|
<uses-permission
|
||||||
android:label="@string/app_name"
|
android:name="android.permission.INSTALL_PACKAGES"
|
||||||
android:requestLegacyExternalStorage="true"
|
tools:ignore="ProtectedPermissions" />
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/AppTheme"
|
<application
|
||||||
android:usesCleartextTraffic="true"
|
android:name=".MyApplication"
|
||||||
android:fullBackupContent="@xml/backup_descriptor">
|
android:allowBackup="true"
|
||||||
|
android:fullBackupContent="@xml/backup_descriptor"
|
||||||
<meta-data
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:name="UPDATE_APP_KEY"
|
android:label="@string/app_name"
|
||||||
android:value="SVSfseesfsf" />
|
android:requestLegacyExternalStorage="true"
|
||||||
<meta-data
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:name="UMENG_APPKEY"
|
android:supportsRtl="true"
|
||||||
android:value="60254fc7425ec25f10f4293e" />
|
android:theme="@style/AppTheme"
|
||||||
<meta-data
|
android:usesCleartextTraffic="true">
|
||||||
android:name="UMENG_CHANNEL"
|
|
||||||
android:value="Umeng" />
|
<meta-data
|
||||||
|
android:name="UPDATE_APP_KEY"
|
||||||
<activity
|
android:value="SVSfseesfsf" />
|
||||||
android:name=".MainActivity"
|
<meta-data
|
||||||
tools:ignore="IntentFilterExportedReceiver">
|
android:name="UMENG_APPKEY"
|
||||||
<intent-filter>
|
android:value="60254fc7425ec25f10f4293e" />
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<meta-data
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
android:name="UMENG_CHANNEL"
|
||||||
</intent-filter>
|
android:value="Umeng" />
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".AboutActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/about"
|
tools:ignore="IntentFilterExportedReceiver">
|
||||||
tools:ignore="IntentFilterExportedReceiver">
|
<intent-filter>
|
||||||
<intent-filter>
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<!--协议部分,随便设置-->
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
<data
|
</intent-filter>
|
||||||
android:scheme="forwarder"
|
</activity>
|
||||||
android:host="main" />
|
<activity
|
||||||
<!--下面这几行也必须得设置-->
|
android:name=".AboutActivity"
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
android:label="@string/about"
|
||||||
<action android:name="android.intent.action.VIEW" />
|
tools:ignore="IntentFilterExportedReceiver">
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<intent-filter>
|
||||||
</intent-filter>
|
<!--协议部分,随便设置-->
|
||||||
</activity>
|
<data
|
||||||
<activity
|
android:host="main"
|
||||||
android:name=".SettingActivity"
|
android:scheme="forwarder" />
|
||||||
android:label="@string/setting" />
|
<!--下面这几行也必须得设置-->
|
||||||
<activity
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
android:name=".CloneActivity"
|
<action android:name="android.intent.action.VIEW" />
|
||||||
android:label="@string/clone" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<activity
|
</intent-filter>
|
||||||
android:name=".RuleActivity"
|
</activity>
|
||||||
android:label="@string/rule_setting" />
|
<activity
|
||||||
<activity
|
android:name=".SettingActivity"
|
||||||
android:name=".SenderActivity"
|
android:label="@string/setting" />
|
||||||
android:label="@string/sender_setting" />
|
<activity
|
||||||
|
android:name=".CloneActivity"
|
||||||
<receiver
|
android:label="@string/clone" />
|
||||||
android:name=".receiver.RebootBroadcastReceiver"
|
<activity
|
||||||
tools:ignore="IntentFilterExportedReceiver">
|
android:name=".RuleActivity"
|
||||||
<intent-filter android:priority="2147483647">
|
android:label="@string/rule_setting" />
|
||||||
<!--重启广播-->
|
<activity
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
android:name=".SenderActivity"
|
||||||
</intent-filter>
|
android:label="@string/sender_setting" />
|
||||||
</receiver>
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".receiver.SmsForwarderBroadcastReceiver"
|
android:name=".receiver.RebootBroadcastReceiver"
|
||||||
android:permission="android.permission.BROADCAST_SMS"
|
tools:ignore="IntentFilterExportedReceiver">
|
||||||
tools:ignore="IntentFilterExportedReceiver">
|
<intent-filter android:priority="2147483647">
|
||||||
<intent-filter android:priority="2147483647">
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
<!--短信广播-->
|
<action android:name="android.intent.action.USER_PRESENT" />
|
||||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
<action android:name="android.intent.action.PACKAGE_RESTARTED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
<receiver
|
||||||
<receiver
|
android:name=".receiver.SmsForwarderBroadcastReceiver"
|
||||||
android:name=".receiver.PhoneStateReceiver"
|
android:permission="android.permission.BROADCAST_SMS"
|
||||||
tools:ignore="IntentFilterExportedReceiver">
|
tools:ignore="IntentFilterExportedReceiver">
|
||||||
<intent-filter>
|
<intent-filter android:priority="2147483647">
|
||||||
<action android:name="android.intent.action.PHONE_STATE" />
|
<!--短信广播-->
|
||||||
</intent-filter>
|
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||||
</receiver>
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
<service android:name=".service.FrontService" />
|
<receiver
|
||||||
</application>
|
android:name=".receiver.PhoneStateReceiver"
|
||||||
|
tools:ignore="IntentFilterExportedReceiver">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.PHONE_STATE" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".service.FrontService"
|
||||||
|
android:enabled="true" />
|
||||||
|
<service
|
||||||
|
android:name=".service.BatteryService"
|
||||||
|
android:enabled="true" />
|
||||||
|
<service
|
||||||
|
android:name=".service.NotifyService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.notification.NotificationListenerService" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -1,247 +1,430 @@
|
||||||
package com.idormy.sms.forwarder;
|
package com.idormy.sms.forwarder;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.ComponentName;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.content.Intent;
|
||||||
import android.os.Handler;
|
import android.content.pm.PackageManager;
|
||||||
import android.util.Log;
|
import android.os.Build;
|
||||||
import android.view.Menu;
|
import android.os.Bundle;
|
||||||
import android.view.MenuInflater;
|
import android.os.Handler;
|
||||||
import android.view.MenuItem;
|
import android.os.PowerManager;
|
||||||
import android.view.View;
|
import android.service.notification.StatusBarNotification;
|
||||||
import android.widget.TextView;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import android.view.MenuItem;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
import com.idormy.sms.forwarder.adapter.LogAdapter;
|
import android.widget.Toast;
|
||||||
import com.idormy.sms.forwarder.model.vo.LogVo;
|
|
||||||
import com.idormy.sms.forwarder.utils.LogUtil;
|
import androidx.annotation.NonNull;
|
||||||
import com.idormy.sms.forwarder.utils.NetUtil;
|
import androidx.annotation.RequiresApi;
|
||||||
import com.idormy.sms.forwarder.utils.PhoneUtils;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import com.idormy.sms.forwarder.utils.SmsUtil;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import com.idormy.sms.forwarder.utils.aUtil;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.idormy.sms.forwarder.adapter.LogAdapter;
|
||||||
import java.util.List;
|
import com.idormy.sms.forwarder.model.vo.LogVo;
|
||||||
|
import com.idormy.sms.forwarder.model.vo.SmsVo;
|
||||||
public class MainActivity extends AppCompatActivity implements RefreshListView.IRefreshListener {
|
import com.idormy.sms.forwarder.notify.NotifyHelper;
|
||||||
|
import com.idormy.sms.forwarder.notify.NotifyListener;
|
||||||
private final String TAG = "MainActivity";
|
import com.idormy.sms.forwarder.sender.SendUtil;
|
||||||
// logVoList用于存储数据
|
import com.idormy.sms.forwarder.service.FrontService;
|
||||||
private List<LogVo> logVos = new ArrayList<>();
|
import com.idormy.sms.forwarder.service.NotifyService;
|
||||||
private LogAdapter adapter;
|
import com.idormy.sms.forwarder.utils.LogUtil;
|
||||||
private RefreshListView listView;
|
import com.idormy.sms.forwarder.utils.NetUtil;
|
||||||
|
import com.idormy.sms.forwarder.utils.PhoneUtils;
|
||||||
@Override
|
import com.idormy.sms.forwarder.utils.SmsUtil;
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
import com.idormy.sms.forwarder.utils.aUtil;
|
||||||
|
|
||||||
LogUtil.init(this);
|
import java.text.SimpleDateFormat;
|
||||||
Log.d(TAG, "onCreate");
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
super.onCreate(savedInstanceState);
|
import java.util.List;
|
||||||
setContentView(R.layout.activity_main);
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
//检查权限是否获取
|
|
||||||
PackageManager pm = getPackageManager();
|
public class MainActivity extends AppCompatActivity implements NotifyListener, RefreshListView.IRefreshListener {
|
||||||
PhoneUtils.CheckPermission(pm, this);
|
|
||||||
|
private final String TAG = "MainActivity";
|
||||||
//获取SIM信息
|
private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
|
||||||
PhoneUtils.init(this);
|
// logVoList用于存储数据
|
||||||
|
private List<LogVo> logVos = new ArrayList<>();
|
||||||
//短信&网络组件初始化
|
private LogAdapter adapter;
|
||||||
SmsUtil.init(this);
|
private RefreshListView listView;
|
||||||
NetUtil.init(this);
|
private Intent serviceIntent;
|
||||||
}
|
private static final int REQUEST_CODE = 9999;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onStart();
|
|
||||||
Log.d(TAG, "onStart");
|
LogUtil.init(this);
|
||||||
|
Log.d(TAG, "onCreate");
|
||||||
//是否关闭页面提示
|
|
||||||
TextView help_tip = findViewById(R.id.help_tip);
|
super.onCreate(savedInstanceState);
|
||||||
help_tip.setVisibility(MyApplication.showHelpTip ? View.VISIBLE : View.GONE);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
// 先拿到数据并放在适配器上
|
//检查权限是否获取
|
||||||
initTLogs(); //初始化数据
|
PackageManager pm = getPackageManager();
|
||||||
showList(logVos);
|
PhoneUtils.CheckPermission(pm, this);
|
||||||
|
|
||||||
// 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法
|
//获取SIM信息
|
||||||
// 在这个方法中可以通过position参数判断出用户点击的是那一个子项
|
PhoneUtils.init(this);
|
||||||
listView.setOnItemClickListener((parent, view, position, id) -> {
|
|
||||||
if (position <= 0) return;
|
//短信&网络组件初始化
|
||||||
|
SmsUtil.init(this);
|
||||||
LogVo logVo = logVos.get(position - 1);
|
NetUtil.init(this);
|
||||||
logDetail(logVo);
|
|
||||||
});
|
//应用通知
|
||||||
|
NotifyHelper.getInstance().setNotifyListener(this);
|
||||||
listView.setOnItemLongClickListener((parent, view, position, id) -> {
|
|
||||||
if (position <= 0) return false;
|
//前台服务
|
||||||
|
serviceIntent = new Intent(MainActivity.this, FrontService.class);
|
||||||
//定义AlertDialog.Builder对象,当长按列表项的时候弹出确认删除对话框
|
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
startService(serviceIntent);
|
||||||
builder.setTitle(R.string.delete_log_title);
|
}
|
||||||
builder.setMessage(R.string.delete_log_tips);
|
|
||||||
|
@Override
|
||||||
//添加AlertDialog.Builder对象的setPositiveButton()方法
|
protected void onStart() {
|
||||||
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
super.onStart();
|
||||||
Long id1 = logVos.get(position - 1).getId();
|
Log.d(TAG, "onStart");
|
||||||
Log.d(TAG, "id = " + id1);
|
|
||||||
LogUtil.delLog(id1, null);
|
//是否关闭页面提示
|
||||||
initTLogs(); //初始化数据
|
TextView help_tip = findViewById(R.id.help_tip);
|
||||||
showList(logVos);
|
help_tip.setVisibility(MyApplication.showHelpTip ? View.VISIBLE : View.GONE);
|
||||||
Toast.makeText(getBaseContext(), R.string.delete_log_toast, Toast.LENGTH_SHORT).show();
|
|
||||||
});
|
// 先拿到数据并放在适配器上
|
||||||
|
initTLogs(); //初始化数据
|
||||||
//添加AlertDialog.Builder对象的setNegativeButton()方法
|
showList(logVos);
|
||||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> {
|
|
||||||
});
|
// 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法
|
||||||
|
// 在这个方法中可以通过position参数判断出用户点击的是那一个子项
|
||||||
builder.create().show();
|
listView.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
return true;
|
if (position <= 0) return;
|
||||||
});
|
|
||||||
}
|
LogVo logVo = logVos.get(position - 1);
|
||||||
|
logDetail(logVo);
|
||||||
@Override
|
});
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
listView.setOnItemLongClickListener((parent, view, position, id) -> {
|
||||||
//第一次打开,未授权无法获取SIM信息,尝试在此重新获取
|
if (position <= 0) return false;
|
||||||
if (MyApplication.SimInfoList.isEmpty()) {
|
|
||||||
MyApplication.SimInfoList = PhoneUtils.getSimMultiInfo();
|
//定义AlertDialog.Builder对象,当长按列表项的时候弹出确认删除对话框
|
||||||
}
|
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||||
Log.d(TAG, "SimInfoList = " + MyApplication.SimInfoList.size());
|
builder.setTitle(R.string.delete_log_title);
|
||||||
}
|
builder.setMessage(R.string.delete_log_tips);
|
||||||
|
|
||||||
// 初始化数据
|
//添加AlertDialog.Builder对象的setPositiveButton()方法
|
||||||
private void initTLogs() {
|
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
||||||
logVos = LogUtil.getLog(null, null);
|
Long id1 = logVos.get(position - 1).getId();
|
||||||
}
|
Log.d(TAG, "id = " + id1);
|
||||||
|
LogUtil.delLog(id1, null);
|
||||||
private void showList(List<LogVo> logVosN) {
|
initTLogs(); //初始化数据
|
||||||
Log.d(TAG, "showList: " + logVosN);
|
showList(logVos);
|
||||||
if (adapter == null) {
|
Toast.makeText(getBaseContext(), R.string.delete_log_toast, Toast.LENGTH_SHORT).show();
|
||||||
// 将适配器上的数据传递给listView
|
});
|
||||||
listView = findViewById(R.id.list_view_log);
|
|
||||||
listView.setInterface(this);
|
//添加AlertDialog.Builder对象的setNegativeButton()方法
|
||||||
adapter = new LogAdapter(MainActivity.this, R.layout.item_log, logVosN);
|
builder.setNegativeButton(R.string.cancel, (dialog, which) -> {
|
||||||
|
});
|
||||||
listView.setAdapter(adapter);
|
|
||||||
} else {
|
builder.create().show();
|
||||||
adapter.onDateChange(logVosN);
|
return true;
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressLint("ObsoleteSdkInt")
|
||||||
public void onRefresh() {
|
@Override
|
||||||
Handler handler = new Handler();
|
protected void onResume() {
|
||||||
handler.postDelayed(() -> {
|
super.onResume();
|
||||||
// TODO Auto-generated method stub
|
//第一次打开,未授权无法获取SIM信息,尝试在此重新获取
|
||||||
//获取最新数据
|
if (MyApplication.SimInfoList.isEmpty()) {
|
||||||
initTLogs();
|
MyApplication.SimInfoList = PhoneUtils.getSimMultiInfo();
|
||||||
//通知界面显示
|
}
|
||||||
showList(logVos);
|
Log.d(TAG, "SimInfoList = " + MyApplication.SimInfoList.size());
|
||||||
//通知listview 刷新数据完毕;
|
|
||||||
listView.refreshComplete();
|
//开启读取通知栏权限
|
||||||
}, 2000);
|
if (!isNotificationListenerServiceEnabled(this)) {
|
||||||
}
|
openNotificationAccess();
|
||||||
|
toggleNotificationListenerService();
|
||||||
|
Toast.makeText(this, "请先勾选《短信转发器》的读取通知栏权限!", Toast.LENGTH_LONG).show();
|
||||||
public void logDetail(LogVo logVo) {
|
return;
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
}
|
||||||
builder.setTitle(R.string.details);
|
|
||||||
String simInfo = logVo.getSimInfo();
|
//省电优化设置为无限制
|
||||||
if (simInfo != null) {
|
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||||
builder.setMessage(logVo.getFrom() + "\n\n" + logVo.getContent() + "\n\n" + logVo.getSimInfo() + "\n\n" + logVo.getRule() + "\n\n" + aUtil.utc2Local(logVo.getTime()) + "\n\nResponse:" + logVo.getForwardResponse());
|
if (!isIgnoringBatteryOptimizations()) {
|
||||||
} else {
|
Toast.makeText(this, "请将省电优化设置为无限制,有利于防止《短信转发器》被杀!!", Toast.LENGTH_LONG).show();
|
||||||
builder.setMessage(logVo.getFrom() + "\n\n" + logVo.getContent() + "\n\n" + logVo.getRule() + "\n\n" + aUtil.utc2Local(logVo.getTime()) + "\n\nResponse:" + logVo.getForwardResponse());
|
}
|
||||||
}
|
}
|
||||||
//删除
|
startService(serviceIntent);
|
||||||
builder.setNegativeButton(R.string.del, (dialog, which) -> {
|
}
|
||||||
Long id = logVo.getId();
|
|
||||||
Log.d(TAG, "id = " + id);
|
@Override
|
||||||
LogUtil.delLog(id, null);
|
protected void onDestroy() {
|
||||||
initTLogs(); //初始化数据
|
super.onDestroy();
|
||||||
showList(logVos);
|
startService(serviceIntent);
|
||||||
Toast.makeText(MainActivity.this, R.string.delete_log_toast, Toast.LENGTH_SHORT).show();
|
}
|
||||||
dialog.dismiss();
|
|
||||||
});
|
@Override
|
||||||
builder.show();
|
protected void onPause() {
|
||||||
}
|
//当界面返回到桌面之后.清除通知设置当中的数据.减少内存占有
|
||||||
|
//if (applicationList != null) {
|
||||||
public void toClone() {
|
// applicationList.setAdapter(null);
|
||||||
Intent intent = new Intent(this, CloneActivity.class);
|
// adapter = null;
|
||||||
startActivity(intent);
|
//}
|
||||||
}
|
super.onPause();
|
||||||
|
startService(serviceIntent);
|
||||||
public void toSetting() {
|
}
|
||||||
Intent intent = new Intent(this, SettingActivity.class);
|
|
||||||
startActivity(intent);
|
@Override
|
||||||
}
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
public void toAbout() {
|
if (requestCode == REQUEST_CODE) {
|
||||||
Intent intent = new Intent(this, AboutActivity.class);
|
if (isNotificationListenerServiceEnabled(this)) {
|
||||||
startActivity(intent);
|
Toast.makeText(this, "通知服务已开启", Toast.LENGTH_SHORT).show();
|
||||||
}
|
toggleNotificationListenerService();
|
||||||
|
} else {
|
||||||
public void toRuleSetting(View view) {
|
Toast.makeText(this, "通知服务未开启", Toast.LENGTH_SHORT).show();
|
||||||
Intent intent = new Intent(this, RuleActivity.class);
|
}
|
||||||
startActivity(intent);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toSendSetting(View view) {
|
// 权限判断相关
|
||||||
Intent intent = new Intent(this, SenderActivity.class);
|
@Override
|
||||||
startActivity(intent);
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
}
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
}
|
||||||
public void cleanLog(View view) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
public void toggleNotificationListenerService() {
|
||||||
builder.setTitle(R.string.clear_logs_tips)
|
PackageManager pm = getPackageManager();
|
||||||
.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), NotifyService.class),
|
||||||
// TODO Auto-generated method stub
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||||
LogUtil.delLog(null, null);
|
|
||||||
initTLogs();
|
pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), NotifyService.class),
|
||||||
adapter.add(logVos);
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
|
||||||
});
|
}
|
||||||
builder.show();
|
|
||||||
}
|
private static boolean isNotificationListenerServiceEnabled(Context context) {
|
||||||
|
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
|
||||||
//按返回键不退出回到桌面
|
return packageNames.contains(context.getPackageName());
|
||||||
@Override
|
}
|
||||||
public void onBackPressed() {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
/**
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
* 判断系统是否已经关闭省电优化
|
||||||
intent.addCategory(Intent.CATEGORY_HOME);
|
*
|
||||||
startActivity(intent);
|
* @return boolean
|
||||||
}
|
*/
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||||
@SuppressLint("NonConstantResourceId")
|
private boolean isIgnoringBatteryOptimizations() {
|
||||||
@Override
|
boolean isIgnoring = false;
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||||
// Handle item selection
|
if (powerManager != null) {
|
||||||
switch (item.getItemId()) {
|
isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName());
|
||||||
case R.id.to_clone:
|
}
|
||||||
toClone();
|
if (!isIgnoring) {
|
||||||
return true;
|
Intent i = new Intent(android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
|
||||||
case R.id.to_setting:
|
startActivity(i);
|
||||||
toSetting();
|
}
|
||||||
return true;
|
return isIgnoring;
|
||||||
case R.id.to_about:
|
}
|
||||||
toAbout();
|
|
||||||
return true;
|
private void openNotificationAccess() {
|
||||||
default:
|
startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
|
||||||
return super.onOptionsItemSelected(item);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
// 初始化数据
|
||||||
@Override
|
private void initTLogs() {
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
logVos = LogUtil.getLog(null, null);
|
||||||
MenuInflater inflater = getMenuInflater();
|
}
|
||||||
inflater.inflate(R.menu.menu_main, menu);
|
|
||||||
return true;
|
private void showList(List<LogVo> logVosN) {
|
||||||
|
Log.d(TAG, "showList: " + logVosN);
|
||||||
}
|
if (adapter == null) {
|
||||||
|
// 将适配器上的数据传递给listView
|
||||||
}
|
listView = findViewById(R.id.list_view_log);
|
||||||
|
listView.setInterface(this);
|
||||||
|
adapter = new LogAdapter(MainActivity.this, R.layout.item_log, logVosN);
|
||||||
|
|
||||||
|
listView.setAdapter(adapter);
|
||||||
|
} else {
|
||||||
|
adapter.onDateChange(logVosN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
Handler handler = new Handler();
|
||||||
|
handler.postDelayed(() -> {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
//获取最新数据
|
||||||
|
initTLogs();
|
||||||
|
//通知界面显示
|
||||||
|
showList(logVos);
|
||||||
|
//通知listview 刷新数据完毕;
|
||||||
|
listView.refreshComplete();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logDetail(LogVo logVo) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||||
|
builder.setTitle(R.string.details);
|
||||||
|
String simInfo = logVo.getSimInfo();
|
||||||
|
if (simInfo != null) {
|
||||||
|
builder.setMessage(logVo.getFrom() + "\n\n" + logVo.getContent() + "\n\n" + logVo.getSimInfo() + "\n\n" + logVo.getRule() + "\n\n" + aUtil.utc2Local(logVo.getTime()) + "\n\nResponse:" + logVo.getForwardResponse());
|
||||||
|
} else {
|
||||||
|
builder.setMessage(logVo.getFrom() + "\n\n" + logVo.getContent() + "\n\n" + logVo.getRule() + "\n\n" + aUtil.utc2Local(logVo.getTime()) + "\n\nResponse:" + logVo.getForwardResponse());
|
||||||
|
}
|
||||||
|
//删除
|
||||||
|
builder.setNegativeButton(R.string.del, (dialog, which) -> {
|
||||||
|
Long id = logVo.getId();
|
||||||
|
Log.d(TAG, "id = " + id);
|
||||||
|
LogUtil.delLog(id, null);
|
||||||
|
initTLogs(); //初始化数据
|
||||||
|
showList(logVos);
|
||||||
|
Toast.makeText(MainActivity.this, R.string.delete_log_toast, Toast.LENGTH_SHORT).show();
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toClone() {
|
||||||
|
Intent intent = new Intent(this, CloneActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toSetting() {
|
||||||
|
Intent intent = new Intent(this, SettingActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toAbout() {
|
||||||
|
Intent intent = new Intent(this, AboutActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toRuleSetting(View view) {
|
||||||
|
Intent intent = new Intent(this, RuleActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toSendSetting(View view) {
|
||||||
|
Intent intent = new Intent(this, SenderActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanLog(View view) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||||
|
builder.setTitle(R.string.clear_logs_tips)
|
||||||
|
.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
LogUtil.delLog(null, null);
|
||||||
|
initTLogs();
|
||||||
|
adapter.add(logVos);
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
//按返回键不退出回到桌面
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.addCategory(Intent.CATEGORY_HOME);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NonConstantResourceId")
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
// Handle item selection
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.to_clone:
|
||||||
|
toClone();
|
||||||
|
return true;
|
||||||
|
case R.id.to_setting:
|
||||||
|
toSetting();
|
||||||
|
return true;
|
||||||
|
case R.id.to_about:
|
||||||
|
toAbout();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.menu_main, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到通知
|
||||||
|
*
|
||||||
|
* @param type 通知类型
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onReceiveMessage(int type) {
|
||||||
|
Log.d(TAG, "收到通知=" + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除通知
|
||||||
|
*
|
||||||
|
* @param type 通知类型
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onRemovedMessage(int type) {
|
||||||
|
Log.d(TAG, "移除通知=" + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到通知
|
||||||
|
*
|
||||||
|
* @param sbn 状态栏通知
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onReceiveMessage(StatusBarNotification sbn) {
|
||||||
|
if (sbn.getNotification() == null) return;
|
||||||
|
|
||||||
|
//推送通知的应用包名
|
||||||
|
String packageName = sbn.getPackageName();
|
||||||
|
//通知标题
|
||||||
|
String title = sbn.getNotification().extras.get("android.title").toString();
|
||||||
|
//通知内容
|
||||||
|
String text = sbn.getNotification().extras.get("android.text").toString();
|
||||||
|
if (text.isEmpty() && sbn.getNotification().tickerText != null) {
|
||||||
|
text = sbn.getNotification().tickerText.toString();
|
||||||
|
}
|
||||||
|
//通知时间
|
||||||
|
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINESE).format(new Date(sbn.getPostTime()));
|
||||||
|
|
||||||
|
Log.d(TAG, String.format(
|
||||||
|
Locale.getDefault(),
|
||||||
|
"onNotificationPosted:\n应用包名:%s\n消息标题:%s\n消息内容:%s\n消息时间:%s\n",
|
||||||
|
packageName, title, text, time)
|
||||||
|
);
|
||||||
|
|
||||||
|
//不处理空消息
|
||||||
|
if (title.isEmpty() && text.isEmpty()) return;
|
||||||
|
|
||||||
|
SmsVo smsVo = new SmsVo(packageName, text, new Date(), title);
|
||||||
|
Log.d(TAG, "send_msg" + smsVo.toString());
|
||||||
|
SendUtil.send_msg(this, smsVo, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除掉通知栏消息
|
||||||
|
*
|
||||||
|
* @param sbn 状态栏通知
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onRemovedMessage(StatusBarNotification sbn) {
|
||||||
|
Log.d(TAG, "移除掉通知栏消息");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,288 +1,356 @@
|
||||||
package com.idormy.sms.forwarder;
|
package com.idormy.sms.forwarder;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.os.Bundle;
|
import android.content.ComponentName;
|
||||||
import android.text.Editable;
|
import android.content.Intent;
|
||||||
import android.text.TextWatcher;
|
import android.content.pm.PackageManager;
|
||||||
import android.util.Log;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.text.Editable;
|
||||||
import android.widget.EditText;
|
import android.text.TextWatcher;
|
||||||
import android.widget.LinearLayout;
|
import android.util.Log;
|
||||||
import android.widget.Switch;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
import com.idormy.sms.forwarder.utils.KeepAliveUtils;
|
import android.widget.Toast;
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtil;
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
public class SettingActivity extends AppCompatActivity {
|
|
||||||
private final String TAG = "SettingActivity";
|
import com.idormy.sms.forwarder.service.NotifyService;
|
||||||
|
import com.idormy.sms.forwarder.utils.KeepAliveUtils;
|
||||||
@Override
|
import com.idormy.sms.forwarder.utils.SettingUtil;
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
Log.d(TAG, "onCreate");
|
import java.util.Set;
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_setting);
|
public class SettingActivity extends AppCompatActivity {
|
||||||
|
private final String TAG = "SettingActivity";
|
||||||
EditText et_add_extra_device_mark = findViewById(R.id.et_add_extra_device_mark);
|
|
||||||
editAddExtraDeviceMark(et_add_extra_device_mark);
|
private static final int REQUEST_CODE = 9527;
|
||||||
|
private TextView textView;
|
||||||
EditText et_add_extra_sim1 = findViewById(R.id.et_add_extra_sim1);
|
|
||||||
editAddExtraSim1(et_add_extra_sim1);
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
EditText et_add_extra_sim2 = findViewById(R.id.et_add_extra_sim2);
|
Log.d(TAG, "onCreate");
|
||||||
editAddExtraSim2(et_add_extra_sim2);
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_setting);
|
||||||
EditText et_battery_level_alarm = findViewById(R.id.et_battery_level_alarm);
|
|
||||||
editBatteryLevelAlarm(et_battery_level_alarm);
|
EditText et_add_extra_device_mark = findViewById(R.id.et_add_extra_device_mark);
|
||||||
|
editAddExtraDeviceMark(et_add_extra_device_mark);
|
||||||
EditText et_retry_delay_time1 = findViewById(R.id.et_retry_delay_time1);
|
|
||||||
editRetryDelayTime(et_retry_delay_time1, 1);
|
EditText et_add_extra_sim1 = findViewById(R.id.et_add_extra_sim1);
|
||||||
EditText et_retry_delay_time2 = findViewById(R.id.et_retry_delay_time2);
|
editAddExtraSim1(et_add_extra_sim1);
|
||||||
editRetryDelayTime(et_retry_delay_time2, 2);
|
|
||||||
EditText et_retry_delay_time3 = findViewById(R.id.et_retry_delay_time3);
|
EditText et_add_extra_sim2 = findViewById(R.id.et_add_extra_sim2);
|
||||||
editRetryDelayTime(et_retry_delay_time3, 3);
|
editAddExtraSim2(et_add_extra_sim2);
|
||||||
EditText et_retry_delay_time4 = findViewById(R.id.et_retry_delay_time4);
|
|
||||||
editRetryDelayTime(et_retry_delay_time4, 4);
|
EditText et_battery_level_alarm = findViewById(R.id.et_battery_level_alarm);
|
||||||
EditText et_retry_delay_time5 = findViewById(R.id.et_retry_delay_time5);
|
editBatteryLevelAlarm(et_battery_level_alarm);
|
||||||
editRetryDelayTime(et_retry_delay_time5, 5);
|
|
||||||
|
EditText et_retry_delay_time1 = findViewById(R.id.et_retry_delay_time1);
|
||||||
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_sms_template = findViewById(R.id.switch_sms_template);
|
editRetryDelayTime(et_retry_delay_time1, 1);
|
||||||
switchSmsTemplate(switch_sms_template);
|
EditText et_retry_delay_time2 = findViewById(R.id.et_retry_delay_time2);
|
||||||
|
editRetryDelayTime(et_retry_delay_time2, 2);
|
||||||
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_phone = findViewById(R.id.switch_enable_phone);
|
EditText et_retry_delay_time3 = findViewById(R.id.et_retry_delay_time3);
|
||||||
switchEnablePhone(switch_enable_phone);
|
editRetryDelayTime(et_retry_delay_time3, 3);
|
||||||
|
EditText et_retry_delay_time4 = findViewById(R.id.et_retry_delay_time4);
|
||||||
EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
editRetryDelayTime(et_retry_delay_time4, 4);
|
||||||
editSmsTemplate(textSmsTemplate);
|
EditText et_retry_delay_time5 = findViewById(R.id.et_retry_delay_time5);
|
||||||
}
|
editRetryDelayTime(et_retry_delay_time5, 5);
|
||||||
|
|
||||||
//设置转发来电
|
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_sms_template = findViewById(R.id.switch_sms_template);
|
||||||
private void switchEnablePhone(@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_phone) {
|
switchSmsTemplate(switch_sms_template);
|
||||||
switch_enable_phone.setChecked(SettingUtil.getSwitchEnablePhone());
|
|
||||||
|
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_phone = findViewById(R.id.switch_enable_phone);
|
||||||
switch_enable_phone.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
switchEnablePhone(switch_enable_phone);
|
||||||
SettingUtil.switchEnablePhone(isChecked);
|
|
||||||
Log.d(TAG, "onCheckedChanged:" + isChecked);
|
EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
||||||
});
|
editSmsTemplate(textSmsTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置设备名称
|
//设置转发来电
|
||||||
private void editAddExtraDeviceMark(final EditText et_add_extra_device_mark) {
|
private void switchEnablePhone(@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_phone) {
|
||||||
et_add_extra_device_mark.setText(SettingUtil.getAddExtraDeviceMark());
|
switch_enable_phone.setChecked(SettingUtil.getSwitchEnablePhone());
|
||||||
|
|
||||||
et_add_extra_device_mark.addTextChangedListener(new TextWatcher() {
|
switch_enable_phone.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
@Override
|
SettingUtil.switchEnablePhone(isChecked);
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
Log.d(TAG, "onCheckedChanged:" + isChecked);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//设置设备名称
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
private void editAddExtraDeviceMark(final EditText et_add_extra_device_mark) {
|
||||||
|
et_add_extra_device_mark.setText(SettingUtil.getAddExtraDeviceMark());
|
||||||
}
|
|
||||||
|
et_add_extra_device_mark.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
SettingUtil.setAddExtraDeviceMark(et_add_extra_device_mark.getText().toString());
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
//设置SIM1备注
|
|
||||||
private void editAddExtraSim1(final EditText et_add_extra_sim1) {
|
}
|
||||||
et_add_extra_sim1.setText(SettingUtil.getAddExtraSim1());
|
|
||||||
|
@Override
|
||||||
et_add_extra_sim1.addTextChangedListener(new TextWatcher() {
|
public void afterTextChanged(Editable s) {
|
||||||
@Override
|
SettingUtil.setAddExtraDeviceMark(et_add_extra_device_mark.getText().toString());
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//设置SIM1备注
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
private void editAddExtraSim1(final EditText et_add_extra_sim1) {
|
||||||
|
et_add_extra_sim1.setText(SettingUtil.getAddExtraSim1());
|
||||||
}
|
|
||||||
|
et_add_extra_sim1.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
SettingUtil.setAddExtraSim1(et_add_extra_sim1.getText().toString());
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
//设置SIM2备注
|
|
||||||
private void editAddExtraSim2(final EditText et_add_extra_sim2) {
|
}
|
||||||
et_add_extra_sim2.setText(SettingUtil.getAddExtraSim2());
|
|
||||||
|
@Override
|
||||||
et_add_extra_sim2.addTextChangedListener(new TextWatcher() {
|
public void afterTextChanged(Editable s) {
|
||||||
@Override
|
SettingUtil.setAddExtraSim1(et_add_extra_sim1.getText().toString());
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//设置SIM2备注
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
private void editAddExtraSim2(final EditText et_add_extra_sim2) {
|
||||||
|
et_add_extra_sim2.setText(SettingUtil.getAddExtraSim2());
|
||||||
}
|
|
||||||
|
et_add_extra_sim2.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
SettingUtil.setAddExtraSim2(et_add_extra_sim2.getText().toString());
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
//设置低电量报警值
|
|
||||||
private void editBatteryLevelAlarm(final EditText et_battery_level_alarm) {
|
}
|
||||||
et_battery_level_alarm.setText(String.valueOf(SettingUtil.getBatteryLevelAlarm()));
|
|
||||||
|
@Override
|
||||||
et_battery_level_alarm.addTextChangedListener(new TextWatcher() {
|
public void afterTextChanged(Editable s) {
|
||||||
@Override
|
SettingUtil.setAddExtraSim2(et_add_extra_sim2.getText().toString());
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
//设置低电量报警值
|
||||||
}
|
private void editBatteryLevelAlarm(final EditText et_battery_level_alarm) {
|
||||||
|
et_battery_level_alarm.setText(String.valueOf(SettingUtil.getBatteryLevelAlarm()));
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
et_battery_level_alarm.addTextChangedListener(new TextWatcher() {
|
||||||
String batteryLevel = et_battery_level_alarm.getText().toString();
|
@Override
|
||||||
if (!batteryLevel.isEmpty()) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
SettingUtil.setBatteryLevelAlarm(Integer.parseInt(batteryLevel));
|
}
|
||||||
} else {
|
|
||||||
SettingUtil.setBatteryLevelAlarm(0);
|
@Override
|
||||||
}
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
String batteryLevel = et_battery_level_alarm.getText().toString();
|
||||||
//接口请求失败重试
|
if (!batteryLevel.isEmpty()) {
|
||||||
private void editRetryDelayTime(final EditText et_retry_delay_time, final int index) {
|
SettingUtil.setBatteryLevelAlarm(Integer.parseInt(batteryLevel));
|
||||||
et_retry_delay_time.setText(String.valueOf(SettingUtil.getRetryDelayTime(index)));
|
} else {
|
||||||
|
SettingUtil.setBatteryLevelAlarm(0);
|
||||||
et_retry_delay_time.addTextChangedListener(new TextWatcher() {
|
}
|
||||||
@Override
|
}
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
//接口请求失败重试
|
||||||
}
|
private void editRetryDelayTime(final EditText et_retry_delay_time, final int index) {
|
||||||
|
et_retry_delay_time.setText(String.valueOf(SettingUtil.getRetryDelayTime(index)));
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
et_retry_delay_time.addTextChangedListener(new TextWatcher() {
|
||||||
String delayTime = et_retry_delay_time.getText().toString();
|
@Override
|
||||||
if (!delayTime.isEmpty()) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
SettingUtil.setRetryDelayTime(index, Integer.parseInt(delayTime));
|
}
|
||||||
} else {
|
|
||||||
SettingUtil.setRetryDelayTime(index, 0);
|
@Override
|
||||||
}
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
//设置转发时启用自定义模版
|
String delayTime = et_retry_delay_time.getText().toString();
|
||||||
private void switchSmsTemplate(@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_sms_template) {
|
if (!delayTime.isEmpty()) {
|
||||||
boolean isOn = SettingUtil.getSwitchSmsTemplate();
|
SettingUtil.setRetryDelayTime(index, Integer.parseInt(delayTime));
|
||||||
switch_sms_template.setChecked(isOn);
|
} else {
|
||||||
|
SettingUtil.setRetryDelayTime(index, 0);
|
||||||
final LinearLayout layout_sms_template = findViewById(R.id.layout_sms_template);
|
}
|
||||||
layout_sms_template.setVisibility(isOn ? View.VISIBLE : View.GONE);
|
}
|
||||||
final EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
});
|
||||||
|
}
|
||||||
switch_sms_template.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
|
||||||
Log.d(TAG, "onCheckedChanged:" + isChecked);
|
//设置转发时启用自定义模版
|
||||||
layout_sms_template.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
private void switchSmsTemplate(@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_sms_template) {
|
||||||
SettingUtil.switchSmsTemplate(isChecked);
|
boolean isOn = SettingUtil.getSwitchSmsTemplate();
|
||||||
if (!isChecked) {
|
switch_sms_template.setChecked(isOn);
|
||||||
textSmsTemplate.setText("{{来源号码}}\n{{短信内容}}\n{{卡槽信息}}\n{{接收时间}}\n{{设备名称}}");
|
|
||||||
}
|
final LinearLayout layout_sms_template = findViewById(R.id.layout_sms_template);
|
||||||
});
|
layout_sms_template.setVisibility(isOn ? View.VISIBLE : View.GONE);
|
||||||
}
|
final EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
||||||
|
|
||||||
//设置转发信息模版
|
switch_sms_template.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
private void editSmsTemplate(final EditText textSmsTemplate) {
|
Log.d(TAG, "onCheckedChanged:" + isChecked);
|
||||||
textSmsTemplate.setText(SettingUtil.getSmsTemplate());
|
layout_sms_template.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||||
|
SettingUtil.switchSmsTemplate(isChecked);
|
||||||
textSmsTemplate.addTextChangedListener(new TextWatcher() {
|
if (!isChecked) {
|
||||||
@Override
|
textSmsTemplate.setText("{{来源号码}}\n{{短信内容}}\n{{卡槽信息}}\n{{接收时间}}\n{{设备名称}}");
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//设置转发信息模版
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
private void editSmsTemplate(final EditText textSmsTemplate) {
|
||||||
|
textSmsTemplate.setText(SettingUtil.getSmsTemplate());
|
||||||
}
|
|
||||||
|
textSmsTemplate.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
SettingUtil.setSmsTemplate(textSmsTemplate.getText().toString());
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
//插入标签
|
|
||||||
@SuppressLint("NonConstantResourceId")
|
}
|
||||||
public void toInsertLabel(View v) {
|
|
||||||
EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
@Override
|
||||||
textSmsTemplate.setFocusable(true);
|
public void afterTextChanged(Editable s) {
|
||||||
textSmsTemplate.requestFocus();
|
SettingUtil.setSmsTemplate(textSmsTemplate.getText().toString());
|
||||||
switch (v.getId()) {
|
}
|
||||||
case R.id.bt_insert_sender:
|
});
|
||||||
textSmsTemplate.append("{{来源号码}}");
|
}
|
||||||
return;
|
|
||||||
case R.id.bt_insert_content:
|
//插入标签
|
||||||
textSmsTemplate.append("{{短信内容}}");
|
@SuppressLint("NonConstantResourceId")
|
||||||
return;
|
public void toInsertLabel(View v) {
|
||||||
case R.id.bt_insert_extra:
|
EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
||||||
textSmsTemplate.append("{{卡槽信息}}");
|
textSmsTemplate.setFocusable(true);
|
||||||
return;
|
textSmsTemplate.requestFocus();
|
||||||
case R.id.bt_insert_time:
|
switch (v.getId()) {
|
||||||
textSmsTemplate.append("{{接收时间}}");
|
case R.id.bt_insert_sender:
|
||||||
return;
|
textSmsTemplate.append("{{来源号码}}");
|
||||||
case R.id.bt_insert_device_name:
|
return;
|
||||||
textSmsTemplate.append("{{设备名称}}");
|
case R.id.bt_insert_content:
|
||||||
return;
|
textSmsTemplate.append("{{短信内容}}");
|
||||||
default:
|
return;
|
||||||
}
|
case R.id.bt_insert_extra:
|
||||||
}
|
textSmsTemplate.append("{{卡槽信息}}");
|
||||||
|
return;
|
||||||
//恢复初始化配置
|
case R.id.bt_insert_time:
|
||||||
public void initSetting(View view) {
|
textSmsTemplate.append("{{接收时间}}");
|
||||||
|
return;
|
||||||
EditText et_add_extra_device_mark = findViewById(R.id.et_add_extra_device_mark);
|
case R.id.bt_insert_device_name:
|
||||||
et_add_extra_device_mark.setText("");
|
textSmsTemplate.append("{{设备名称}}");
|
||||||
editAddExtraDeviceMark(et_add_extra_device_mark);
|
return;
|
||||||
|
default:
|
||||||
EditText et_add_extra_sim1 = findViewById(R.id.et_add_extra_sim1);
|
}
|
||||||
et_add_extra_sim1.setText("");
|
}
|
||||||
editAddExtraSim1(et_add_extra_sim1);
|
|
||||||
|
//恢复初始化配置
|
||||||
EditText et_add_extra_sim2 = findViewById(R.id.et_add_extra_sim2);
|
public void initSetting(View view) {
|
||||||
et_add_extra_sim2.setText("");
|
|
||||||
editAddExtraSim2(et_add_extra_sim2);
|
EditText et_add_extra_device_mark = findViewById(R.id.et_add_extra_device_mark);
|
||||||
|
et_add_extra_device_mark.setText("");
|
||||||
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_sms_template = findViewById(R.id.switch_sms_template);
|
editAddExtraDeviceMark(et_add_extra_device_mark);
|
||||||
switch_sms_template.setChecked(false);
|
|
||||||
switchSmsTemplate(switch_sms_template);
|
EditText et_add_extra_sim1 = findViewById(R.id.et_add_extra_sim1);
|
||||||
|
et_add_extra_sim1.setText("");
|
||||||
EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
editAddExtraSim1(et_add_extra_sim1);
|
||||||
textSmsTemplate.setText("{{来源号码}}\n{{短信内容}}\n{{卡槽信息}}\n{{接收时间}}\n{{设备名称}}");
|
|
||||||
editSmsTemplate(textSmsTemplate);
|
EditText et_add_extra_sim2 = findViewById(R.id.et_add_extra_sim2);
|
||||||
|
et_add_extra_sim2.setText("");
|
||||||
}
|
editAddExtraSim2(et_add_extra_sim2);
|
||||||
|
|
||||||
public void batterySetting(View view) {
|
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_sms_template = findViewById(R.id.switch_sms_template);
|
||||||
if (KeepAliveUtils.isIgnoreBatteryOptimization(this)) {
|
switch_sms_template.setChecked(false);
|
||||||
Toast.makeText(this, R.string.isIgnored, Toast.LENGTH_SHORT).show();
|
switchSmsTemplate(switch_sms_template);
|
||||||
} else {
|
|
||||||
KeepAliveUtils.ignoreBatteryOptimization(this);
|
EditText textSmsTemplate = findViewById(R.id.text_sms_template);
|
||||||
}
|
textSmsTemplate.setText("{{来源号码}}\n{{短信内容}}\n{{卡槽信息}}\n{{接收时间}}\n{{设备名称}}");
|
||||||
}
|
editSmsTemplate(textSmsTemplate);
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void batterySetting(View view) {
|
||||||
|
if (KeepAliveUtils.isIgnoreBatteryOptimization(this)) {
|
||||||
|
Toast.makeText(this, R.string.isIgnored, Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
KeepAliveUtils.ignoreBatteryOptimization(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求权限
|
||||||
|
*
|
||||||
|
* @param view 控件
|
||||||
|
*/
|
||||||
|
public void requestPermission(View view) {
|
||||||
|
if (!isNLServiceEnabled()) {
|
||||||
|
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
|
||||||
|
startActivityForResult(intent, REQUEST_CODE);
|
||||||
|
} else {
|
||||||
|
showMsg("通知服务已开启");
|
||||||
|
toggleNotificationListenerService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用通知监听服务
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isNLServiceEnabled() {
|
||||||
|
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(this);
|
||||||
|
return packageNames.contains(getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换通知监听器服务
|
||||||
|
*/
|
||||||
|
public void toggleNotificationListenerService() {
|
||||||
|
PackageManager pm = getPackageManager();
|
||||||
|
pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), NotifyService.class),
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||||
|
|
||||||
|
pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), NotifyService.class),
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if (requestCode == REQUEST_CODE) {
|
||||||
|
if (isNLServiceEnabled()) {
|
||||||
|
showMsg("通知服务已开启");
|
||||||
|
toggleNotificationListenerService();
|
||||||
|
} else {
|
||||||
|
showMsg("通知服务未开启");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void showMsg(String msg) {
|
||||||
|
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.idormy.sms.forwarder.notify;
|
||||||
|
|
||||||
|
import android.service.notification.StatusBarNotification;
|
||||||
|
|
||||||
|
public class NotifyHelper {
|
||||||
|
|
||||||
|
private static NotifyHelper instance;
|
||||||
|
|
||||||
|
public static final int N_MESSAGE = 0;
|
||||||
|
public static final int N_CALL = 1;
|
||||||
|
public static final int N_QQ = 2;
|
||||||
|
public static final int N_WX = 3;
|
||||||
|
|
||||||
|
private NotifyListener notifyListener;
|
||||||
|
|
||||||
|
public static NotifyHelper getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new NotifyHelper();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到消息
|
||||||
|
*
|
||||||
|
* @param type 消息类型
|
||||||
|
*/
|
||||||
|
public void onReceive(int type) {
|
||||||
|
if (notifyListener != null) {
|
||||||
|
notifyListener.onReceiveMessage(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到消息
|
||||||
|
*
|
||||||
|
* @param sbn 状态栏通知
|
||||||
|
*/
|
||||||
|
public void onReceive(StatusBarNotification sbn) {
|
||||||
|
if (notifyListener != null) {
|
||||||
|
notifyListener.onReceiveMessage(sbn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除消息
|
||||||
|
*
|
||||||
|
* @param type 消息类型
|
||||||
|
*/
|
||||||
|
public void onRemoved(int type) {
|
||||||
|
if (notifyListener != null) {
|
||||||
|
notifyListener.onRemovedMessage(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除消息
|
||||||
|
*
|
||||||
|
* @param sbn 状态栏通知
|
||||||
|
*/
|
||||||
|
public void onRemoved(StatusBarNotification sbn) {
|
||||||
|
if (notifyListener != null) {
|
||||||
|
notifyListener.onRemovedMessage(sbn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置回调方法
|
||||||
|
*
|
||||||
|
* @param notifyListener 通知监听
|
||||||
|
*/
|
||||||
|
public void setNotifyListener(NotifyListener notifyListener) {
|
||||||
|
this.notifyListener = notifyListener;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.idormy.sms.forwarder.notify;
|
||||||
|
|
||||||
|
import android.service.notification.StatusBarNotification;
|
||||||
|
|
||||||
|
public interface NotifyListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收到通知栏消息
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
void onReceiveMessage(int type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除掉通知栏消息
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
void onRemovedMessage(int type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收到通知栏消息
|
||||||
|
*
|
||||||
|
* @param sbn
|
||||||
|
*/
|
||||||
|
void onReceiveMessage(StatusBarNotification sbn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除掉通知栏消息
|
||||||
|
*
|
||||||
|
* @param sbn
|
||||||
|
*/
|
||||||
|
void onRemovedMessage(StatusBarNotification sbn);
|
||||||
|
}
|
|
@ -76,7 +76,7 @@ public class SendUtil {
|
||||||
|
|
||||||
public static void sendMsgByRuleModelSenderId(final Handler handError, RuleModel ruleModel, SmsVo smsVo, Long senderId) throws Exception {
|
public static void sendMsgByRuleModelSenderId(final Handler handError, RuleModel ruleModel, SmsVo smsVo, Long senderId) throws Exception {
|
||||||
if (senderId == null) {
|
if (senderId == null) {
|
||||||
throw new Exception("先新建并选择发送方");
|
throw new Exception("先新建并选择发送通道");
|
||||||
}
|
}
|
||||||
|
|
||||||
String testSim = smsVo.getSimInfo().substring(0, 4);
|
String testSim = smsVo.getSimInfo().substring(0, 4);
|
||||||
|
@ -92,7 +92,7 @@ public class SendUtil {
|
||||||
|
|
||||||
List<SenderModel> senderModels = SenderUtil.getSender(senderId, null);
|
List<SenderModel> senderModels = SenderUtil.getSender(senderId, null);
|
||||||
if (senderModels.isEmpty()) {
|
if (senderModels.isEmpty()) {
|
||||||
throw new Exception("未找到发送方");
|
throw new Exception("未找到发送通道");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SenderModel senderModel : senderModels
|
for (SenderModel senderModel : senderModels
|
||||||
|
|
|
@ -1,111 +1,109 @@
|
||||||
package com.idormy.sms.forwarder.service;
|
package com.idormy.sms.forwarder.service;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class BatteryService extends Service {
|
public class BatteryService extends Service {
|
||||||
|
|
||||||
private static final String TAG = "BatteryReceiver";
|
private static final String TAG = "BatteryReceiver";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
Log.i(TAG, "onCreate--------------");
|
Log.i(TAG, "onCreate--------------");
|
||||||
IntentFilter batteryFilter = new IntentFilter();
|
IntentFilter batteryFilter = new IntentFilter();
|
||||||
batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||||
registerReceiver(batteryReceiver, batteryFilter);
|
registerReceiver(batteryReceiver, batteryFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart(Intent intent, int startId) {
|
public void onStart(Intent intent, int startId) {
|
||||||
super.onStart(intent, startId);
|
super.onStart(intent, startId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
Log.i(TAG, "onStartCommand--------------");
|
Log.i(TAG, "onStartCommand--------------");
|
||||||
return Service.START_STICKY; //保证service不被杀死
|
return Service.START_STICKY; //保证service不被杀死
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
Log.i(TAG, "onDestroy--------------");
|
Log.i(TAG, "onDestroy--------------");
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
this.unregisterReceiver(batteryReceiver);
|
this.unregisterReceiver(batteryReceiver);
|
||||||
|
}
|
||||||
}
|
|
||||||
|
// 接收电池信息更新的广播
|
||||||
// 接收电池信息更新的广播
|
private final BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
|
||||||
private final BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
|
@SuppressWarnings("unused")
|
||||||
@SuppressWarnings("unused")
|
@Override
|
||||||
@Override
|
public void onReceive(Context context, Intent intent) {
|
||||||
public void onReceive(Context context, Intent intent) {
|
Log.i(TAG, "BatteryReceiver--------------");
|
||||||
Log.i(TAG, "BatteryReceiver--------------");
|
String action = intent.getAction();
|
||||||
String action = intent.getAction();
|
Log.i(TAG, " 0 action:" + action);
|
||||||
Log.i(TAG, " 0 action:" + action);
|
Log.i(TAG, "ACTION_BATTERY_CHANGED");
|
||||||
Log.i(TAG, "ACTION_BATTERY_CHANGED");
|
int status = intent.getIntExtra("status", 0);
|
||||||
int status = intent.getIntExtra("status", 0);
|
int health = intent.getIntExtra("health", 0);
|
||||||
int health = intent.getIntExtra("health", 0);
|
boolean present = intent.getBooleanExtra("present", false);
|
||||||
boolean present = intent.getBooleanExtra("present", false);
|
int level = intent.getIntExtra("level", 0);
|
||||||
int level = intent.getIntExtra("level", 0);
|
int scale = intent.getIntExtra("scale", 0);
|
||||||
int scale = intent.getIntExtra("scale", 0);
|
int icon_small = intent.getIntExtra("icon-small", 0);
|
||||||
int icon_small = intent.getIntExtra("icon-small", 0);
|
int plugged = intent.getIntExtra("plugged", 0);
|
||||||
int plugged = intent.getIntExtra("plugged", 0);
|
int voltage = intent.getIntExtra("voltage", 0);
|
||||||
int voltage = intent.getIntExtra("voltage", 0);
|
int temperature = intent.getIntExtra("temperature", 0);
|
||||||
int temperature = intent.getIntExtra("temperature", 0);
|
String technology = intent.getStringExtra("technology");
|
||||||
String technology = intent.getStringExtra("technology");
|
|
||||||
|
String statusString = "";
|
||||||
String statusString = "";
|
switch (status) {
|
||||||
switch (status) {
|
case BatteryManager.BATTERY_STATUS_UNKNOWN:
|
||||||
case BatteryManager.BATTERY_STATUS_UNKNOWN:
|
statusString = "unknown";
|
||||||
statusString = "unknown";
|
break;
|
||||||
break;
|
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
statusString = "charging";
|
||||||
statusString = "charging";
|
break;
|
||||||
break;
|
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
statusString = "discharging";
|
||||||
statusString = "discharging";
|
break;
|
||||||
break;
|
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
|
||||||
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
|
statusString = "not charging";
|
||||||
statusString = "not charging";
|
break;
|
||||||
break;
|
case BatteryManager.BATTERY_STATUS_FULL:
|
||||||
case BatteryManager.BATTERY_STATUS_FULL:
|
statusString = "full";
|
||||||
statusString = "full";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
String acString = "";
|
||||||
String acString = "";
|
|
||||||
|
switch (plugged) {
|
||||||
switch (plugged) {
|
case BatteryManager.BATTERY_PLUGGED_AC:
|
||||||
case BatteryManager.BATTERY_PLUGGED_AC:
|
acString = "plugged ac";
|
||||||
acString = "plugged ac";
|
break;
|
||||||
break;
|
case BatteryManager.BATTERY_PLUGGED_USB:
|
||||||
case BatteryManager.BATTERY_PLUGGED_USB:
|
acString = "plugged usb";
|
||||||
acString = "plugged usb";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
@SuppressLint("SimpleDateFormat") SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS ");
|
||||||
@SuppressLint("SimpleDateFormat") SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS ");
|
String date = sDateFormat.format(new java.util.Date());
|
||||||
String date = sDateFormat.format(new java.util.Date());
|
|
||||||
|
Log.i(TAG, "battery: date=" + date + ",status " + statusString
|
||||||
Log.i(TAG, "battery: date=" + date + ",status " + statusString
|
+ ",level=" + level + ",scale=" + scale
|
||||||
+ ",level=" + level + ",scale=" + scale
|
+ ",voltage=" + voltage + ",acString=" + acString);
|
||||||
+ ",voltage=" + voltage + ",acString=" + acString);
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,142 +1,174 @@
|
||||||
package com.idormy.sms.forwarder.service;
|
package com.idormy.sms.forwarder.service;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.ComponentName;
|
||||||
import android.content.ContextWrapper;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.ContextWrapper;
|
||||||
import android.content.IntentFilter;
|
import android.content.Intent;
|
||||||
import android.os.BatteryManager;
|
import android.content.IntentFilter;
|
||||||
import android.os.Build;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.IBinder;
|
import android.os.BatteryManager;
|
||||||
import android.util.Log;
|
import android.os.Build;
|
||||||
|
import android.os.IBinder;
|
||||||
import androidx.annotation.Nullable;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.idormy.sms.forwarder.MainActivity;
|
import androidx.annotation.Nullable;
|
||||||
import com.idormy.sms.forwarder.MyApplication;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import com.idormy.sms.forwarder.R;
|
|
||||||
import com.idormy.sms.forwarder.model.vo.SmsVo;
|
import com.idormy.sms.forwarder.MainActivity;
|
||||||
import com.idormy.sms.forwarder.sender.SendUtil;
|
import com.idormy.sms.forwarder.MyApplication;
|
||||||
import com.idormy.sms.forwarder.sender.SenderUtil;
|
import com.idormy.sms.forwarder.R;
|
||||||
import com.idormy.sms.forwarder.utils.PhoneUtils;
|
import com.idormy.sms.forwarder.model.vo.SmsVo;
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtil;
|
import com.idormy.sms.forwarder.sender.SendUtil;
|
||||||
|
import com.idormy.sms.forwarder.sender.SenderUtil;
|
||||||
import java.util.Date;
|
import com.idormy.sms.forwarder.utils.PhoneUtils;
|
||||||
import java.util.Timer;
|
import com.idormy.sms.forwarder.utils.SettingUtil;
|
||||||
import java.util.TimerTask;
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Set;
|
||||||
public class FrontService extends Service {
|
import java.util.Timer;
|
||||||
private static final String TAG = "FrontService";
|
import java.util.TimerTask;
|
||||||
private static final String CHANNEL_ONE_ID = "com.idormy.sms.forwarder";
|
|
||||||
private static final String CHANNEL_ONE_NAME = "com.idormy.sms.forwarderName";
|
public class FrontService extends Service {
|
||||||
|
private static final String TAG = "FrontService";
|
||||||
@SuppressLint("IconColors")
|
private static final String CHANNEL_ONE_ID = "com.idormy.sms.forwarder";
|
||||||
@Override
|
private static final String CHANNEL_ONE_NAME = "com.idormy.sms.forwarderName";
|
||||||
public void onCreate() {
|
private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
|
||||||
super.onCreate();
|
|
||||||
Log.i(TAG, "onCreate");
|
@SuppressLint("IconColors")
|
||||||
Notification.Builder builder = new Notification.Builder(this);
|
@Override
|
||||||
builder.setSmallIcon(R.drawable.ic_forwarder);
|
public void onCreate() {
|
||||||
//OSUtils.ROM_TYPE romType = OSUtils.getRomType();
|
super.onCreate();
|
||||||
//Log.d(TAG, "onCreate: " + romType);
|
Log.i(TAG, "onCreate");
|
||||||
//if (romType == OSUtils.ROM_TYPE.MIUI_ROM) {
|
Notification.Builder builder = new Notification.Builder(this);
|
||||||
builder.setContentTitle(getString(R.string.app_name));
|
builder.setSmallIcon(R.drawable.ic_forwarder);
|
||||||
//}
|
builder.setContentTitle(getString(R.string.app_name));
|
||||||
builder.setContentText(getString(R.string.notification_content));
|
builder.setContentText(getString(R.string.notification_content));
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
@SuppressLint("UnspecifiedImmutableFlag") PendingIntent pendingIntent = PendingIntent.getActivity
|
@SuppressLint("UnspecifiedImmutableFlag") PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
builder.setContentIntent(pendingIntent);
|
||||||
builder.setContentIntent(pendingIntent);
|
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
//修改安卓8.1以上系统报错
|
||||||
//修改安卓8.1以上系统报错
|
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN);
|
||||||
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN);
|
notificationChannel.enableLights(false);//如果使用中的设备支持通知灯,则说明此通知通道是否应显示灯
|
||||||
notificationChannel.enableLights(false);//如果使用中的设备支持通知灯,则说明此通知通道是否应显示灯
|
notificationChannel.setShowBadge(false);//是否显示角标
|
||||||
notificationChannel.setShowBadge(false);//是否显示角标
|
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
|
||||||
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
|
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
manager.createNotificationChannel(notificationChannel);
|
||||||
manager.createNotificationChannel(notificationChannel);
|
builder.setChannelId(CHANNEL_ONE_ID);
|
||||||
builder.setChannelId(CHANNEL_ONE_ID);
|
}
|
||||||
}
|
|
||||||
|
Notification notification = builder.build();
|
||||||
Notification notification = builder.build();
|
startForeground(1, notification);
|
||||||
startForeground(1, notification);
|
|
||||||
|
//检查权限是否获取
|
||||||
//检查权限是否获取
|
//PackageManager pm = getPackageManager();
|
||||||
//PackageManager pm = getPackageManager();
|
//PhoneUtils.CheckPermission(pm, this);
|
||||||
//PhoneUtils.CheckPermission(pm, this);
|
|
||||||
|
//Android8.1以下尝试启动主界面,以便动态获取权限
|
||||||
//Android8.1以下尝试启动主界面,以便动态获取权限
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
startActivity(intent);
|
||||||
startActivity(intent);
|
}
|
||||||
}
|
// 手机重启,未打开app时,主动获取SIM卡信息
|
||||||
// 手机重启,未打开app时,主动获取SIM卡信息
|
if (MyApplication.SimInfoList.isEmpty()) {
|
||||||
if (MyApplication.SimInfoList.isEmpty()) {
|
PhoneUtils.init(this);
|
||||||
PhoneUtils.init(this);
|
MyApplication.SimInfoList = PhoneUtils.getSimMultiInfo();
|
||||||
MyApplication.SimInfoList = PhoneUtils.getSimMultiInfo();
|
}
|
||||||
}
|
|
||||||
|
// 低电量预警
|
||||||
// 低电量预警
|
final int[] alarmTimes = {0}; //通知次数,只通知2次
|
||||||
final int[] alarmTimes = {0}; //通知次数,只通知2次
|
Context context1 = this;
|
||||||
Context context1 = this;
|
SenderUtil.init(context1);
|
||||||
SenderUtil.init(context1);
|
new Timer().schedule(new TimerTask() {
|
||||||
new Timer().schedule(new TimerTask() {
|
@Override
|
||||||
@Override
|
public void run() {
|
||||||
public void run() {
|
int batteryLevel = getBatteryLevel();
|
||||||
int batteryLevel = getBatteryLevel();
|
System.out.println("当前剩余电量:" + batteryLevel + "%");
|
||||||
System.out.println("当前剩余电量:" + batteryLevel + "%");
|
int batteryLevelAlarm = SettingUtil.getBatteryLevelAlarm();
|
||||||
int batteryLevelAlarm = SettingUtil.getBatteryLevelAlarm();
|
if (alarmTimes[0] <= 1 && batteryLevelAlarm > 0 && batteryLevelAlarm <= 100 && (batteryLevel == batteryLevelAlarm || batteryLevel == batteryLevelAlarm - 1)) {
|
||||||
if (alarmTimes[0] <= 1 && batteryLevelAlarm > 0 && batteryLevelAlarm <= 100 && (batteryLevel == batteryLevelAlarm || batteryLevel == batteryLevelAlarm - 1)) {
|
try {
|
||||||
try {
|
alarmTimes[0] = alarmTimes[0] + 1;
|
||||||
alarmTimes[0] = alarmTimes[0] + 1;
|
SmsVo smsVo = new SmsVo("88888888",
|
||||||
SmsVo smsVo = new SmsVo("88888888",
|
"当前剩余电量:" + batteryLevel + "%,已经到达低电量预警阈值,请及时充电!",
|
||||||
"当前剩余电量:" + batteryLevel + "%,已经到达低电量预警阈值,请及时充电!",
|
new Date(),
|
||||||
new Date(),
|
"低电量预警");
|
||||||
"低电量预警");
|
Log.d(TAG, "send_msg" + smsVo.toString());
|
||||||
Log.d(TAG, "send_msg" + smsVo.toString());
|
SendUtil.send_msg(context1, smsVo, 1);
|
||||||
SendUtil.send_msg(context1, smsVo, 1);
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
Log.e(TAG, "getLog e:" + e.getMessage());
|
||||||
Log.e(TAG, "getLog e:" + e.getMessage());
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (batteryLevelAlarm > 0 && batteryLevelAlarm <= 100 && batteryLevel > batteryLevelAlarm) {
|
||||||
if (batteryLevelAlarm > 0 && batteryLevelAlarm <= 100 && batteryLevel > batteryLevelAlarm) {
|
alarmTimes[0] = 0;
|
||||||
alarmTimes[0] = 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
}, 0, 10000);
|
||||||
}, 0, 10000);
|
|
||||||
}
|
if (!isNotificationListenerServiceEnabled(this)) {
|
||||||
|
openNotificationAccess();
|
||||||
@Nullable
|
}
|
||||||
@Override
|
toggleNotificationListenerService();
|
||||||
public IBinder onBind(Intent intent) {
|
}
|
||||||
return null;
|
|
||||||
}
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
@Override
|
//进行自动重启
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
Intent intent = new Intent(FrontService.this, FrontService.class);
|
||||||
Log.i(TAG, "flags: " + flags + " startId: " + startId);
|
//重新开启服务
|
||||||
return START_STICKY; //保证service不被杀死
|
startService(intent);
|
||||||
}
|
stopForeground(true);
|
||||||
|
super.onDestroy();
|
||||||
//获取当前电量
|
}
|
||||||
@SuppressLint("ObsoleteSdkInt")
|
|
||||||
private int getBatteryLevel() {
|
@Override
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
|
//return super.onStartCommand(intent, flags, startId);
|
||||||
return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
|
return START_STICKY; //保证service不被杀死
|
||||||
} else {
|
}
|
||||||
Intent intent = new ContextWrapper(getApplicationContext()).
|
|
||||||
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
@Nullable
|
||||||
return (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
|
@Override
|
||||||
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
public IBinder onBind(Intent intent) {
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//获取当前电量
|
||||||
|
@SuppressLint("ObsoleteSdkInt")
|
||||||
|
private int getBatteryLevel() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
|
||||||
|
return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
|
||||||
|
} else {
|
||||||
|
Intent intent = new ContextWrapper(getApplicationContext()).
|
||||||
|
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||||
|
return (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
|
||||||
|
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleNotificationListenerService() {
|
||||||
|
PackageManager pm = getPackageManager();
|
||||||
|
pm.setComponentEnabledSetting(new ComponentName(this, NotifyService.class),
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||||
|
|
||||||
|
pm.setComponentEnabledSetting(new ComponentName(this, NotifyService.class),
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isNotificationListenerServiceEnabled(Context context) {
|
||||||
|
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
|
||||||
|
return packageNames.contains(context.getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openNotificationAccess() {
|
||||||
|
startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.idormy.sms.forwarder.service;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.service.notification.NotificationListenerService;
|
||||||
|
import android.service.notification.StatusBarNotification;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.idormy.sms.forwarder.notify.NotifyHelper;
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||||
|
public class NotifyService extends NotificationListenerService {
|
||||||
|
|
||||||
|
public static final String TAG = "NotifyService";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布通知
|
||||||
|
*
|
||||||
|
* @param sbn 状态栏通知
|
||||||
|
*/
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||||
|
@Override
|
||||||
|
public void onNotificationPosted(StatusBarNotification sbn) {
|
||||||
|
if (sbn.getNotification() == null) return;
|
||||||
|
Log.d(TAG, sbn.getPackageName());
|
||||||
|
NotifyHelper.getInstance().onReceive(sbn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知已删除
|
||||||
|
*
|
||||||
|
* @param sbn 状态栏通知
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onNotificationRemoved(StatusBarNotification sbn) {
|
||||||
|
Log.d(TAG, sbn.getPackageName());
|
||||||
|
NotifyHelper.getInstance().onRemoved(sbn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听断开
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onListenerDisconnected() {
|
||||||
|
Log.d(TAG, "通知侦听器断开连接 - 请求重新绑定");
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
requestRebind(new ComponentName(this, NotificationListenerService.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -545,12 +545,13 @@ public class PhoneUtils {
|
||||||
boolean permission_read_call_log = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_CALL_LOG", that.getPackageName()));
|
boolean permission_read_call_log = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_CALL_LOG", that.getPackageName()));
|
||||||
boolean permission_read_contacts = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_CONTACTS", that.getPackageName()));
|
boolean permission_read_contacts = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_CONTACTS", that.getPackageName()));
|
||||||
boolean permission_battery_stats = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.BATTERY_STATS", that.getPackageName()));
|
boolean permission_battery_stats = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.BATTERY_STATS", that.getPackageName()));
|
||||||
|
boolean permission_bind_notification_listener_service = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.BIND_NOTIFICATION_LISTENER_SERVICE", that.getPackageName()));
|
||||||
|
|
||||||
if (!(permission_internet && permission_receive_boot && permission_foreground_service &&
|
if (!(permission_internet && permission_receive_boot && permission_foreground_service &&
|
||||||
permission_read_external_storage && permission_write_external_storage &&
|
permission_read_external_storage && permission_write_external_storage &&
|
||||||
permission_receive_sms && permission_read_sms && permission_send_sms &&
|
permission_receive_sms && permission_read_sms && permission_send_sms &&
|
||||||
permission_read_call_log && permission_read_contacts &&
|
permission_read_call_log && permission_read_contacts &&
|
||||||
permission_read_phone_state && permission_read_phone_numbers && permission_battery_stats)) {
|
permission_read_phone_state && permission_read_phone_numbers && permission_battery_stats && permission_bind_notification_listener_service)) {
|
||||||
ActivityCompat.requestPermissions((Activity) that, new String[]{
|
ActivityCompat.requestPermissions((Activity) that, new String[]{
|
||||||
Manifest.permission.INTERNET,
|
Manifest.permission.INTERNET,
|
||||||
Manifest.permission.RECEIVE_BOOT_COMPLETED,
|
Manifest.permission.RECEIVE_BOOT_COMPLETED,
|
||||||
|
@ -565,6 +566,7 @@ public class PhoneUtils {
|
||||||
Manifest.permission.READ_PHONE_NUMBERS,
|
Manifest.permission.READ_PHONE_NUMBERS,
|
||||||
Manifest.permission.FOREGROUND_SERVICE,
|
Manifest.permission.FOREGROUND_SERVICE,
|
||||||
Manifest.permission.BATTERY_STATS,
|
Manifest.permission.BATTERY_STATS,
|
||||||
|
Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE,
|
||||||
}, 0x01);
|
}, 0x01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ public class SmsUtil {
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
static Context context;
|
static Context context;
|
||||||
|
|
||||||
|
|
||||||
public static void init(Context context1) {
|
public static void init(Context context1) {
|
||||||
synchronized (hasInit) {
|
synchronized (hasInit) {
|
||||||
if (hasInit) return;
|
if (hasInit) return;
|
||||||
|
|
|
@ -1,72 +1,72 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.idormy.sms.forwarder.RefreshListView
|
<com.idormy.sms.forwarder.RefreshListView
|
||||||
android:id="@+id/list_view_log"
|
android:id="@+id/list_view_log"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_margin="5dp"
|
android:layout_margin="5dp"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/help_tip"
|
android:id="@+id/help_tip"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/log_tips"
|
android:text="@string/log_tips"
|
||||||
android:textColor="@color/colorPrimary" />
|
android:textColor="@color/colorPrimary" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="cleanLog"
|
android:onClick="cleanLog"
|
||||||
android:text="@string/bt_refresh_log"
|
android:text="@string/bt_refresh_log"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toRuleSetting"
|
android:onClick="toRuleSetting"
|
||||||
android:text="@string/rule_setting"
|
android:text="@string/rule_setting"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:layout_marginLeft="10dp"
|
android:layout_marginLeft="10dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginRight="10dp"
|
android:layout_marginRight="10dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toSendSetting"
|
android:onClick="toSendSetting"
|
||||||
android:text="@string/sender_setting"
|
android:text="@string/sender_setting"
|
||||||
tools:ignore="ButtonStyle" />
|
tools:ignore="ButtonStyle" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1,459 +1,480 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/device_name"
|
android:text="@string/device_name"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_add_extra_device_mark"
|
android:id="@+id/et_add_extra_device_mark"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/sim1_remark"
|
android:text="@string/sim1_remark"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:text="@string/carrier_mobile"
|
android:text="@string/carrier_mobile"
|
||||||
android:textSize="9sp"
|
android:textSize="9sp"
|
||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_add_extra_sim1"
|
android:id="@+id/et_add_extra_sim1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/sim2_remark"
|
android:text="@string/sim2_remark"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:text="@string/carrier_mobile"
|
android:text="@string/carrier_mobile"
|
||||||
android:textSize="9sp"
|
android:textSize="9sp"
|
||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_add_extra_sim2"
|
android:id="@+id/et_add_extra_sim2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/low_power_alarm_threshold"
|
android:text="@string/low_power_alarm_threshold"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:text="@string/low_power_alarm_threshold_tips"
|
android:text="@string/low_power_alarm_threshold_tips"
|
||||||
android:textSize="9sp"
|
android:textSize="9sp"
|
||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_battery_level_alarm"
|
android:id="@+id/et_battery_level_alarm"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/retry_interval"
|
android:text="@string/retry_interval"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:text="@string/retry_interval_tips"
|
android:text="@string/retry_interval_tips"
|
||||||
android:textSize="9sp"
|
android:textSize="9sp"
|
||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_retry_delay_time1"
|
android:id="@+id/et_retry_delay_time1"
|
||||||
android:layout_width="42dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_retry_delay_time2"
|
android:id="@+id/et_retry_delay_time2"
|
||||||
android:layout_width="42dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_retry_delay_time3"
|
android:id="@+id/et_retry_delay_time3"
|
||||||
android:layout_width="42dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_retry_delay_time4"
|
android:id="@+id/et_retry_delay_time4"
|
||||||
android:layout_width="42dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_retry_delay_time5"
|
android:id="@+id/et_retry_delay_time5"
|
||||||
android:layout_width="42dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:ems="16"
|
android:ems="16"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/forward_missed_calls"
|
android:text="@string/forward_missed_calls"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:ignore="RelativeOverlap" />
|
tools:ignore="RelativeOverlap" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/switch_enable_phone"
|
android:id="@+id/switch_enable_phone"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="3"
|
android:layout_weight="3"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="3"
|
android:layout_weight="3"
|
||||||
android:text="@string/enable_custom_templates"
|
android:text="@string/enable_custom_templates"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/switch_sms_template"
|
android:id="@+id/switch_sms_template"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="3"
|
android:layout_weight="3"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layout_sms_template"
|
android:id="@+id/layout_sms_template"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="15dp"
|
android:padding="15dp"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/custom_templates"
|
android:text="@string/custom_templates"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:text="@string/custom_templates_tips"
|
android:text="@string/custom_templates_tips"
|
||||||
android:textSize="11sp" />
|
android:textSize="11sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/text_sms_template"
|
android:id="@+id/text_sms_template"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:autofillHints=""
|
android:autofillHints=""
|
||||||
android:inputType="textMultiLine"
|
android:inputType="textMultiLine"
|
||||||
android:gravity="left|top"
|
android:gravity="left|top"
|
||||||
android:minLines="1"
|
android:minLines="1"
|
||||||
android:text=""
|
android:text=""
|
||||||
tools:ignore="LabelFor" />
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/bt_insert_sender"
|
android:id="@+id/bt_insert_sender"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toInsertLabel"
|
android:onClick="toInsertLabel"
|
||||||
android:text="@string/insert_sender"
|
android:text="@string/insert_sender"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/bt_insert_content"
|
android:id="@+id/bt_insert_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toInsertLabel"
|
android:onClick="toInsertLabel"
|
||||||
android:text="@string/insert_content"
|
android:text="@string/insert_content"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/bt_insert_extra"
|
android:id="@+id/bt_insert_extra"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toInsertLabel"
|
android:onClick="toInsertLabel"
|
||||||
android:text="@string/insert_extra"
|
android:text="@string/insert_extra"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/bt_insert_time"
|
android:id="@+id/bt_insert_time"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toInsertLabel"
|
android:onClick="toInsertLabel"
|
||||||
android:text="@string/insert_time"
|
android:text="@string/insert_time"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/bt_insert_device_name"
|
android:id="@+id/bt_insert_device_name"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="toInsertLabel"
|
android:onClick="toInsertLabel"
|
||||||
android:text="@string/insert_device_name"
|
android:text="@string/insert_device_name"
|
||||||
tools:ignore="ButtonStyle,NestedWeights" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="10dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@android:color/white"
|
||||||
android:onClick="initSetting"
|
android:gravity="center_vertical"
|
||||||
android:padding="0dp"
|
android:orientation="horizontal"
|
||||||
android:text="@string/init_setting" />
|
android:padding="15dp">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_weight="1"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:onClick="batterySetting"
|
android:onClick="batterySetting"
|
||||||
android:padding="0dp"
|
android:text="@string/battery_setting"
|
||||||
android:text="@string/battery_setting" />
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
</LinearLayout>
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@color/colorPrimary"
|
||||||
|
android:onClick="requestPermission"
|
||||||
|
android:text="@string/request_permission"
|
||||||
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@color/colorBlueGreyDark"
|
||||||
|
android:onClick="initSetting"
|
||||||
|
android:text="@string/init_setting"
|
||||||
|
tools:ignore="ButtonStyle,NestedWeights" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
|
@ -159,6 +159,7 @@
|
||||||
<string name="insert_device_name">Device</string>
|
<string name="insert_device_name">Device</string>
|
||||||
<string name="init_setting">Restore initial Setting</string>
|
<string name="init_setting">Restore initial Setting</string>
|
||||||
<string name="battery_setting">Battery Optimization</string>
|
<string name="battery_setting">Battery Optimization</string>
|
||||||
|
<string name="request_permission">Request Notify Permission</string>
|
||||||
<string name="unknown_number">Unknown Number</string>
|
<string name="unknown_number">Unknown Number</string>
|
||||||
<string name="calling">Incoming telegram</string>
|
<string name="calling">Incoming telegram</string>
|
||||||
<string name="unsupport">Your phone does not support this setting</string>
|
<string name="unsupport">Your phone does not support this setting</string>
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
<string name="clone">一键克隆</string>
|
<string name="clone">一键克隆</string>
|
||||||
<string name="setting">设置</string>
|
<string name="setting">设置</string>
|
||||||
<string name="about">关于</string>
|
<string name="about">关于</string>
|
||||||
<string name="rule_setting">设置转发规则</string>
|
<string name="rule_setting">转发规则</string>
|
||||||
<string name="sender_setting">设置发送方</string>
|
<string name="sender_setting">发送通道</string>
|
||||||
<string name="log_tips">提示:置顶下拉刷新,长按删除单条记录</string>
|
<string name="log_tips">提示:置顶下拉刷新,长按删除单条记录</string>
|
||||||
<string name="rule_tips">提示:新建规则点击“添加”,长按删除/点击编辑已有</string>
|
<string name="rule_tips">提示:新建规则点击“添加”,长按删除/点击编辑已有</string>
|
||||||
<string name="sender_tips">提示:新建发送方点击“添加”,长按删除/点击编辑已有</string>
|
<string name="sender_tips">提示:新建发送通道点击“添加”,长按删除/点击编辑已有</string>
|
||||||
<!--AboutActivity-->
|
<!--AboutActivity-->
|
||||||
<string name="version">当前版本</string>
|
<string name="version">当前版本</string>
|
||||||
<string name="check_for_updates">检查新版本</string>
|
<string name="check_for_updates">检查新版本</string>
|
||||||
|
@ -50,9 +50,9 @@
|
||||||
<string name="delete_rule_title">规则删除确认</string>
|
<string name="delete_rule_title">规则删除确认</string>
|
||||||
<string name="delete_rule_tips">确定删除该条规则?</string>
|
<string name="delete_rule_tips">确定删除该条规则?</string>
|
||||||
<string name="delete_rule_toast">该条规则已经删除!</string>
|
<string name="delete_rule_toast">该条规则已经删除!</string>
|
||||||
<string name="new_sender_first">请先创建发送方再选择</string>
|
<string name="new_sender_first">请先创建发送通道再选择</string>
|
||||||
<string name="add_sender_first">请先去设置发送方页面添加</string>
|
<string name="add_sender_first">请先去设置发送通道页面添加</string>
|
||||||
<string name="select_sender">选择发送方</string>
|
<string name="select_sender">选择发送通道</string>
|
||||||
<string name="rule_tester">规则测试</string>
|
<string name="rule_tester">规则测试</string>
|
||||||
<string name="new_forwarding_rule">添加转发规则</string>
|
<string name="new_forwarding_rule">添加转发规则</string>
|
||||||
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
||||||
|
@ -72,11 +72,11 @@
|
||||||
<string name="btn_regex">正则匹配</string>
|
<string name="btn_regex">正则匹配</string>
|
||||||
<string name="match_value">设置匹配的值</string>
|
<string name="match_value">设置匹配的值</string>
|
||||||
<!--SenderActivity-->
|
<!--SenderActivity-->
|
||||||
<string name="invalid_sender">异常的发送方类型,自动删除!</string>
|
<string name="invalid_sender">异常的发送通道类型,自动删除!</string>
|
||||||
<string name="delete_sender_title">发送方删除确认</string>
|
<string name="delete_sender_title">发送通道删除确认</string>
|
||||||
<string name="delete_sender_tips">确定删除该条发送方?</string>
|
<string name="delete_sender_tips">确定删除该条发送通道?</string>
|
||||||
<string name="delete_sender_toast">该条发送方已经删除!</string>
|
<string name="delete_sender_toast">该条发送通道已经删除!</string>
|
||||||
<string name="add_sender_title">选择发送方类型</string>
|
<string name="add_sender_title">选择发送通道类型</string>
|
||||||
<string name="not_supported">暂不支持这种转发</string>
|
<string name="not_supported">暂不支持这种转发</string>
|
||||||
<string name="setdingdingtitle">设置钉钉机器人</string>
|
<string name="setdingdingtitle">设置钉钉机器人</string>
|
||||||
<string name="setemailtitle">设置邮箱</string>
|
<string name="setemailtitle">设置邮箱</string>
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<string name="invalid_webhook">webHook 不能为空</string>
|
<string name="invalid_webhook">webHook 不能为空</string>
|
||||||
<string name="invalid_at_mobiles">指定成员 不能为空 或者 选择@all</string>
|
<string name="invalid_at_mobiles">指定成员 不能为空 或者 选择@all</string>
|
||||||
<string name="invalid_phone_num">接收手机号不能为空</string>
|
<string name="invalid_phone_num">接收手机号不能为空</string>
|
||||||
<string name="new_sender">添加发送方</string>
|
<string name="new_sender">添加发送通道</string>
|
||||||
<string name="set_bark_name">设置分组名称</string>
|
<string name="set_bark_name">设置分组名称</string>
|
||||||
<string name="set_bark_server">设置Bark-Server地址,示例:https://bark.bms.ink/XXXXXXXX/</string>
|
<string name="set_bark_server">设置Bark-Server地址,示例:https://bark.bms.ink/XXXXXXXX/</string>
|
||||||
<string name="set_bark_icon">设置推送消息图标(可选),示例:http://day.app/assets/images/avatar.jpg</string>
|
<string name="set_bark_icon">设置推送消息图标(可选),示例:http://day.app/assets/images/avatar.jpg</string>
|
||||||
|
@ -157,8 +157,9 @@
|
||||||
<string name="insert_extra">卡槽信息</string>
|
<string name="insert_extra">卡槽信息</string>
|
||||||
<string name="insert_time">接收时间</string>
|
<string name="insert_time">接收时间</string>
|
||||||
<string name="insert_device_name">设备名称</string>
|
<string name="insert_device_name">设备名称</string>
|
||||||
<string name="init_setting">恢复初始化配置</string>
|
<string name="init_setting">恢复默认配置</string>
|
||||||
<string name="battery_setting">设置电池优化</string>
|
<string name="battery_setting">设置电池优化</string>
|
||||||
|
<string name="request_permission">请求通知权限</string>
|
||||||
<string name="unknown_number">未知号码</string>
|
<string name="unknown_number">未知号码</string>
|
||||||
<string name="calling">来电</string>
|
<string name="calling">来电</string>
|
||||||
<string name="unsupport">您的手机不支持此设置</string>
|
<string name="unsupport">您的手机不支持此设置</string>
|
||||||
|
@ -174,7 +175,7 @@
|
||||||
<string name="post">POST</string>
|
<string name="post">POST</string>
|
||||||
<string name="get">GET</string>
|
<string name="get">GET</string>
|
||||||
<string name="local_ip">本机IP:</string>
|
<string name="local_ip">本机IP:</string>
|
||||||
<string name="operating_instruction">操作说明:\n1.请保持新旧手机在同一个WiFi网络下,且没有开启隔离\n2.旧手机直接点【发送】按钮,获取到【服务端IP】\n3.新手机填写【服务端IP】后,点【接收】按钮\n【注意】新手机接收后,发送方、转发规则将完全被覆盖,清空历史记录!</string>
|
<string name="operating_instruction">操作说明:\n1.新旧手机连接同一个WiFi网络(禁用AP隔离)\n2.旧手机直接点【发送】按钮,获取到【服务端IP】\n3.新手机填写【服务端IP】后,点【接收】按钮\n【注意】新手机接收后,发送通道、转发规则将完全被覆盖,清空历史记录!</string>
|
||||||
<string name="send">发送</string>
|
<string name="send">发送</string>
|
||||||
<string name="stop">停止</string>
|
<string name="stop">停止</string>
|
||||||
<string name="old_mobile_phone">我是旧手机</string>
|
<string name="old_mobile_phone">我是旧手机</string>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# 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
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
rootProject.name = "SmsForwarder"
|
||||||
include ':app'
|
include ':app'
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#Fri Jul 16 10:33:23 CST 2021
|
#Fri Jul 16 10:33:23 CST 2021
|
||||||
versionName=2.1.1
|
versionName=2.2.0
|
||||||
versionCode=29
|
versionCode=30
|
||||||
|
|
Loading…
Reference in New Issue