Compare commits

...

9 Commits

Author SHA1 Message Date
wangsiyuan ac624c70b2 更新 strings.xml 2023-12-08 20:55:38 +08:00
wangsiyuan 030e8250e6 创建 HeartbeatWorker.java 2023-12-08 20:55:35 +08:00
wangsiyuan c0548705a2 更新 DeviceInfoUtils.java 2023-12-08 20:55:32 +08:00
wangsiyuan 6ae23c1e2f 创建 DeviceInfo.java 2023-12-08 20:55:28 +08:00
wangsiyuan bfc5a741a6 更新 MainActivity.java 2023-12-08 20:55:24 +08:00
wangsiyuan cf5039ae63 更新 EchoLink.java 2023-12-08 20:55:18 +08:00
wangsiyuan 46fe0c6d24 删除 DeviceInfo.java 2023-12-08 20:55:14 +08:00
wangsiyuan e9b769be85 更新 AndroidManifest.xml 2023-12-08 20:55:12 +08:00
wangsiyuan cb660865a1 更新 build.gradle 2023-12-08 20:55:05 +08:00
9 changed files with 173 additions and 31 deletions

View File

@ -37,7 +37,8 @@ dependencies {
implementation 'com.google.code.gson:gson:2.10'
// https://mvnrepository.com/artifact/com.jakewharton.timber/timber
implementation 'com.jakewharton.timber:timber:5.0.1'
// WorkManager
implementation "androidx.work:work-runtime:2.7.0"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACTION_NOTIFICATION_LISTENER_SETTINGS" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

View File

@ -1,11 +0,0 @@
package com.nbee.echolink;
import android.os.Build;
public class DeviceInfo {
public static int getApiVersion() {
return Build.VERSION.SDK_INT;
}
}

View File

@ -1,17 +1,40 @@
package com.nbee.echolink;
import android.app.Application;
import android.content.Context;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import com.nbee.echolink.utils.HeartbeatWorker;
import java.util.concurrent.TimeUnit;
import timber.log.Timber;
public class EchoLink extends Application {
private static final int EXECUTION_INTERVAL = 15; // 示例15分钟
@Override
public void onCreate() {
super.onCreate();
// 植入 Timber
Timber.plant(new FileLoggingTree(this));
// 打印日志文件的路径
Timber.d("Log file path: " + this.getFilesDir() + "/logs/echoLink.log");
// 安排定时任务
doScheduledTask(this);
}
private void doScheduledTask(Context context){
Timber.d("start do scheduled task");
PeriodicWorkRequest heartbeatWorkRequest =
new PeriodicWorkRequest.Builder(HeartbeatWorker.class, EXECUTION_INTERVAL, TimeUnit.MINUTES)
.build();
// 安排周期性工作
WorkManager.getInstance(context).enqueueUniquePeriodicWork("HeartbeatWork",
ExistingPeriodicWorkPolicy.KEEP,
heartbeatWorkRequest);
}
}

View File

@ -10,9 +10,13 @@ import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import com.nbee.echolink.service.MonitorService;
import com.nbee.echolink.utils.BatteryOptimizationUtil;
import com.nbee.echolink.utils.HeartbeatWorker;
import com.nbee.echolink.utils.PermissionUtils;
import com.nbee.echolink.utils.ShellUtils;
@ -20,6 +24,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import timber.log.Timber;
@ -98,5 +103,4 @@ public class MainActivity extends AppCompatActivity {
return "读取日志文件时出错";
}
}
}

View File

