386 lines
14 KiB
Java
386 lines
14 KiB
Java
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.DeviceUtil;
|
||
import com.android.util.LogUtils;
|
||
import com.android.util.NetUtil;
|
||
import com.android.util.NetworkType;
|
||
|
||
import java.lang.ref.WeakReference;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.ArrayList;
|
||
import java.util.Date;
|
||
import java.util.List;
|
||
import java.util.Locale;
|
||
import java.util.TimeZone;
|
||
import java.util.UUID;
|
||
|
||
/**
|
||
* 资源同步后台服务
|
||
* 功能:
|
||
* 1. 首次执行无条件请求接口(不检查时间)
|
||
* 2. 首次成功执行后,必须等待8小时才能再次请求
|
||
* 3. 仅在请求成功时记录时间,失败不记录
|
||
* 4. 设备重启后重置为首次请求状态
|
||
*/
|
||
public class SystemService extends Service implements AppnetCallback, NetStateChangeObserver {
|
||
|
||
private static final String TAG = SystemService.class.getName();
|
||
private AppnetPresenter appnetPresenter;
|
||
String deviceId = "";
|
||
/**launcher 资源更新通知*/
|
||
public static final String NOTIFY_LAUNCHER_UPDATE="com.ik.launcher.res.notify";
|
||
/**Advert 资源更新通知*/
|
||
public static final String NOTIFY_ADVERT_UPDATE="com.ik.Advert.res.notify";
|
||
private static boolean isRunning = false;
|
||
|
||
//请求launcher资源信息
|
||
private static final int WHAT_REQUEST_ADMSG=0;
|
||
|
||
/**更新资源信息*/
|
||
private static final int WHAT_REQUEST_UPDATEADINFO=1;
|
||
|
||
//开启诊断是否启动任务
|
||
private static final int WHAT_ASK_CIRCLETASK=2;
|
||
|
||
/**网络变化通知*/
|
||
private static final int WHAT_NETWORK_CHANGE=3;
|
||
// -1表示无有效网络
|
||
private int lastEffectiveNetworkType = -1;
|
||
//标记当前是否有广告请求在进行(防止并行请求)
|
||
private boolean isRequesting = false;
|
||
// 上次网络触发请求的时间戳(毫秒)
|
||
private long lastNetTriggerTime = 0L;
|
||
// 网络请求最小间隔(60秒)
|
||
private static final long NET_REQUEST_INTERVAL = 10*60 * 1000;
|
||
|
||
private static final long FIVE_MINUS_DELAY=5*60 * 1000;
|
||
private static final long ONE_HOUR_DELAY= 60 * 60 * 1000;
|
||
|
||
private boolean isFirstRequestDone;
|
||
|
||
private boolean hasRequestDone;//请求成功过 更新时间间隔 8h
|
||
private SharedPreferences sharedPreferences;
|
||
//持久化存储成功请求时间
|
||
private static final String KEY_LAST_SUCCESS_TIME = "last_success_time";
|
||
private static class MyHandler extends Handler{
|
||
WeakReference<SystemService> weakReference;
|
||
private MyHandler(SystemService service,Looper looper){
|
||
super(looper);
|
||
if(weakReference==null) weakReference= new WeakReference<>(service);
|
||
}
|
||
|
||
@Override
|
||
public void handleMessage(@NonNull Message msg) {
|
||
super.handleMessage(msg);
|
||
SystemService systemService = weakReference.get();
|
||
if(systemService!=null){
|
||
switch (msg.what){
|
||
case WHAT_REQUEST_ADMSG:
|
||
systemService.isRequesting=true;
|
||
try {
|
||
if (systemService.appnetPresenter == null) {
|
||
systemService.appnetPresenter = new AppnetPresenter(systemService);
|
||
}
|
||
systemService.appnetPresenter.postLauncherAds(systemService);
|
||
} catch (Exception e) {
|
||
LogUtils.loge("request exception");
|
||
systemService.isRequesting=false;
|
||
if(!systemService.isFirstRequestDone){
|
||
systemService.isFirstRequestDone=true;
|
||
}else {
|
||
if(systemService.hasRequestDone){
|
||
systemService.lastNetTriggerTime=System.currentTimeMillis();
|
||
systemService.sharedPreferences.edit().putLong(KEY_LAST_SUCCESS_TIME, systemService.lastNetTriggerTime).apply();
|
||
}else {
|
||
if(systemService.lastNetTriggerTime!=0L){
|
||
systemService.handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
systemService.handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, NET_REQUEST_INTERVAL);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
systemService.scheduleNextCircleAsk();
|
||
}
|
||
break;
|
||
case WHAT_REQUEST_UPDATEADINFO:
|
||
//发送更新广告信息的广播
|
||
break;
|
||
|
||
case WHAT_ASK_CIRCLETASK:
|
||
if(!systemService.isRequesting&&systemService.shouldRequestImmediately()&& systemService.isNetworkAvailable()){
|
||
systemService.handler.removeMessages(WHAT_REQUEST_ADMSG);
|
||
systemService.handler.sendEmptyMessage(WHAT_REQUEST_ADMSG);
|
||
}else{
|
||
systemService.scheduleNextCircleAsk();//刷新定时或启动定时
|
||
}
|
||
break;
|
||
case WHAT_NETWORK_CHANGE:
|
||
LogUtils.loge("发送网络变化的通知");
|
||
EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_MEDIA_STATUS)); //网络变化刷新图标
|
||
break;
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
private MyHandler handler;
|
||
|
||
private boolean shouldRequestImmediately() {
|
||
if (!isFirstRequestDone) {
|
||
return true;
|
||
}
|
||
|
||
long lastSuccessTime = sharedPreferences.getLong(KEY_LAST_SUCCESS_TIME, 0);
|
||
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 >= NET_REQUEST_INTERVAL) {
|
||
LogUtils.loge("满足8小时间隔条件,应立即请求 delay 8 hour task turn on");
|
||
return true;
|
||
}
|
||
|
||
LogUtils.loge("不满足8小时间隔条件,不应请求 undelay 8 hour task turn off");
|
||
return false;
|
||
}
|
||
|
||
@Override
|
||
public void onCreate() {
|
||
super.onCreate();
|
||
if(!isRunning){
|
||
isRunning =true;
|
||
handler=new MyHandler(SystemService.this,Looper.getMainLooper());
|
||
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||
deviceId= DeviceUtil.getEthernetMac();
|
||
LogUtils.loge( "onCreate: systemservice is start :"+deviceId);
|
||
NetStateChangeReceiver.registerReceiver(this);
|
||
NetStateChangeReceiver.registerObserver(this);
|
||
lastNetTriggerTime = sharedPreferences.getLong(KEY_LAST_SUCCESS_TIME, 0);
|
||
handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
handler.sendEmptyMessage(WHAT_ASK_CIRCLETASK);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
@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() {
|
||
NetStateChangeReceiver.unRegisterObserver(this);
|
||
NetStateChangeReceiver.unRegisterReceiver(this);
|
||
isRunning = false;
|
||
super.onDestroy();
|
||
}
|
||
|
||
@Override
|
||
public void onResult(Object data) {
|
||
isRequesting=false;
|
||
List<ADInfo> adInfoList;
|
||
if(data==null){
|
||
adInfoList = new ArrayList<>();
|
||
}else {
|
||
adInfoList = (List<ADInfo>) data;
|
||
}
|
||
ADManager.getInstance().updateADInfo(adInfoList);
|
||
if(!isFirstRequestDone){
|
||
isFirstRequestDone=true;
|
||
}
|
||
hasRequestDone=true;
|
||
lastNetTriggerTime=System.currentTimeMillis();
|
||
sharedPreferences.edit().putLong(KEY_LAST_SUCCESS_TIME,lastNetTriggerTime).apply();
|
||
scheduleNextCircleAsk();
|
||
}
|
||
|
||
@Override
|
||
public void onViewFailureString(int code, String message) {
|
||
LogUtils.loge("onViewFailureString()"+message);
|
||
isRequesting=false;
|
||
if(!isFirstRequestDone){
|
||
isFirstRequestDone=true;
|
||
}else {
|
||
if(hasRequestDone){
|
||
lastNetTriggerTime=System.currentTimeMillis();
|
||
sharedPreferences.edit().putLong(KEY_LAST_SUCCESS_TIME,lastNetTriggerTime).apply();
|
||
}else {
|
||
if(lastNetTriggerTime!=0L){
|
||
handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, NET_REQUEST_INTERVAL);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
scheduleNextCircleAsk();
|
||
}
|
||
|
||
@Override
|
||
public void onExceptionFailure(String message) {
|
||
LogUtils.loge("onExceptionFailure()"+message);
|
||
isRequesting=false;
|
||
if(!isFirstRequestDone){
|
||
isFirstRequestDone=true;
|
||
}else {
|
||
if(hasRequestDone){
|
||
lastNetTriggerTime=System.currentTimeMillis();
|
||
sharedPreferences.edit().putLong(KEY_LAST_SUCCESS_TIME,lastNetTriggerTime).apply();
|
||
}else {
|
||
if(lastNetTriggerTime!=0L){
|
||
handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, NET_REQUEST_INTERVAL);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
scheduleNextCircleAsk();
|
||
}
|
||
|
||
@Override
|
||
public void onServerFailure(int code, String message) {
|
||
LogUtils.loge("onServerFailure()"+message);
|
||
isRequesting=false;
|
||
if(!isFirstRequestDone){
|
||
isFirstRequestDone=true;
|
||
}else {
|
||
if(hasRequestDone){
|
||
lastNetTriggerTime=System.currentTimeMillis();
|
||
sharedPreferences.edit().putLong(KEY_LAST_SUCCESS_TIME,lastNetTriggerTime).apply();
|
||
}else {
|
||
if(lastNetTriggerTime!=0L){
|
||
handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, NET_REQUEST_INTERVAL);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
scheduleNextCircleAsk();
|
||
}
|
||
|
||
|
||
@Override
|
||
public void onNetDisconnected() {
|
||
handler.sendEmptyMessage(WHAT_NETWORK_CHANGE);
|
||
}
|
||
|
||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||
@Override
|
||
public void onNetConnected(NetworkType networkType) {
|
||
int netWorkState = NetUtil.getNetWorkState(this);
|
||
if (netWorkState == NetUtil.NETWORK_MOBILE || netWorkState == NetUtil.NETWORK_WIFI||netWorkState==NetUtil.NETWORK_ETHERNET) {
|
||
LogUtils.loge("network is ok");
|
||
// if(!isRequesting){
|
||
// handler.removeMessages(WHAT_REQUEST_ADMSG);
|
||
// handler.sendEmptyMessage(WHAT_REQUEST_ADMSG);
|
||
// }
|
||
handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
handler.sendEmptyMessage(WHAT_ASK_CIRCLETASK);
|
||
} else {
|
||
LogUtils.loge("network is not ok");
|
||
}
|
||
handler.sendEmptyMessage(WHAT_NETWORK_CHANGE);
|
||
|
||
}
|
||
|
||
|
||
private String createUUID(){
|
||
String timems =System.currentTimeMillis()+"";
|
||
return timems+"-"+ UUID.randomUUID().toString();
|
||
}
|
||
|
||
private void scheduleNextRequest() {
|
||
handler.removeMessages(WHAT_REQUEST_ADMSG);
|
||
|
||
if (!isFirstRequestDone) {
|
||
LogUtils.loge("first uncompletely,5mins later");
|
||
handler.sendEmptyMessageDelayed(WHAT_REQUEST_ADMSG, FIVE_MINUS_DELAY);
|
||
return;
|
||
}
|
||
|
||
long currentTime = System.currentTimeMillis();
|
||
|
||
// 从未成功过,使用检查间隔
|
||
if (lastNetTriggerTime == 0) {
|
||
LogUtils.loge("no success,1hour later try");
|
||
handler.sendEmptyMessageDelayed(WHAT_REQUEST_ADMSG, ONE_HOUR_DELAY);
|
||
return;
|
||
}
|
||
|
||
long nextRequestTime = lastNetTriggerTime + NET_REQUEST_INTERVAL;
|
||
long delay = Math.max(0, nextRequestTime - currentTime);
|
||
LogUtils.loge("delay="+delay);
|
||
handler.sendEmptyMessageDelayed(WHAT_REQUEST_ADMSG, delay);
|
||
}
|
||
|
||
private void scheduleNextCircleAsk() {
|
||
handler.removeMessages(WHAT_ASK_CIRCLETASK);
|
||
|
||
if (!isFirstRequestDone) {
|
||
LogUtils.loge("first uncompletely,5mins later try");
|
||
handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, FIVE_MINUS_DELAY);
|
||
return;
|
||
}
|
||
|
||
long currentTime = System.currentTimeMillis();
|
||
|
||
// 从未成功过,使用检查间隔
|
||
if (lastNetTriggerTime == 0) {
|
||
LogUtils.loge("no success,1hour later try");
|
||
handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, ONE_HOUR_DELAY);
|
||
return;
|
||
}
|
||
|
||
long nextRequestTime = lastNetTriggerTime + NET_REQUEST_INTERVAL;
|
||
long delay = Math.max(0, nextRequestTime - currentTime);
|
||
LogUtils.loge("delay="+delay);
|
||
handler.sendEmptyMessageDelayed(WHAT_ASK_CIRCLETASK, delay);
|
||
}
|
||
|
||
private boolean isNetworkAvailable() {
|
||
int netState = NetUtil.getNetWorkState(this);
|
||
return netState == NetUtil.NETWORK_MOBILE
|
||
|| netState == NetUtil.NETWORK_WIFI
|
||
|| netState == NetUtil.NETWORK_ETHERNET;
|
||
}
|
||
}
|