Compare commits

..

8 Commits

15 changed files with 482 additions and 320 deletions

View File

@@ -27,6 +27,7 @@
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission <uses-permission
android:name="android.permission.INSTALL_PACKAGES"/> android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="permission.REQUEST_DELETE_PACKAGES" /> <uses-permission android:name="permission.REQUEST_DELETE_PACKAGES" />

View File

@@ -22,16 +22,19 @@ import com.android.device.NetStateChangeObserver;
import com.android.nebulasdk.bean.ADInfo; import com.android.nebulasdk.bean.ADInfo;
import com.android.nebulasdk.presenter.AppnetPresenter; import com.android.nebulasdk.presenter.AppnetPresenter;
import com.android.nebulasdk.presenter.callback.AppnetCallback; import com.android.nebulasdk.presenter.callback.AppnetCallback;
import com.android.util.DeviceUtil;
import com.android.util.LogUtils; import com.android.util.LogUtils;
import com.android.util.NetUtil; import com.android.util.NetUtil;
import com.android.util.NetworkType; import com.android.util.NetworkType;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID;
/** /**
* 资源同步后台服务 * 资源同步后台服务
@@ -43,154 +46,113 @@ import java.util.TimeZone;
*/ */
public class SystemService extends Service implements AppnetCallback, NetStateChangeObserver { public class SystemService extends Service implements AppnetCallback, NetStateChangeObserver {
private static final int WHAT_REQUEST_ADMSG = 0; private static final String TAG = SystemService.class.getName();
private static final int WHAT_NETWORK_CHANGE = 3; private AppnetPresenter appnetPresenter;
private static final int WHAT_PERIODIC_REQUEST = 4; 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;
// 请求间隔8小时正式环境 //请求launcher资源信息
// private static final long REQUEST_INTERVAL = 8 * 60 * 60 * 1000; private static final int WHAT_REQUEST_ADMSG=0;
// 测试用短间隔
private static final long REQUEST_INTERVAL = 5 * 60 * 1000; // 5分钟 /**更新资源信息*/
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 final String KEY_LAST_SUCCESS_TIME = "last_success_time";
private boolean isFirstRequestDone = false; // 首次请求是否完成重启后重置为false private static class MyHandler extends Handler{
private boolean isRunning = false; WeakReference<SystemService> weakReference;
private boolean isRequesting = false; private MyHandler(SystemService service,Looper looper){
super(looper);
private AppnetPresenter appnetPresenter; if(weakReference==null) weakReference= new WeakReference<>(service);
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 @Override
public void handleMessage(@NonNull Message msg) { public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
SystemService systemService = weakReference.get();
if(systemService!=null){
switch (msg.what){ switch (msg.what){
case WHAT_REQUEST_ADMSG: case WHAT_REQUEST_ADMSG:
handleAdRequest(); 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; break;
case WHAT_NETWORK_CHANGE: case WHAT_NETWORK_CHANGE:
notifyNetworkChange(); LogUtils.loge("发送网络变化的通知");
EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_MEDIA_STATUS)); //网络变化刷新图标
break; 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 MyHandler handler;
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() { private boolean shouldRequestImmediately() {
if (!isFirstRequestDone) { if (!isFirstRequestDone) {
return true; return true;
} }
long lastSuccessTime = getLastSuccessTime(); long lastSuccessTime = sharedPreferences.getLong(KEY_LAST_SUCCESS_TIME, 0);
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
if (lastSuccessTime == 0) { if (lastSuccessTime == 0) {
@@ -203,7 +165,7 @@ public class SystemService extends Service implements AppnetCallback, NetStateCh
} }
long timeDiff = currentTime - lastSuccessTime; long timeDiff = currentTime - lastSuccessTime;
if (timeDiff >= REQUEST_INTERVAL) { if (timeDiff >= NET_REQUEST_INTERVAL) {
LogUtils.loge("满足8小时间隔条件应立即请求 delay 8 hour task turn on"); LogUtils.loge("满足8小时间隔条件应立即请求 delay 8 hour task turn on");
return true; return true;
} }
@@ -212,137 +174,23 @@ public class SystemService extends Service implements AppnetCallback, NetStateCh
return false; 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 @Override
public void onNetDisconnected() { public void onCreate() {
LogUtils.loge("网络断开 netdisconnect"); super.onCreate();
handler.sendEmptyMessage(WHAT_NETWORK_CHANGE); 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 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) @RequiresApi(api = Build.VERSION_CODES.O)
@@ -351,6 +199,9 @@ public class SystemService extends Service implements AppnetCallback, NetStateCh
return START_STICKY; return START_STICKY;
} }
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return null;
@@ -358,26 +209,177 @@ public class SystemService extends Service implements AppnetCallback, NetStateCh
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy();
isRunning = false;
isRequesting = false;
NetStateChangeReceiver.unRegisterObserver(this); NetStateChangeReceiver.unRegisterObserver(this);
NetStateChangeReceiver.unRegisterReceiver(this); NetStateChangeReceiver.unRegisterReceiver(this);
isRunning = false;
if (handler != null) { super.onDestroy();
handler.removeCallbacksAndMessages(null);
} }
if (appnetPresenter != null) { @Override
appnetPresenter = null; 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();
} }
private String formatTime(long timestamp) { @Override
if (timestamp == 0) return "未记录 no record"; public void onViewFailureString(int code, String message) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()); LogUtils.loge("onViewFailureString()"+message);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); isRequesting=false;
return sdf.format(new Date(timestamp)); 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;
} }
} }

