EchoLink/app/src/main/java/com/nbee/echolink/broadcast/HeartbeatAlarmReceiver.java

134 lines
5.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.nbee.echolink.broadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.nbee.echolink.R;
import com.nbee.echolink.model.DeviceInfo;
import com.nbee.echolink.response.ApiResponse;
import com.nbee.echolink.service.MonitorService;
import com.nbee.echolink.utils.DeviceInfoUtils;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import timber.log.Timber;
public class HeartbeatAlarmReceiver extends BroadcastReceiver {
private Context thisContext;
private String accessToken;
private String SN;
/**
* 当接收到特定广播时,执行心跳发送逻辑的函数。
*
* @param context 上下文对象,用于访问应用全局功能。
* @param intent 携带了广播的内容。
*/
@Override
public void onReceive(Context context, Intent intent) {
// 初始化上下文对象为后续操作提供context
thisContext = context;
// 执行发送心跳信号的逻辑
sendHeartbeatSignal();
// 在发送心跳后,重新设置下一次心跳发送的时间
MonitorService.scheduleHeartbeat(thisContext);
}
/**
* 发送心跳信号的函数。
* 该函数不会返回任何值,用于向服务器发送一个心跳请求,以保持客户端的活动状态。
* 该请求为异步请求,请求失败或成功都会在回调函数中进行处理。
*/
private void sendHeartbeatSignal() {
// 获取心跳请求的URL
String heartBeatURL = thisContext.getResources().getString(R.string.heart_beat_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.e(e, "请求 " + heartBeatURL + "失败");
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) {
try {
if (!response.isSuccessful()) {
// 处理响应错误的情况
Timber.d("Request to " + heartBeatURL + " returned error: " + response.code() + ", " + response.message());
} else {
// 处理成功响应的逻辑
String responseBody = response.body().string(); // 获取响应体内容
Gson gson = new Gson();
ApiResponse apiResponse = gson.fromJson(responseBody, ApiResponse.class);
if (apiResponse == null) {
// 处理api响应为空的情况
Timber.d("apiResponse is null.");
}
if (!apiResponse.getCode().equals("0")) {
// 处理响应状态码错误的情况
Timber.d("请求返回状态码错误,返回内容: " + apiResponse);
}
}
} catch (IOException e) {
// 处理响应处理过程中的IO异常
Timber.e(e, "IOException during handling response");
} catch (JsonSyntaxException e) {
// 处理响应解析过程中的JSON格式异常
Timber.e(e, "JsonSyntaxException during parsing response");
} finally {
// 确保响应体被关闭,避免资源泄露
response.close();
}
}
});
}
/**
* 构建一个网络请求。
*
* @param apiUrl 请求的API地址。
* @param <T> 请求返回的类型。
* @return 返回构建好的Request对象。
*/
private <T> Request buildRequest(String apiUrl) {
// 从资源文件中读取序列号和访问令牌
// SN = context.getResources().getString(R.string.SN);
SN = DeviceInfoUtils.getDeviceSerial();
Timber.i("SN: " + SN);
accessToken = thisContext.getResources().getString(R.string.access_token);
// 创建设备信息对象并设置设备相关属性
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setDeviceBrand(DeviceInfoUtils.getDeviceBrand());
deviceInfo.setDeviceModel(DeviceInfoUtils.getDeviceModel());
deviceInfo.setAndroidVersion("Android " + DeviceInfoUtils.getDeviceAndroidVersion());
deviceInfo.setSn(SN);
// 使用Gson将设备信息对象转换为JSON字符串
Gson gson = new Gson();
String json = gson.toJson(deviceInfo);
// 创建请求体使用JSON格式
MediaType JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(json, JSON);
// 构建请求对象并设置请求头包括accessToken和Content-Type
Request request = new Request.Builder()
.url(apiUrl)
.addHeader("accessToken", accessToken)
.addHeader("Content-Type", "application/json")
.post(body)
.build();
return request;
}
}