Files
SNFLauncherMain_AllWinner/app/src/main/java/com/ik/mboxlauncher/SystemService.java

384 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.ik.mboxlauncher;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import com.android.device.NetStateChangeReceiver;
import com.android.eventbaus.EventBusUtils;
import com.android.eventbaus.MessageEvent;
import com.android.nebulasdk.ADManager;
import com.android.device.NetStateChangeObserver;
import com.android.nebulasdk.bean.ADInfo;
import com.android.nebulasdk.presenter.AppnetPresenter;
import com.android.nebulasdk.presenter.callback.AppnetCallback;
import com.android.util.LogUtils;
import com.android.util.NetUtil;
import com.android.util.NetworkType;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
/**
* 资源同步后台服务
* 功能:
* 1. 首次执行无条件请求接口(不检查时间)
* 2. 首次成功执行后必须等待8小时才能再次请求
* 3. 仅在请求成功时记录时间,失败不记录
* 4. 设备重启后重置为首次请求状态
*/
public class SystemService extends Service implements AppnetCallback, NetStateChangeObserver {
private static final int WHAT_REQUEST_ADMSG = 0;
private static final int WHAT_NETWORK_CHANGE = 3;
private static final int WHAT_PERIODIC_REQUEST = 4;
// 请求间隔8小时正式环境
// private static final long REQUEST_INTERVAL = 8 * 60 * 60 * 1000;
// 测试用短间隔
private static final long REQUEST_INTERVAL = 5 * 60 * 1000; // 5分钟
//持久化存储成功请求时间
private static final String KEY_LAST_SUCCESS_TIME = "last_success_time";
private boolean isFirstRequestDone = false; // 首次请求是否完成重启后重置为false
private boolean isRunning = false;
private boolean isRequesting = false;
private AppnetPresenter appnetPresenter;
private Handler handler;
private SharedPreferences sharedPreferences;
private PowerManager powerManager;
@Override
public void onCreate() {
super.onCreate();
if (!isRunning) {
isRunning = true;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
initHandler();
NetStateChangeReceiver.registerReceiver(this);
NetStateChangeReceiver.registerObserver(this);
// 检查是否是重启后首次启动服务
checkRebootStatus();
// 检查网络并执行首次请求
checkNetworkAndInitiateFirstRequest();
//handler.postDelayed(() -> ADManager.getInstance().restDownloadTask(), 3000);
}
}
/**
* 检查是否是重启后首次启动
*/
private void checkRebootStatus() {
if (powerManager != null) {
// 判断是否是开机后首次启动服务
boolean isReboot = powerManager.isInteractive();
if (isReboot) {
// LogUtils.loge("检测到设备重启,重置为首次请求状态");
isFirstRequestDone = false;
}
}
}
private void initHandler() {
handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case WHAT_REQUEST_ADMSG:
handleAdRequest();
break;
case WHAT_NETWORK_CHANGE:
notifyNetworkChange();
break;
case WHAT_PERIODIC_REQUEST:
handlePeriodicRequest();
break;
}
}
};
}
private void handlePeriodicRequest() {
// boolean should=shouldRequestImmediately();
// LogUtils.loge("shouldRequestImmediately()="+should+"isRequesting="+isRequesting);
if (isNetworkAvailable() && shouldRequestImmediately() && !isRequesting) {
LogUtils.loge("定时任务:满足条件,执行请求,task turn on");
handleAdRequest();
} else {
scheduleNextPeriodicRequest();
}
}
private void checkNetworkAndInitiateFirstRequest() {
if (isFirstRequestDone) {
if (shouldRequestImmediately() && !isRequesting) {
handler.sendEmptyMessage(WHAT_REQUEST_ADMSG);
} else {
LogUtils.loge("首次请求已完成,启动定时任务 first request");
scheduleNextPeriodicRequest();
}
return;
}
boolean currentNetworkAvailable = isNetworkAvailable();
if (currentNetworkAvailable && !isRequesting) {
LogUtils.loge("执行首次请求 first request handler msg");
handler.sendEmptyMessage(WHAT_REQUEST_ADMSG);
} else {
LogUtils.loge("网络不可用,安排首次请求检查 network dont work");
scheduleNextPeriodicRequest();
}
}
private void scheduleNextPeriodicRequest() {
handler.removeMessages(WHAT_PERIODIC_REQUEST);
if (!isFirstRequestDone) {
LogUtils.loge("首次请求未完成5分钟后再次检查 first uncompletely");
handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, 5*60 * 1000);
return;
}
long lastSuccessTime = getLastSuccessTime();
long currentTime = System.currentTimeMillis();
// 从未成功过,使用检查间隔
if (lastSuccessTime == 0) {
LogUtils.loge("从未成功请求过1个小时后再次尝试,no success,1hour later try");
handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, 60 * 60 * 1000);
return;
}
if(currentTime<lastSuccessTime){
handler.sendEmptyMessage(WHAT_PERIODIC_REQUEST);
return;
}
long nextRequestTime = lastSuccessTime + REQUEST_INTERVAL;
long delay = Math.max(0, nextRequestTime - currentTime);
LogUtils.loge("delay="+delay);
handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, delay);
// if (isNetworkAvailable()){
// LogUtils.loge("定时任务安排完成:" +
// "上次成功时间=" + formatTime(lastSuccessTime) +
// ",当前时间=" + formatTime(currentTime) +
// ",延迟=" + (delay / 1000 / 60) + "分钟" +
// ",下次执行=" + formatTime(currentTime + delay));
// }
}
private boolean shouldRequestImmediately() {
if (!isFirstRequestDone) {
return true;
}
long lastSuccessTime = getLastSuccessTime();
long currentTime = System.currentTimeMillis();
if (lastSuccessTime == 0) {
LogUtils.loge("从未成功请求过,应立即请求 unsuccess task turn on");
return true;
}
if (currentTime < lastSuccessTime) {
LogUtils.loge("满足(时间回退),应立即请求 time forecase task turn on");
return true;
}
long timeDiff = currentTime - lastSuccessTime;
if (timeDiff >= REQUEST_INTERVAL) {
LogUtils.loge("满足8小时间隔条件应立即请求 delay 8 hour task turn on");
return true;
}
LogUtils.loge("不满足8小时间隔条件不应请求 undelay 8 hour task turn off");
return false;
}
private void markFirstRequestDone() {
isFirstRequestDone = true;
// LogUtils.loge("标记首次请求已完成");
}
private void handleAdRequest() {
if (isRequesting) {
return;
}
if (appnetPresenter == null) {
try {
appnetPresenter = new AppnetPresenter(this);
} catch (Exception e) {
isRequesting = false;
if (!isFirstRequestDone) {
markFirstRequestDone();
}
// 失败时不保存时间
// saveLastSuccessTime();
LogUtils.loge("请求异常 request exception");
scheduleNextPeriodicRequest();
return;
}
}
isRequesting = true;
appnetPresenter.postLauncherAds(this);
}
private void notifyNetworkChange() {
EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_MEDIA_STATUS));
}
private boolean isNetworkAvailable() {
int netState = NetUtil.getNetWorkState(this);
return netState == NetUtil.NETWORK_MOBILE
|| netState == NetUtil.NETWORK_WIFI
|| netState == NetUtil.NETWORK_ETHERNET;
}
private long getLastSuccessTime() {
return sharedPreferences.getLong(KEY_LAST_SUCCESS_TIME, 0);
}
private void saveLastSuccessTime() {
long currentTime = System.currentTimeMillis();
sharedPreferences.edit()
.putLong(KEY_LAST_SUCCESS_TIME, currentTime)
.apply();
LogUtils.loge("已保存本次成功请求时间refresh" + formatTime(currentTime));
}
@Override
public void onNetDisconnected() {
LogUtils.loge("网络断开 netdisconnect");
handler.sendEmptyMessage(WHAT_NETWORK_CHANGE);
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onNetConnected(NetworkType networkType) {
LogUtils.loge("网络连接恢复netconnect" + networkType.name());
scheduleNextPeriodicRequest();
handler.sendEmptyMessage(WHAT_NETWORK_CHANGE);
}
@Override
public void onResult(Object data) {
isRequesting = false;
List<ADInfo> adInfoList = (data instanceof List<?>) ? (List<ADInfo>) data : new ArrayList<>();
ADManager.getInstance().updateADInfo(adInfoList);
if (!isFirstRequestDone) {
markFirstRequestDone();
}
// 成功时保存时间
saveLastSuccessTime();
scheduleNextPeriodicRequest();
}
@Override
public void onViewFailureString(int code, String message) {
isRequesting = false;
LogUtils.loge("接口请求失败(视图层):错误码= code" + code + ",错误信息= viewmsg" + message);
handleRequestFailure();
}
@Override
public void onExceptionFailure(String message) {
isRequesting = false;
LogUtils.loge("接口请求异常:异常信息= exceptionmsg" + message);
handleRequestFailure();
}
@Override
public void onServerFailure(int code, String message) {
isRequesting = false;
LogUtils.loge("接口请求失败(服务端):错误码= code" + code + ",错误信息= servermsg" + message);
// handleRequestFailure();
// 仅保留首次请求完成标记(必须保留,避免无限重复首次请求)
if (!isFirstRequestDone) {
scheduleNextPeriodicRequest();
markFirstRequestDone();
return;
}
boolean isTimeout = code==0 || message.contains("The server is busy");
if (isTimeout) {
long lastSuccessTime = getLastSuccessTime();
if (lastSuccessTime == 0) {
scheduleNextPeriodicRequest();
} else {
handler.removeMessages(WHAT_PERIODIC_REQUEST);
handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, REQUEST_INTERVAL);
}
} else {
//保留原逻辑
scheduleNextPeriodicRequest();
}
}
private void handleRequestFailure() {
if (!isFirstRequestDone) {
markFirstRequestDone();
}
// 失败时不保存时间
// saveLastSuccessTime();
scheduleNextPeriodicRequest();
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
isRunning = false;
isRequesting = false;
NetStateChangeReceiver.unRegisterObserver(this);
NetStateChangeReceiver.unRegisterReceiver(this);
if (handler != null) {
handler.removeCallbacksAndMessages(null);
}
if (appnetPresenter != null) {
appnetPresenter = null;
}
}
private String formatTime(long timestamp) {
if (timestamp == 0) return "未记录 no record";
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
return sdf.format(new Date(timestamp));
}
}