View File

@@ -10,6 +10,7 @@ import android.view.View;
import com.android.device.MediaStateChangeObserver; import com.android.device.MediaStateChangeObserver;
import com.android.eventbaus.MessageEvent; import com.android.eventbaus.MessageEvent;
import com.android.util.LogUtils; import com.android.util.LogUtils;
import com.android.util.SharedPreferencesUtil;
import com.ik.mboxlauncher.R; import com.ik.mboxlauncher.R;
import com.ik.mboxlauncher.ui.base.FragmentActivity; import com.ik.mboxlauncher.ui.base.FragmentActivity;
import com.ik.mboxlauncher.ui.fragment.AppsFragment; import com.ik.mboxlauncher.ui.fragment.AppsFragment;
@@ -73,6 +74,11 @@ public class CategoryActivity extends FragmentActivity {
return null; return null;
} }
@Override
public void setFragmentsDisableRefreshDataFlag() {
FragmentManager.getInstance().pressBackUpdateAllFragmentDisableRefreshDataFlag();
}
@Override @Override
public void popBackStackFragment() { public void popBackStackFragment() {
@@ -94,6 +100,21 @@ public class CategoryActivity extends FragmentActivity {
} }
@Override
protected void onResume() {
super.onResume();
onResumeResetDisableFreshDataFlag();
}
private void onResumeResetDisableFreshDataFlag() {
if(SharedPreferencesUtil.getSharePrefrencesBoolean(this,SharedPreferencesUtil.CONFIG_RESET_DISABLE_FRESHDATA_FLAG)){
SharedPreferencesUtil.setSharePrefrencesBoolean(this,SharedPreferencesUtil.CONFIG_RESET_DISABLE_FRESHDATA_FLAG,false);
FragmentManager.getInstance().pressBackUpdateAllFragmentDisableRefreshDataFlag();
if(currentFragment!=null){
currentFragment.onResumeFragment(new MessageEvent());
}
}
}
// public void setPopWindow(int top, int bottom){ // public void setPopWindow(int top, int bottom){
@@ -122,6 +143,7 @@ public class CategoryActivity extends FragmentActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
FragmentManager.getInstance().destory();
super.onDestroy(); super.onDestroy();
} }
@@ -135,9 +157,16 @@ public class CategoryActivity extends FragmentActivity {
if(currentFragment.onKeyDown(keyCode,event)){ if(currentFragment.onKeyDown(keyCode,event)){
return true; return true;
}else { }else {
//currentFragment.resetDisableRefreshDataFlag();
FragmentManager.getInstance().pressBackUpdateAllFragmentDisableRefreshDataFlag();
return super.onKeyDown(keyCode,event); return super.onKeyDown(keyCode,event);
} }
} }
if(keyCode==KeyEvent.KEYCODE_HOME){
LogUtils.loge("onKeyDown===>KEYCODE_HOME");
currentFragment.onDetach();
FragmentManager.getInstance().pressBackUpdateAllFragmentDisableRefreshDataFlag();
}
return super.onKeyDown(keyCode,event); return super.onKeyDown(keyCode,event);
} }

