Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e8f666802 | |||
| 884aefc366 | |||
| 2c84258ae2 |
@@ -43,6 +43,6 @@ dependencies {
|
|||||||
implementation 'com.google.android.material:material:1.3.0'
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?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"
|
||||||
|
package="com.nbee.echolink"
|
||||||
|
android:sharedUserId="android.uid.system"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
@@ -21,6 +23,7 @@
|
|||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".EchoLink"
|
android:name=".EchoLink"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -216,8 +216,16 @@ public class MonitorService extends Service {
|
|||||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
// 创建一个意图,指定当闹钟触发时要执行的广播接收器
|
// 创建一个意图,指定当闹钟触发时要执行的广播接收器
|
||||||
Intent intent = new Intent(context, HeartbeatAlarmReceiver.class);
|
Intent intent = new Intent(context, HeartbeatAlarmReceiver.class);
|
||||||
// 根据意图和标志位创建一个唯一的PendingIntent,系统通过这个PendingIntent触发广播
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
// 根据Android版本选择合适的标志位创建一个唯一的PendingIntent
|
||||||
|
PendingIntent pendingIntent = null;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
// Android 12及以上版本需要指定FLAG_IMMUTABLE或FLAG_MUTABLE
|
||||||
|
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
|
||||||
|
} else {
|
||||||
|
// 早期版本不需要指定这些标志
|
||||||
|
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// 计算心跳事件的触发间隔,单位为毫秒
|
// 计算心跳事件的触发间隔,单位为毫秒
|
||||||
long intervalMillis = HEARTBEAT_INTERVAL_MINUTES * 60 * 1000; // 10分钟的毫秒数
|
long intervalMillis = HEARTBEAT_INTERVAL_MINUTES * 60 * 1000; // 10分钟的毫秒数
|
||||||
@@ -235,4 +243,5 @@ public class MonitorService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.nbee.echolink.model.WeChatMsg;
|
|||||||
import com.nbee.echolink.utils.HandleNoticeUtils;
|
import com.nbee.echolink.utils.HandleNoticeUtils;
|
||||||
import com.nbee.echolink.utils.NetworkUtils;
|
import com.nbee.echolink.utils.NetworkUtils;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -27,6 +28,7 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
private static final List<String> notAllowList = Arrays.asList("com.github.kr328.clash","com.google.android.dialer",
|
private static final List<String> notAllowList = Arrays.asList("com.github.kr328.clash","com.google.android.dialer",
|
||||||
"com.google.android.apps.messaging");
|
"com.google.android.apps.messaging");
|
||||||
private HandleNoticeUtils handleNoticeUtils;
|
private HandleNoticeUtils handleNoticeUtils;
|
||||||
|
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
||||||
private NetworkUtils networkUtil;
|
private NetworkUtils networkUtil;
|
||||||
private final HashMap<String, Long> recentLogs = new HashMap<>();
|
private final HashMap<String, Long> recentLogs = new HashMap<>();
|
||||||
private final Handler logCleanerHandler = new Handler(Looper.getMainLooper());
|
private final Handler logCleanerHandler = new Handler(Looper.getMainLooper());
|
||||||
@@ -46,40 +48,52 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bundle extras = sbn.getNotification().extras;
|
Bundle extras = sbn.getNotification().extras;
|
||||||
CharSequence titleCharSequence = extras.getCharSequence(Notification.EXTRA_TITLE);
|
String title = getNotificationText(extras, Notification.EXTRA_TITLE);
|
||||||
String title = titleCharSequence != null ? titleCharSequence.toString() : null;
|
String content = getNotificationText(extras, Notification.EXTRA_TEXT);
|
||||||
String content = extras.getString(Notification.EXTRA_TEXT);
|
|
||||||
String tickerText = sbn.getNotification().tickerText != null ? sbn.getNotification().tickerText.toString() : "";
|
String tickerText = sbn.getNotification().tickerText != null ? sbn.getNotification().tickerText.toString() : "";
|
||||||
String logMessage = String.format("packageName: %s,title: %s,content: %s,tickerText: %s", packageName, title, content, tickerText);
|
String logMessage = String.format("packageName: %s, title: %s, content: %s, tickerText: %s", packageName, title, content, tickerText);
|
||||||
String appName = handleNoticeUtils.messageHandle(packageName);
|
|
||||||
|
|
||||||
if ("微信".equals(appName) && tickerText.contains(":")) {
|
if (!shouldPrintLog(logMessage)) {
|
||||||
|
return; // 如果在30秒内已打印过,则跳过
|
||||||
|
}
|
||||||
|
|
||||||
|
String appName = handleNoticeUtils.messageHandle(packageName);
|
||||||
|
if ("微信".equals(appName)) {
|
||||||
|
handleWeChatNotification(packageName, title, tickerText);
|
||||||
|
}
|
||||||
|
|
||||||
|
Timber.d(logMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNotificationText(Bundle extras, String key) {
|
||||||
|
CharSequence charSequence = extras.getCharSequence(key);
|
||||||
|
return charSequence != null ? charSequence.toString() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleWeChatNotification(String packageName, String title, String tickerText) {
|
||||||
|
if (tickerText.contains(":")) {
|
||||||
String[] parts = tickerText.split(":", 2);
|
String[] parts = tickerText.split(":", 2);
|
||||||
String sender = parts[0].trim(); // 去除两端的空格
|
if (parts.length < 2) return; // 安全检查,确保不会因数组越界而崩溃
|
||||||
String message = parts.length > 1 ? parts[1].trim() : ""; // 同样去除两端的空格
|
|
||||||
|
String sender = parts[0].trim();
|
||||||
|
String message = parts[1].trim();
|
||||||
WeChatMsg weChatMsg = new WeChatMsg();
|
WeChatMsg weChatMsg = new WeChatMsg();
|
||||||
weChatMsg.setPackageName(packageName);
|
weChatMsg.setPackageName(packageName);
|
||||||
weChatMsg.setSender(sender);
|
weChatMsg.setSender(sender);
|
||||||
weChatMsg.setMessage(message);
|
weChatMsg.setMessage(message);
|
||||||
weChatMsg.setTitle(title);
|
weChatMsg.setTitle(title);
|
||||||
weChatMsg.setAppName(appName);
|
weChatMsg.setAppName("微信");
|
||||||
weChatMsg.setCurrentTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date()));
|
weChatMsg.setCurrentTime(DATE_FORMAT.format(new Date()));
|
||||||
|
|
||||||
Timber.d("准备发送微信消息: %s", weChatMsg);
|
try {
|
||||||
// 异步执行网络请求
|
Timber.d("准备将接受的微信通知转发: %s", weChatMsg);
|
||||||
networkUtil.postRequest(weChatMsg);
|
networkUtil.postRequest(weChatMsg);
|
||||||
return;
|
} catch (Exception e) {
|
||||||
|
Timber.e(e, "转发送微信通知失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否在30秒内已打印过相同内容
|
|
||||||
if (!shouldPrintLog(logMessage)) {
|
|
||||||
return; // 如果在30秒内已打印过,则跳过
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timber.d(logMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotificationRemoved(StatusBarNotification sbn) {
|
public void onNotificationRemoved(StatusBarNotification sbn) {
|
||||||
// 当通知被移除时调用
|
// 当通知被移除时调用
|
||||||
|
|||||||
Reference in New Issue
Block a user