@ -0,0 +1,49 @@
package com.nbee.echolink.model;
public class DeviceInfo {
private String deviceBrand;
private String deviceModel;
private String androidVersion;
public DeviceInfo() {
}
public DeviceInfo(String deviceBrand, String deviceModel, String androidVersion) {
this.deviceBrand = deviceBrand;
this.deviceModel = deviceModel;
this.androidVersion = androidVersion;
}
public String getDeviceBrand() {
return deviceBrand;
}
public void setDeviceBrand(String deviceBrand) {
this.deviceBrand = deviceBrand;
}
public String getDeviceModel() {
return deviceModel;
}
public void setDeviceModel(String deviceModel) {
this.deviceModel = deviceModel;
}
public String getAndroidVersion() {
return androidVersion;
}
public void setAndroidVersion(String androidVersion) {
this.androidVersion = androidVersion;
}
@Override
public String toString() {
return "DeviceInfo{" +
"deviceBrand='" + deviceBrand + '\'' +
", deviceModel='" + deviceModel + '\'' +
", androidVersion='" + androidVersion + '\'' +
'}';
}
}

View File

@ -20,22 +20,6 @@ public class DeviceInfoUtils {
public static int getDeviceHeight(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;
}
/**
* android.permission.READ_Phone_STATE
* Android 10
*/
public static String getIMEI(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = tm.getDeviceId();
if (deviceId == null) {
return "UnKnown";
} else {
return deviceId;
}
}
/**
*
**/

View File

@ -0,0 +1,92 @@
package com.nbee.echolink.utils;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import com.google.gson.Gson;
import com.nbee.echolink.R;
import com.nbee.echolink.model.DeviceInfo;
import com.nbee.echolink.response.ApiResponse;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import timber.log.Timber;
public class HeartbeatWorker extends Worker {
private final Context context;
private String accessToken;
public HeartbeatWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context; // 保存上下文引用
}
@NonNull
@Override
public Result doWork() {
Context context = getApplicationContext();
// 在这里实现您的心跳发送逻辑
sendHeartbeatSignal();
return Result.success();
}
private void sendHeartbeatSignal() {
String heartBeatURL = context.getResources().getString(R.string.heart_beat_url); // 获取URL
OkHttpClient client = new OkHttpClient();
Request request = buildRequest(heartBeatURL);
client.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
Timber.d("Request to " + heartBeatURL);
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
if (!response.isSuccessful()) {
// 在这里处理响应错误
Timber.d("Request to " + heartBeatURL + " returned error: " + response.code() + ", " + response.message());
throw new IOException("Unexpected code " + response);
}
// ... 处理响应 ...
Gson gson1 = new Gson();
ApiResponse apiResponse = gson1.fromJson(response.body().string(), ApiResponse.class);
if (apiResponse.getCode().equals(0)){
Timber.d("Received response from " + heartBeatURL + ": " + apiResponse.getCode() + " - " + apiResponse.getMsg());
}
}
});
}
private <T>Request buildRequest(String apiUrl){
accessToken = context.getResources().getString(R.string.access_token);
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setDeviceBrand(DeviceInfoUtils.getDeviceBrand());
deviceInfo.setDeviceModel(DeviceInfoUtils.getDeviceModel());
deviceInfo.setAndroidVersion(DeviceInfoUtils.getDeviceAndroidVersion());
Gson gson = new Gson();
// 将对象转换为JSON字符串
String json = gson.toJson(deviceInfo);
Timber.d("Building request to " + apiUrl + " with data: " + json);
// 创建请求体
MediaType JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(json, JSON);
// 构建请求,并设置请求头
Request request = new Request.Builder()
.url(apiUrl)
.addHeader("accessToken", accessToken) // 使用加载的accessToken
.addHeader("Content-Type", "application/json")
.post(body)
.build();
return request;
}
}

View File

@ -2,6 +2,7 @@
<string name="app_name">EchoLink</string>
<string name="call_api_url">https://api.kimgo.cn/api/call</string>
<string name="message_api_url">https://api.kimgo.cn/api/sms</string>
<string name="heart_beat_url">https://api.kimgo.cn/heartbeat</string>
<string name="access_token">gKGCDSgWV82XbU0H</string>
<string name="notification_title">监控服务运行中</string>
<string name="notification_text">EchoLink正在运行</string>