View File

@@ -2,6 +2,7 @@ package com.ik.mboxlauncher.ui;
import android.content.Context; import android.content.Context;
import com.android.util.LogUtils;
import com.ik.mboxlauncher.ui.base.BaseFragment; import com.ik.mboxlauncher.ui.base.BaseFragment;
import com.ik.mboxlauncher.ui.base.NotifyInterface; import com.ik.mboxlauncher.ui.base.NotifyInterface;
import com.ik.mboxlauncher.ui.fragment.AppsFragment; import com.ik.mboxlauncher.ui.fragment.AppsFragment;
@@ -55,9 +56,10 @@ public class FragmentManager {
public static void init(Context context, NotifyInterface notifyInterface){ public static void init(Context context, NotifyInterface notifyInterface){
if(mInstance==null){ if(mInstance==null){
LogUtils.loge("FragmentManager init null");
mInstance = new FragmentManager(context,notifyInterface); mInstance = new FragmentManager(context,notifyInterface);
} }
LogUtils.loge("FragmentManager init end");
} }
public static FragmentManager getInstance(){ public static FragmentManager getInstance(){
@@ -82,6 +84,25 @@ public class FragmentManager {
return null; return null;
} }
public void destory(){ public void destory(){
// 清空所有 Fragment 引用
if(mAppsFragment != null) {
mAppsFragment = null;
}
if(mLocalFragment != null) {
mLocalFragment = null;
}
if(mMainFragment != null) {
mMainFragment = null;
}
if(mMusicFragment != null) {
mMusicFragment = null;
}
if(mRecommendFragment != null) {
mRecommendFragment = null;
}
if(mVideoFragment != null) {
mVideoFragment = null;
}
mInstance = null; mInstance = null;
} }
@@ -91,4 +112,34 @@ public class FragmentManager {
} }
return ""; return "";
} }
//按返回键 home键 等必须恢复 刷新数据处理
public void pressBackUpdateAllFragmentDisableRefreshDataFlag(){
if(mAppsFragment!=null){
mAppsFragment.resetDisableRefreshDataFlag();
}else {
LogUtils.loge("mAppsFragment==null");
}
if(mLocalFragment!=null){
mLocalFragment.resetDisableRefreshDataFlag();
}else {
LogUtils.loge("mLocalFragment==null");
}
if(mVideoFragment!=null){
mVideoFragment.resetDisableRefreshDataFlag();
}else {
LogUtils.loge("mVideoFragment==null");
}
if(mMusicFragment!=null){
mMusicFragment.resetDisableRefreshDataFlag();
}else {
LogUtils.loge("mMusicFragment==null");
}
if(mRecommendFragment!=null){
mRecommendFragment.resetDisableRefreshDataFlag();
}else {
LogUtils.loge("mRecommendFragment==null");
}
}
} }

View File

