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; } 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 adInfoList = (data instanceof List) ? (List) 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) { markFirstRequestDone(); } boolean isTimeout = code==0 || message.contains("The server is busy"); if (isTimeout) { 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)); } }