@@ -293,6 +293,10 @@ public class Launcher extends FragmentActivity implements SplashView.SplashAdLi
ADSWindowManager.init(this); ADSWindowManager.init(this);
bindAdsWindowMultiView(); bindAdsWindowMultiView();
//内存不足时释放单列所有Fragment 打开设置按Home出现单个Fragment异常
if(FragmentManager.getInstance()!=null){
FragmentManager.getInstance().destory();
}
} }
@@ -711,6 +715,7 @@ public boolean onGenericMotionEvent(MotionEvent event) {
displayStatus(); displayStatus();
}else if(MessageEvent.ACTION_UPADATE_APPS_SOURCE.equals(event.action)){ }else if(MessageEvent.ACTION_UPADATE_APPS_SOURCE.equals(event.action)){
if(currentFragment!=null&&currentFragment instanceof AppsFragment){ if(currentFragment!=null&&currentFragment instanceof AppsFragment){
LogUtils.loge("Launcher onMessageEvent===>"+event.action);
currentFragment.onResumeFragment(event); currentFragment.onResumeFragment(event);
} }
@@ -718,6 +723,11 @@ public boolean onGenericMotionEvent(MotionEvent event) {
} }
@Override
public void setFragmentsDisableRefreshDataFlag() {
}
private void displayStatus() { private void displayStatus() {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@@ -880,7 +890,7 @@ public boolean onGenericMotionEvent(MotionEvent event) {
} }
}); });
translateAnimation.setDuration(380); translateAnimation.setDuration(300);
translateAnimation.setFillAfter(true); translateAnimation.setFillAfter(true);
content_view.startAnimation(translateAnimation); content_view.startAnimation(translateAnimation);
@@ -897,11 +907,12 @@ public boolean onGenericMotionEvent(MotionEvent event) {
cuttentModel = MODEL_NORMAL; cuttentModel = MODEL_NORMAL;
LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height);
TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,(float)(0 - coustom_view.getLayoutParams().height - gv_shortcut.getHeight()),0.0f); TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,(float)(0 - coustom_view.getLayoutParams().height - gv_shortcut.getHeight()),0.0f);
translateAnimation.setDuration(380); translateAnimation.setDuration(300);
translateAnimation.setAnimationListener(new Animation.AnimationListener() { translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override @Override
public void onAnimationStart(Animation animation) { public void onAnimationStart(Animation animation) {
coustom_view.setTranslationZ(0); coustom_view.setTranslationZ(0);
grid_coustom_apps.disScrollFocus();
loadShortAppList(); loadShortAppList();
coustom_view.clearFocus(); coustom_view.clearFocus();
} }

View File

@@ -1,6 +1,8 @@
package com.ik.mboxlauncher.ui; package com.ik.mboxlauncher.ui;
import android.app.ActivityManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
@@ -18,6 +20,7 @@ import com.android.nebulasdk.AppManager;
import com.android.util.EventBusType; import com.android.util.EventBusType;
import com.android.util.LogManager; import com.android.util.LogManager;
import com.android.util.LogUtils; import com.android.util.LogUtils;
import com.android.util.SharedPreferencesUtil;
import com.ik.mboxlauncher.SystemService; import com.ik.mboxlauncher.SystemService;
import java.util.List; import java.util.List;
@@ -102,10 +105,39 @@ public class StartupBroadcast extends BroadcastReceiver {
break; break;
} }
EventBusUtils.postMsg(messageEvent); EventBusUtils.postMsg(messageEvent);
if(!isTopAppPackage(context)){
LogUtils.loge("three app activity on top of layer");
boolean sharePrefrencesBoolean = SharedPreferencesUtil.getSharePrefrencesBoolean(context, SharedPreferencesUtil.CONFIG_RESET_DISABLE_FRESHDATA_FLAG);
if(!sharePrefrencesBoolean){
SharedPreferencesUtil.setSharePrefrencesBoolean(context,SharedPreferencesUtil.CONFIG_RESET_DISABLE_FRESHDATA_FLAG,true);
} }
} }
} }
}
}
/**
* 获取顶层应用的包名
* @param context 上下文
* @return 顶层应用包名,如果获取失败返回 null
*/
public static boolean isTopAppPackage(Context context) {
try {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager != null) {
List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
if (runningTasks != null && !runningTasks.isEmpty()) {
ActivityManager.RunningTaskInfo taskInfo = runningTasks.get(0);
ComponentName topActivity = taskInfo.topActivity;
LogUtils.loge("topActivity packagename: " + topActivity.getPackageName());
return topActivity.getPackageName().equalsIgnoreCase(context.getPackageName());
}
}
} catch (Exception e) {
LogUtils.loge("Error getting top app package name: " + e.getMessage());
e.printStackTrace();
}
return true;
}
/** /**
* 获取指定包名应用的Launcher Activity信息 * 获取指定包名应用的Launcher Activity信息

View File

@@ -27,6 +27,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.android.eventbaus.MessageEvent; import com.android.eventbaus.MessageEvent;
import com.android.util.LogUtils;
/** A fragment which slides when it is entering/exiting. */ /** A fragment which slides when it is entering/exiting. */
public abstract class BaseFragment extends Fragment { public abstract class BaseFragment extends Fragment {
@@ -38,6 +39,8 @@ public abstract class BaseFragment extends Fragment {
protected static final int MODEL_NORMAL = 0x00; protected static final int MODEL_NORMAL = 0x00;
protected static final int MODEL_CUSTOM = 0x01; protected static final int MODEL_CUSTOM = 0x01;
protected int cuttentModel=MODEL_NORMAL; protected int cuttentModel=MODEL_NORMAL;
private View view;
public NotifyInterface getNotifyInterface() { public NotifyInterface getNotifyInterface() {
return notifyInterface; return notifyInterface;
} }
@@ -110,7 +113,12 @@ public abstract class BaseFragment extends Fragment {
@Override @Override
public View onCreateView( public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutResourceId(), container, false); if(view==null){
view = inflater.inflate(getLayoutResourceId(), container, false);
LogUtils.loge("onCreateView()==>view=null"+getClass().getSimpleName());
}else {
LogUtils.loge("onCreateView()==>view!=null"+getClass().getSimpleName());
}
initView( view); initView( view);
handler.post(inidataRunnable); handler.post(inidataRunnable);
return view; return view;
@@ -152,7 +160,7 @@ public abstract class BaseFragment extends Fragment {
protected abstract void initView(View view); protected abstract void initView(View view);
protected abstract void initData(); protected abstract void initData();
public abstract void resetDisableRefreshDataFlag();
@Override @Override
public void setEnterTransition(Transition transition) { public void setEnterTransition(Transition transition) {
super.setEnterTransition(transition); super.setEnterTransition(transition);

View File

@@ -23,6 +23,7 @@ import android.app.FragmentTransaction;
import android.os.Bundle; import android.os.Bundle;
import com.android.eventbaus.MessageEvent; import com.android.eventbaus.MessageEvent;
import com.android.util.LogUtils;
/** /**
@@ -42,16 +43,19 @@ public abstract class FragmentActivity extends BaseActivity implements NotifyInt
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(getlayoutId()); setContentView(getlayoutId());
if (savedInstanceState == null) {
LogUtils.loge("savedInstanceState===>null");
showInitialFragment();
} else {
mShowInitialFragment = false;
LogUtils.loge("savedInstanceState===>not null");
}
mFragmentManager = getFragmentManager(); mFragmentManager = getFragmentManager();
initView(); initView();
initData(); initData();
// Show initial fragment only when the saved state is not restored, because the last // Show initial fragment only when the saved state is not restored, because the last
// fragment is restored if savesInstanceState is not null. // fragment is restored if savesInstanceState is not null.
if (savedInstanceState == null) {
showInitialFragment();
} else {
mShowInitialFragment = false;
}
} }
@@ -95,10 +99,11 @@ public abstract class FragmentActivity extends BaseActivity implements NotifyInt
protected FragmentTransaction showFragment(Fragment fragment, boolean addToBackStack) { protected FragmentTransaction showFragment(Fragment fragment, boolean addToBackStack) {
currentFragment = (BaseFragment) fragment; currentFragment = (BaseFragment) fragment;
currentFragment.setNotifyInterface(this); currentFragment.setNotifyInterface(this);
LogUtils.loge("showFragment===>mFragmentManager1");
if (mFragmentManager == null) { if (mFragmentManager == null) {
return null; return null;
} }
LogUtils.loge("showFragment===>mFragmentManager2");
FragmentTransaction ft = mFragmentManager.beginTransaction(); FragmentTransaction ft = mFragmentManager.beginTransaction();
// ft.setCustomAnimations( // ft.setCustomAnimations(
// R.anim.slide_left_in, // R.anim.slide_left_in,
@@ -128,6 +133,7 @@ public abstract class FragmentActivity extends BaseActivity implements NotifyInt
} }
if (!fragment.isAdded()) { if (!fragment.isAdded()) {
ft.replace(getFramlayoutId(), fragment, tag).commit(); ft.replace(getFramlayoutId(), fragment, tag).commit();
LogUtils.loge("showFragment===>replace");
} else { } else {
ft.show(fragment).commit(); ft.show(fragment).commit();
} }
@@ -139,7 +145,9 @@ public abstract class FragmentActivity extends BaseActivity implements NotifyInt
@Override @Override
public void onMessageEvent(MessageEvent event) { public void onMessageEvent(MessageEvent event) {
super.onMessageEvent(event); super.onMessageEvent(event);
// if(MessageEvent.ACTION_UPADATE_DATA_SOURCE.equals(event.action)){ if(MessageEvent.ACTION_UPADATE_APPS_SOURCE.equals(event.action)){
setFragmentsDisableRefreshDataFlag();
}
// 更新UI // 更新UI
if(currentFragment!=null){ if(currentFragment!=null){
currentFragment.onResumeFragment(event); currentFragment.onResumeFragment(event);
@@ -147,7 +155,7 @@ public abstract class FragmentActivity extends BaseActivity implements NotifyInt
// } // }
} }
public abstract void setFragmentsDisableRefreshDataFlag();
protected boolean isShowDisplay() { protected boolean isShowDisplay() {
int count = mFragmentManager.getBackStackEntryCount(); int count = mFragmentManager.getBackStackEntryCount();
if (count > 0) { if (count > 0) {

View File

@@ -153,7 +153,10 @@ public abstract class CategoryFragment extends BaseFragment implements AppnetCal
mCategoryAppPresenter.loadAppByCategory(category); mCategoryAppPresenter.loadAppByCategory(category);
} }
@Override
public void resetDisableRefreshDataFlag() {
disableFreshData=false;
}
protected abstract void toNextPage(); protected abstract void toNextPage();

View File

@@ -135,9 +135,10 @@ public class MainFragment extends BaseFragment implements ShortAppInfoAdapter.On
ADSWindowManager.getInstance().startVideo(); ADSWindowManager.getInstance().startVideo();
} }
@Override
public void resetDisableRefreshDataFlag() {
}
@SuppressLint("UnsafeOptInUsageError") @SuppressLint("UnsafeOptInUsageError")

View File

@@ -161,6 +161,7 @@ public class RecommendFragment extends CategoryFragment {
@Override @Override
public void onResumeFragment(MessageEvent event) { public void onResumeFragment(MessageEvent event) {
super.onResumeFragment(event); super.onResumeFragment(event);
disableFreshData=false;
loadAppInfoByCategory(AppManager.CATEGORY_RECOMMEND);//重新加载数据 loadAppInfoByCategory(AppManager.CATEGORY_RECOMMEND);//重新加载数据
} }
} }

View File

@@ -130,6 +130,7 @@ public class VideoFragment extends CategoryFragment {
@Override @Override
protected void initData() { protected void initData() {
LogUtils.loge("VideoFragment===>initData()");
loadAppInfoByCategory(AppManager.CATEGORY_VIDEO); loadAppInfoByCategory(AppManager.CATEGORY_VIDEO);
} }
@@ -160,6 +161,7 @@ public class VideoFragment extends CategoryFragment {
@Override @Override
public void onResumeFragment(MessageEvent event) { public void onResumeFragment(MessageEvent event) {
super.onResumeFragment(event); super.onResumeFragment(event);
LogUtils.loge("VideoFragment===>onResumeFragment()");
disableFreshData=false; disableFreshData=false;
loadAppInfoByCategory(AppManager.CATEGORY_VIDEO);//重新加载数据 loadAppInfoByCategory(AppManager.CATEGORY_VIDEO);//重新加载数据
} }

View File

@@ -6,6 +6,7 @@ import android.content.res.TypedArray;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.FocusFinder;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -227,7 +228,7 @@ public class CustomRecyclerViewer extends RecyclerView {
public boolean dispatchKeyEvent(KeyEvent event) { public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getAction() == KeyEvent.ACTION_DOWN) {
// int keyCode = event.getKeyCode(); int keyCode = event.getKeyCode();
// if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) { // if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) {
// long current = System.currentTimeMillis(); // long current = System.currentTimeMillis();
// boolean res; // boolean res;
@@ -240,32 +241,40 @@ public class CustomRecyclerViewer extends RecyclerView {
// return res; // return res;
// } // }
// //
if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) {
// View focusedView = getFocusedChild(); // 获取当前获得焦点的view
// View nextFocusView; View focusedView = getFocusedChild(); // 获取当前获得焦点的view
// try { View nextFocusView;
// if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { try {
// // 通过findNextFocus获取下一个需要得到焦点的view if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
// nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_DOWN); // 通过findNextFocus获取下一个需要得到焦点的view
// } else { nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_DOWN);
// // 通过findNextFocus获取下一个需要得到焦点的view } else {
// nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_UP); // 通过findNextFocus获取下一个需要得到焦点的view
// } nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_UP);
// }
//
// LogUtils.loge("nextFocusView===>"+nextFocusView);
// LogUtils.loge("nextFocusView===>" + nextFocusView);
// } catch (Exception e) {
// nextFocusView = null; } catch (Exception e) {
// } nextFocusView = null;
// }
// // 如果获取失败(也就是说需要交给系统来处理焦点, 消耗掉事件,不让系统处理, 并让先前获取焦点的view获取焦点)
// if (nextFocusView == null) { // 如果获取失败(也就是说需要交给系统来处理焦点, 消耗掉事件,不让系统处理, 并让先前获取焦点的view获取焦点)
// focusedView.requestFocus(); if (nextFocusView == null) {
// return true; if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
// focusedView.requestFocus(View.FOCUS_DOWN);
// } }
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
focusedView.requestFocus(View.FOCUS_UP);
}
return true;
}
// } // }
}
// } // }
} }

View File

@@ -129,6 +129,10 @@ public class TvRecyclerView extends RecyclerView {
LogUtils.loge("TvRecyclerView gainFocus="+gainFocus); LogUtils.loge("TvRecyclerView gainFocus="+gainFocus);
} }
} }
//防止失去焦点还是会继续滚动再度获取焦点
public void disScrollFocus(){
hasResetFocus=false;
}
@Override @Override
public boolean hasFocus() { public boolean hasFocus() {

View File

@@ -29,7 +29,7 @@ public class SharedPreferencesUtil {
public static final String CONFIG_LOCAL_BOOKMARK_APP="config_local_bookmark_app";//本地配置 收藏夹 public static final String CONFIG_LOCAL_BOOKMARK_APP="config_local_bookmark_app";//本地配置 收藏夹
public static final String CONFIG_NET_DEFEND_BOOKMARK_APP="config_net_defend_bookmark_app";//网络隔离 收藏夹 public static final String CONFIG_NET_DEFEND_BOOKMARK_APP="config_net_defend_bookmark_app";//网络隔离 收藏夹
public static final String CONFIG_RESET_DISABLE_FRESHDATA_FLAG="config_reset_disable_freshdata_flag";//重置设备禁止刷新数据为true可刷新
public static String getSharePrefrencesString(Context context,String key){ public static String getSharePrefrencesString(Context context,String key){
SharedPreferences sharedPreferences=context.getSharedPreferences(SHARE_NAME,0); SharedPreferences sharedPreferences=context.getSharedPreferences(SHARE_NAME,0);