Compare commits

10 Commits

Author SHA1 Message Date
c8fb7a5d93 1.考虑到retrofit 头header 有d-time 字段 舍弃UploadADBean dtime字段漏提交 2025-11-26 20:49:22 +08:00
824c5fed37 1.考虑到retrofit 头header 有d-time 字段 舍弃UploadADBean dtime字段 2025-11-26 20:38:26 +08:00
7df8c91156 1.优化断电重启文件丢失(服务器已上报),重新下载图片 2025-11-26 19:59:22 +08:00
3311bda502 1.优化处理后台任务含视频有空地址的情况保持代码健壮性
2.优化处理apk下载完成不上报后台后减少EventBus通知
2025-11-26 16:04:15 +08:00
ab21451616 1.上报接口需求由0-资源下载完成1-app下载完成2-app安装完成更改为增加3-app已存在,0改为图片下载完成,1改为视频下载完成,上报字段添加dtime
2.Shareprerence删除key未删除成功更正
3.取消上报接口 原1-app下载完成
2025-11-22 17:12:10 +08:00
ecdbb788f5 1.广告位上报接口和对已上报进行Sharedference存储
2.对广告位更新资源对Sharedference进行清除
2025-11-21 19:29:53 +08:00
7c9a2c44fd 1.同一个广告位交替更换图片有概率产生图片已下载完成但下载任务表未删的情况 2025-11-11 22:10:42 +08:00
fd76fa3a2f 1.优化apk 安装过程中重启apk未安装未删除安装包修改为继续安装 2025-11-11 15:58:34 +08:00
632000cb56 1.apk 安装过程中重启apk未安装未删除安装包修改为继续安装并删除安装包
2.apk 安装过程中重启apk已安装未删除安装包修改为删除安装包
3.DownLoadManager撤回下载任务但文件丢失会产生-tmp 0 size大小文件bug,下载异常日志打印
2025-11-10 16:42:17 +08:00
646719c3fb 1.AppManager和SplashView处理图片断电重启无论多少次图片不显示而其原因为文件变回-tmp情况,广告位5s后刷新
2.DownLoadManeger 处理下载apk安装未完成重启无论多少次不安装情况
3.重命名系统概率不成功把重命名和删除文件操作分开间隔5s
2025-11-08 09:03:38 +08:00
18 changed files with 558 additions and 23 deletions

View File

@@ -11,8 +11,8 @@ android {
minSdkVersion 21
targetSdkVersion 34
multiDexEnabled true
versionCode 568888804
versionName "SNFLauncher-5.6.4"
versionCode 568888806
versionName "SNFLauncher-5.6.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String", "MANUFACTURER", '"allwinner"'
buildConfigField "boolean", "LOG_ENABLED", "false"

View File

@@ -48,7 +48,7 @@ public class SystemService extends Service implements AppnetCallback, NetStateCh
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 = 8 * 60 * 60 * 1000;
// 测试用短间隔
private static final long REQUEST_INTERVAL = 5 * 60 * 1000; // 5分钟
//持久化存储成功请求时间

View File

@@ -30,6 +30,7 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.android.MXQConfig;
import com.android.SharePreUtils;
import com.android.api.encrytion.UtilEncrypt;
import com.android.database.lib.AdsInfoBean;
import com.android.database.lib.AppBean;
@@ -41,9 +42,13 @@ import com.android.monitor.DataBeeObserver;
import com.android.nebulasdk.ADManager;
import com.android.nebulasdk.AppManager;
import com.android.nebulasdk.bean.FavNaviBean;
import com.android.nebulasdk.bean.UploadADBean;
import com.android.nebulasdk.presenter.DownLoadAdPresenter;
import com.android.nebulasdk.presenter.callback.AppnetCallback;
import com.android.util.GsonUtil;
import com.android.util.IntentUtil;
import com.android.util.LogUtils;
import com.android.util.NetUtil;
import com.android.util.PakageInstallUtil;
import com.ik.mboxlauncher.R;
import com.ik.mboxlauncher.ui.adapter.CustomAppAdapter;
@@ -101,6 +106,7 @@ public class Launcher extends FragmentActivity implements SplashView.SplashAdLi
/**闪屏界面是否结束*/
private boolean isSplashEnd=false;
private SplashView mSplashView;
private DownLoadAdPresenter downLoadAdPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -322,7 +328,12 @@ public class Launcher extends FragmentActivity implements SplashView.SplashAdLi
}
private boolean isNetworkAvailable() {
int netState = NetUtil.getNetWorkState(this);
return netState == NetUtil.NETWORK_MOBILE
|| netState == NetUtil.NETWORK_WIFI
|| netState == NetUtil.NETWORK_ETHERNET;
}
@Override
protected int getFramlayoutId() {
return R.layout.main;
@@ -631,6 +642,45 @@ public boolean onGenericMotionEvent(MotionEvent event) {
LogUtils.loge("onMessageEvent===>"+event.action);
if(MessageEvent.ACTION_UPADATE_DATA_SOURCE.equals(event.action)) {
ADManager.getInstance().updateDownloadTaskBeanTable();
if(isNetworkAvailable()){
ArrayList<UploadADBean.RecordsBean> uploadAds = ADManager.getInstance().getUploadAds();
if(uploadAds.size()>0){
if(downLoadAdPresenter==null){
downLoadAdPresenter = new DownLoadAdPresenter(new AppnetCallback() {
@Override
public void onResult(Object data) {
LogUtils.loge("DownLoadAdPresenter result="+String.valueOf(data));
SharePreUtils.savePreference();
}
@Override
public void onViewFailureString(int code, String message) {
LogUtils.loge("DownLoadAdPresenter onViewFailureString="+message);
SharePreUtils.resetDataList();
}
@Override
public void onExceptionFailure(String message) {
LogUtils.loge("DownLoadAdPresenter onExceptionFailure="+message);
SharePreUtils.resetDataList();
}
@Override
public void onServerFailure(int code, String message) {
LogUtils.loge("DownLoadAdPresenter onServerFailure="+message+"code="+code);
SharePreUtils.resetDataList();
}
});
}
try {
downLoadAdPresenter.postDownLoadAds(Launcher.this,uploadAds);
} catch (Exception e) {
LogUtils.loge("downLoadAdPresenter net request error"+e.getMessage());
SharePreUtils.resetDataList();
//throw new RuntimeException(e);
}
}
}
handler.removeCallbacks(runnable);
handler.postDelayed(runnable,1000*5);
@@ -949,7 +999,10 @@ public boolean onGenericMotionEvent(MotionEvent event) {
if(isSplashEnd) {
ADSWindowManager.getInstance().startVideo();
}
if(isNetworkAvailable()){
ADManager.getInstance().clearTaskInteruptQueueAndRestart();
ADManager.getInstance().clearApkFileByPowerDown();
}
setImageViewData();
loadShortAppList();
}

View File

@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.android.SharePreUtils;
import com.android.monitor.DataBeeObserver;
import com.android.nebulasdk.ADManager;
import com.android.nebulasdk.AppManager;
@@ -27,7 +28,7 @@ public class MyApplication extends Application {
DataBeeObserver.init(getApplicationContext());
AppManager.init(getApplicationContext());
ADManager.init(getApplicationContext());
SharePreUtils.getInstance(getApplicationContext());
AdConfig config = new AdConfig.Builder()
.isDebug(false)//是否开始 debug 模式开启会打印更多log供开发调试
.productName("aike")//正式发版时使用正式的PN

View File

@@ -184,7 +184,7 @@ public class HomeMultiView extends MultiView {
@Override
public void onImageRestartLocal(String path){
LogUtils.loge("onImageRestartLocal==>"+path);
if(path==null){
if(TextUtils.isEmpty(path)){
return;
}
img_view.setVisibility(VISIBLE);

View File

@@ -158,10 +158,17 @@ public class SplashView {
}
File file = new File(adsInfoBeanInfo.getLocalFilePath());
if(!file.exists()){
File tempFile=new File(adsInfoBeanInfo.getLocalFilePath()+"-tmp");
if(tempFile.exists()&&tempFile.length()==adsInfoBeanInfo.getAdSize()){
tempFile.renameTo(file);
tempFile.delete();
LogUtils.loge("下载大小完成但重命名失败同时下载任务已清除图片至始至终未显示优化处理 system rename file file bug compose");
}else {
LogUtils.loge("file is not exits===>");
mHandler.sendEmptyMessageDelayed(2,10000);
return ;
}
}
if(adsInfoBeanInfo.getState()==0){

View File

@@ -0,0 +1,103 @@
package com.android;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import com.android.util.GsonUtil;
import com.android.util.LogUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SharePreUtils {
public static final String SHARERE_NAME="upload_ads_droid";
private static SharePreUtils mInstance;
private static List<Map<String, Object>> dataList;//处理一对多的关系 key为AdSourceId value 为任务类型值
private static SharedPreferences.Editor editor;
private static SharedPreferences sharedPreferences;
public SharePreUtils(Context context) {
sharedPreferences=context.getSharedPreferences(SHARERE_NAME,Context.MODE_PRIVATE);
editor=sharedPreferences.edit();
dataList=getDataList();
}
public synchronized static SharePreUtils getInstance(Context context){
if(mInstance==null){
mInstance=new SharePreUtils(context);
}
return mInstance;
}
public synchronized static List<Map<String, Object>> getDataList(){
if(dataList==null){
String adsHasUpload = sharedPreferences.getString("ads_has_upload", "");
if(!TextUtils.isEmpty(adsHasUpload)){
List<Map<String, Object>> mapList = GsonUtil.GsonToListMaps(adsHasUpload);
dataList=mapList;
}else{
dataList=new ArrayList<>();
}
}
return dataList;
}
public synchronized static void addRelation(String key, Object value) {
if(dataList!=null){
Map<String, Object> record = new HashMap<>();
record.put("relation_key", key);
record.put("relation_value", value);
dataList.add(record);
}
}
public static boolean filterByKeyValue(String key, Object value) {
List<Map<String, Object>> filtered = new ArrayList<>();
if(dataList!=null){
for (Map<String, Object> record : dataList) {
if (key.equals(record.get("relation_key")) &&(value == null ? record.get("relation_value") == null :value.equals(record.get("relation_value")))) {
filtered.add(record);
}
}
}
LogUtils.loge("filterByKeyValue() size"+filtered.size()+"dataList() size"+dataList.size());
return filtered.size()==1;
}
public synchronized static void savePreference(){
if(dataList!=null&&dataList.size()>0){
String commitJson = GsonUtil.GsonString(dataList);
editor.putString("ads_has_upload",commitJson).apply();
}
}
public static void removeKeyFromAllMaps(String keyToRemove) {
if (dataList == null || keyToRemove == null) {
return;
}
List<Map<String, Object>> current=new ArrayList<>();
// 遍历列表中的每个Map
for (Map<String, Object> map : dataList) {
if (map != null) {
// 使用remove方法删除指定键
if(!map.containsValue(keyToRemove)){
current.add(map);
}
}
}
dataList=current;
//LogUtils.loge("removeKeyFromAllMaps current()"+current.size());
}
public static void resetDataList(){
String adsHasUpload = sharedPreferences.getString("ads_has_upload", "");
if(!TextUtils.isEmpty(adsHasUpload)&& GsonUtil.isJson(adsHasUpload)){
List<Map<String, Object>> mapList = GsonUtil.GsonToListMaps(adsHasUpload);
dataList=mapList;
}else{
dataList=new ArrayList<>();
}
}
}

View File

@@ -27,4 +27,8 @@ public interface ServerApi {
@POST(ServerInterface.POST_LAUNCHER_ADS)
Call<String> postLauncherAds(@Body RequestBody requestBody);
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST(ServerInterface.POST_DOWNLOAD_ADS)
Call<String> postDownLoadAds(@Body RequestBody requestBody);
}

View File

@@ -21,6 +21,8 @@ public class ServerInterface {
/**上传事件信息*/
public static final String POST_EVENTINFO_DEVICE="/app-api/third/launcher/ad/play/callback";
public static final String POST_DOWNLOAD_ADS="/app-api/launcher/ad/cb";
private static final boolean USER_DEBUG=false;

View File

@@ -4,6 +4,7 @@ package com.android.api.biz;
import com.android.api.biz.OnBaseListener;
import com.android.database.lib.RecordEventBean;
import com.android.nebulasdk.bean.EventDataInfo;
import com.android.nebulasdk.bean.UploadADBean;
import java.util.List;
import java.util.Map;
@@ -19,8 +20,8 @@ public interface Biz {
void postLauncherAds(Map<String ,String > map, OnBaseListener listener);
//记录设备事件的接口
void postEventData(List<EventDataInfo> recordEventBeans, OnBaseListener listener);
//上传各个广告位下载状态
void postDownloadAd(UploadADBean uploadADBean, OnBaseListener listener);

View File

@@ -2,6 +2,7 @@ package com.android.api.biz.bizimpl;
import com.android.api.biz.Biz;
import com.android.nebulasdk.bean.EventDataInfo;
import com.android.nebulasdk.bean.UploadADBean;
import com.google.gson.JsonObject;
import com.android.api.ServerApi;
import com.android.api.biz.BaseBiz;
@@ -110,5 +111,38 @@ public class BizImpl extends BaseBiz implements Biz {
});
}
@Override
public void postDownloadAd(UploadADBean uploadADBean, OnBaseListener listener) {
RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), GsonUtil.GsonString(uploadADBean));
getStringRetrofit().create(ServerApi.class).postDownLoadAds(requestBody).enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(call != null){
if (response.body() != null) {
LogUtils.loge("postLauncherAds response==>" + GsonUtil.GsonString(response.body()));
if (response.isSuccessful()) {
listener.onResponse(response.body());
} else {
listener.onFailure(response.message(), response.raw().code());
}
} else {
listener.onFailure("The server is busy, please try again later", response.raw().code());
}
}else {
LogUtils.loge("postDownloadAd Biz>>>>>>>>>>>>>>>>>>call == null<<<<<<<<<<<<<<<<<<");
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
if (call.isExecuted()) {
call.cancel();
}
LogUtils.loge("recoedDeviceEvent Biz服务器未响应请求失败==>" + GsonUtil.GsonString(t.getMessage()));
listener.onFailure("The server is busy, please try again later", 0);
}
});
}
}

View File

@@ -9,6 +9,7 @@ import com.android.util.GsonUtil;
import com.android.util.LogUtils;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class DownLoadManeger {
@@ -135,6 +136,20 @@ public class DownLoadManeger {
if(file.exists()&&downLoadTaskBean.getCurrentProgress()==file.length()&&file.length()<=downLoadTaskBean.getTotal()){
TaskQueue.getInstance().remove(downLoadTaskBean);
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));
}else if(downLoadTaskBean.getTaskType()==1){//apk 下载完成未安装断电重新启动下载任务 因为需要安装apk
File apkFile = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName());
if(apkFile.exists()&&apkFile.length()==downLoadTaskBean.getTotal()&&downLoadTaskBean.getCurrentProgress()<downLoadTaskBean.getTotal()){
TaskQueue.getInstance().remove(downLoadTaskBean);
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));
}
}else if(downLoadTaskBean.getTaskType()==0){//图片文件下载完成 删除downloadtaskbean表数据脏数据
File imgFile = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName());
if(imgFile.exists()&&imgFile.length()==downLoadTaskBean.getTotal()){
DaoManager.getInstance().delete(DownLoadTaskBean.class,downLoadTaskBean);
}
}
if(!file.exists()&&downLoadTaskBean.getCurrentProgress()==0){
LogUtils.loge("power down but downloadstaskbean table remain task");
}
}
}
@@ -274,4 +289,9 @@ public class DownLoadManeger {
}
}
};
public boolean checkTaskQueueClear(){
LogUtils.loge("checkTaskQueueClear() size="+TaskQueue.getInstance().getAllTask().size());
return TaskQueue.getInstance().size()==0;
}
}

View File

@@ -49,6 +49,7 @@ public class DownLoadTaskThread implements Runnable {
File dataFile = new File(bean.getPath(), bean.getFileName());
if(dataFile.exists()&&dataFile.length()==bean.getTotal()){ //判断该文件已下载无需再下载
LogUtils.loge("dont need download "+bean.getFileName());
observer.onFinish(bean, bean.getTaskId(), dataFile.length());
return;
}
@@ -63,9 +64,9 @@ public class DownLoadTaskThread implements Runnable {
if(currentTotal==bean.getTotal()){
File targFile = new File(bean.getPath(), bean.getFileName());
file.renameTo(targFile);//重命名
file.delete();//删除临时文件
Thread.sleep(5000);
Thread.sleep(3000);
observer.onFinish(bean, bean.getTaskId(), currentTotal);
file.delete();//删除临时文件
return;
}
//设置下载位置
@@ -114,10 +115,10 @@ public class DownLoadTaskThread implements Runnable {
LogUtils.loge("download Exception===>sleeping before");
File targFile = new File(bean.getPath(), bean.getFileName());
file.renameTo(targFile);//重命名
file.delete();//删除临时文件
Thread.sleep(5000);
Thread.sleep(3000);
LogUtils.loge("download Exception===>sleeping after");
observer.onFinish(bean, bean.getTaskId(), currentTotal);
file.delete();//删除临时文件
}else {
LogUtils.loge("下载失败");
if (observer != null) {

View File

@@ -4,6 +4,7 @@ import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import com.android.SharePreUtils;
import com.android.database.AdsInfoBeanDao;
import com.android.database.DaoManager;
import com.android.database.lib.AdsInfoBean;
@@ -14,6 +15,7 @@ import com.android.download.DownLoadManeger;
import com.android.eventbaus.EventBusUtils;
import com.android.eventbaus.MessageEvent;
import com.android.nebulasdk.bean.ADInfo;
import com.android.nebulasdk.bean.UploadADBean;
import com.android.util.FileUtil;
import com.android.util.GsonUtil;
import com.android.util.LogUtils;
@@ -115,18 +117,20 @@ public class ADManager implements DownLoadManeger.DownloadListener {
// if(adsInfoBean.getAdId()==aDInfo.getAdId()){ //是同一个任务,根据版本号更新新资源
LogUtils.loge("aDInfo.getAdVersion()|adsInfoBean.getAdVersion():"+aDInfo.getAdVersion()+"|"+adsInfoBean.getAdVersion());
if(Long.valueOf(aDInfo.getAdVersion())!=adsInfoBean.getAdVersion()){ //更新新资源
SharePreUtils.removeKeyFromAllMaps(String.valueOf(adsInfoBean.getAdResourceId()));
LogUtils.loge("广告位"+adsInfoBean.getId()+"已存在,是同一个任务同步资源,需要删除缓存文件:"+GsonUtil.GsonString(adsInfoBean));//先删除旧任务的缓存文件,再更新数据
String dbLocalFilePath=adsInfoBean.getLocalFilePath();
if(!TextUtils.isEmpty(dbLocalFilePath)) {
int lastIndex = dbLocalFilePath.lastIndexOf("/");
String fileName=lastIndex==-1?dbLocalFilePath:dbLocalFilePath.substring(lastIndex+1);
if(!aDInfo.getAdUri().contains(fileName)){
if(TextUtils.isEmpty(aDInfo.getAdUri())||!aDInfo.getAdUri().contains(fileName)){
File oldfile = new File(dbLocalFilePath);
List<AdsInfoBean> adSInfoBeanList =DaoManager.getInstance().queryByKeyList(AdsInfoBean.class,"localFilePath",dbLocalFilePath);
if (oldfile.exists()&& adSInfoBeanList.size()==1) {
oldfile.delete();
}
}else {
//todo SharePreUtils.addRelation(String.valueOf(aDInfo.getAdResourceId()),String.valueOf(0));
LogUtils.loge("广告位仅换apk不换图 fresh apk not fresh img,dont delete img but download");
}
}
@@ -335,7 +339,7 @@ public class ADManager implements DownLoadManeger.DownloadListener {
}else {
LogUtils.loge("app已安装");
SharePreUtils.addRelation(String.valueOf(adinfo.getAdResourceId()),String.valueOf(3));
}
}else {
LogUtils.loge("没有app任务");
@@ -406,7 +410,7 @@ public class ADManager implements DownLoadManeger.DownloadListener {
EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_DATA_SOURCE));
}
},1000*5);
// EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_DATA_SOURCE));
}else{
EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_DATA_SOURCE));
}
@@ -454,7 +458,117 @@ public class ADManager implements DownLoadManeger.DownloadListener {
DownLoadManeger.getInstance().updateDownloadTaskBeanTable();
}
public void clearApkFileByPowerDown(){
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class);
if(list==null||list.size()==0){
String apkDir = FileUtil.getBakPath(mContext, 1);
File apkFile = new File(apkDir);
if(apkFile.exists()){
File[] files = apkFile.listFiles();
for (int i = 0; i < files.length; i++) {
boolean isApk = files[i].getAbsolutePath().endsWith("apk");
if(isApk){
String apkFileName = files[i].getName();
int apkFileContainIndex=-1;
List<AdsInfoBean> adsInfoBeanList = DaoManager.getInstance().queryList(AdsInfoBean.class);
for (int j = 0; j < adsInfoBeanList.size(); j++) {
if(!TextUtils.isEmpty(adsInfoBeanList.get(j).getAppUrl())&&adsInfoBeanList.get(j).getAppUrl().contains(apkFileName)){
apkFileContainIndex=j;
break;
}
}
if(apkFileContainIndex==-1){
files[i].delete();
LogUtils.loge("apk data rm need delete app");
}else {
AdsInfoBean adsInfoBean = adsInfoBeanList.get(apkFileContainIndex);
if(!(PakageInstallUtil.checkAppInstall(mContext,adsInfoBean.getInfo()))||PakageInstallUtil.checkAppUpdate(mContext,adsInfoBean.getInfo(),(int) adsInfoBean.getAppVersion())){ //需要跟新app
LogUtils.loge("need reinstall app");
addDownloadTask(adsInfoBean,adsInfoBean.getAppUrl(),1,adsInfoBean.getAppSize());
}else {
LogUtils.loge("need delete app");
files[i].delete();
}
}
}
}
}
}
}
public void hasDownloadButLostFile(AdsInfoBean adsInfoBean,String url, int taskType,long fileSize){
addDownloadTask(adsInfoBean,url,taskType,fileSize);
}
public boolean checkTaskQueueClear(){
return DownLoadManeger.getInstance().checkTaskQueueClear();
}
public ArrayList<UploadADBean.RecordsBean> getUploadAds(){
List<AdsInfoBean> adsInfoBeanList = DaoManager.getInstance().queryByKeyList(AdsInfoBean.class, "state", "1");
ArrayList<UploadADBean.RecordsBean> uploadAdList=new ArrayList<>();
for (int i = 0; i < adsInfoBeanList.size(); i++) {
AdsInfoBean adsInfoBean = adsInfoBeanList.get(i);
String appUrl=adsInfoBean.getAppUrl();
if(!TextUtils.isEmpty(adsInfoBean.getAppUrl())){
// int lastIndex = appUrl.lastIndexOf("/");
// String fileName=lastIndex==-1?appUrl:appUrl.substring(lastIndex+1);
// String filePath = FileUtil.getBakPath(mContext,1)+"/"+fileName;
// String tmpFilePath = FileUtil.getBakPath(mContext, 1) + "/" + fileName + "-tmp";
// File tmpFile=new File(tmpFilePath);
// File file =new File(filePath);
if((PakageInstallUtil.checkAppInstall(mContext,adsInfoBean.getInfo()))&& !PakageInstallUtil.checkAppUpdate(mContext,adsInfoBean.getInfo(),(int) adsInfoBean.getAppVersion())) {
if (!SharePreUtils.filterByKeyValue(String.valueOf(adsInfoBean.getAdResourceId()), String.valueOf(2))) {
SharePreUtils.addRelation(String.valueOf(adsInfoBean.getAdResourceId()), String.valueOf(2));
UploadADBean.RecordsBean recordsBean = new UploadADBean.RecordsBean();
recordsBean.setAdResourceId(adsInfoBean.getAdResourceId());
if (SharePreUtils.filterByKeyValue(String.valueOf(adsInfoBean.getAdResourceId()), String.valueOf(3))) {//考虑到3为app已安装 analysisResInfo
recordsBean.setType(3);
} else {
recordsBean.setType(2);
}
uploadAdList.add(recordsBean);
}
LogUtils.loge("==============resid" + adsInfoBean.getAdResourceId());
}
// }else if(file.exists()||(tmpFile.exists()&&tmpFile.length()==adsInfoBean.getAppSize())){
// if(!SharePreUtils.filterByKeyValue(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(1))){
// SharePreUtils.addRelation(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(1));
// UploadADBean.RecordsBean recordsBean = new UploadADBean.RecordsBean();
// recordsBean.setAdResourceId(adsInfoBean.getAdResourceId());
// recordsBean.setType(1);
// uploadAdList.add(recordsBean);
// }
// }
}
if(!TextUtils.isEmpty(adsInfoBean.getLocalFilePath())){
File file = new File(adsInfoBean.getLocalFilePath());
File tmpFile=new File(adsInfoBean.getLocalFilePath()+"-tmp");
if(file.exists()||(tmpFile.exists()&&tmpFile.length()==adsInfoBean.getAdSize())){
if(ADTYPE_IMAGE.equalsIgnoreCase(adsInfoBean.getAdType())){
if(!SharePreUtils.filterByKeyValue(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(0))){
SharePreUtils.addRelation(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(0));
UploadADBean.RecordsBean recordsBean = new UploadADBean.RecordsBean();
recordsBean.setAdResourceId(adsInfoBean.getAdResourceId());
recordsBean.setType(0);
uploadAdList.add(recordsBean);
}
}else if(ADTYPE_VIDEO.equalsIgnoreCase(adsInfoBean.getAdType())){
if(!SharePreUtils.filterByKeyValue(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(1))){
SharePreUtils.addRelation(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(1));
UploadADBean.RecordsBean recordsBean = new UploadADBean.RecordsBean();
recordsBean.setAdResourceId(adsInfoBean.getAdResourceId());
recordsBean.setType(1);
uploadAdList.add(recordsBean);
}
}
LogUtils.loge("==============resid"+adsInfoBean.getAdResourceId());
}
}
}
if(uploadAdList.size()>0){
LogUtils.loge(GsonUtil.GsonString(uploadAdList));
}
return uploadAdList;
}
}

View File

@@ -5,17 +5,23 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.text.TextUtils;
import com.android.SharePreUtils;
import com.android.database.DaoManager;
import com.android.database.lib.AdsInfoBean;
import com.android.database.lib.AppBean;
import com.android.database.lib.DownLoadTaskBean;
import com.android.database.lib.LocalAppBean;
import com.android.database.lib.MusicAppBean;
import com.android.database.lib.NetShortAppBean;
import com.android.database.lib.RecommendAppBean;
import com.android.database.lib.ShortAppBean;
import com.android.database.lib.VideoAppBean;
import com.android.eventbaus.EventBusUtils;
import com.android.eventbaus.MessageEvent;
import com.android.nebulasdk.bean.FavNaviBean;
import com.android.util.FileUtil;
import com.android.util.GsonUtil;
import com.android.util.LogUtils;
import com.android.util.PakageInstallUtil;
@@ -586,12 +592,55 @@ public class AppManager {
File file = new File(adsInfoBean.getLocalFilePath());
if (file.exists()) {
favNaviBean = new FavNaviBean(index, adsInfoBean.getLocalFilePath(), adsInfoBean.getInfo(), null);
}else {
}else {//考虑下载好图片重启后变回 -tmp文件的情况
File tempFile=new File(adsInfoBean.getLocalFilePath()+"-tmp");
//对已上报的图片文件 系统丢失文件情况 重新下载
if(!tempFile.exists()&& SharePreUtils.filterByKeyValue(String.valueOf(adsInfoBean.getAdResourceId()),String.valueOf(0))){
LogUtils.loge("sys lost file which has upload,redownload it but not notify");
ADManager.getInstance().hasDownloadButLostFile(adsInfoBean,adsInfoBean.getAdUri(),0,adsInfoBean.getAdSize());
}
if(tempFile.exists()&&tempFile.length()==adsInfoBean.getAdSize()){
tempFile.renameTo(file);
tempFile.delete();
EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_DATA_SOURCE));
LogUtils.loge("下载大小完成但重命名失败同时下载任务已清除图片至始至终未显示处理 sys rename failed bug solved");
}
LogUtils.loge(file.getPath()+" is not exit");
}
}
}else {
LogUtils.loge(adsInfoBean.getInfo()+" is not exit");
LogUtils.loge(adsInfoBean.getInfo()+" is not exit");//考虑下载好APK重启后变回 -tmp文件的情况 补充clearApkFileByPowerDown 下载任务有脏数据情况下
String appUrl = adsInfoBean.getAppUrl();
boolean taskTableHasIt=false;
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class);
for (int i = 0; i <list.size() ; i++) {
if(list.get(i).getUrl().equalsIgnoreCase(appUrl)){
taskTableHasIt=true;
break;
}
}
if(!TextUtils.isEmpty(appUrl)&&!taskTableHasIt){
int lastIndex = appUrl.lastIndexOf("/");
String fileName=lastIndex==-1?appUrl:appUrl.substring(lastIndex+1);
String filePath = FileUtil.getBakPath(mContext,1)+"/"+fileName;
String tmpFilePath = FileUtil.getBakPath(mContext, 1) + "/" + fileName + "-tmp";
File tmpFile=new File(tmpFilePath);
File file =new File(filePath);
if(tmpFile.exists()&&tmpFile.length()==adsInfoBean.getAppSize()){
LogUtils.loge(adsInfoBean.getInfo()+" but apk tmpfile is exit");
tmpFile.renameTo(file);
//tmpFile.delete();
if(list!=null&&list.size()>0){
boolean flag = PakageInstallUtil.silentInstall(mContext, file.getAbsolutePath());
LogUtils.loge("no task and restart sys apk back to tmp install result="+flag);
}
}else if(file.exists()&&file.length()==adsInfoBean.getAppSize()){
if(list!=null&&list.size()>0){
boolean flag = PakageInstallUtil.silentInstall(mContext, file.getAbsolutePath());
LogUtils.loge("no task and restart sys apk not install result="+flag);
}
}
}
}
}

View File

@@ -0,0 +1,77 @@
package com.android.nebulasdk.bean;
import java.util.List;
public class UploadADBean {
/**
* mac : 9C:00:D3:86:31:DF
* cpu : 1747248796593488611d7d3114575b9
* records : [{"adId":494,"type":0,"ts":1763450525769},{"adId":494,"type":2,"ts":1763450525769},{"adId":494,"type":0,"ts":1763450925769},{"adId":396,"type":0,"ts":1763450525769}]
*/
private String mac;
private String cpu;
private List<RecordsBean> records;
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public List<RecordsBean> getRecords() {
return records;
}
public void setRecords(List<RecordsBean> records) {
this.records = records;
}
public static class RecordsBean {
/**
* adId : 494
* type : 0
* ts : 1763450525769
*/
private long adResourceId;
private int type;
//private long ts;
public long getAdResourceId() {
return adResourceId;
}
public void setAdResourceId(long adId) {
this.adResourceId = adId;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
// public long getTs() {
// return ts;
// }
//
// public void setTs(long ts) {
// this.ts = ts;
// }
}
}

View File

@@ -0,0 +1,69 @@
package com.android.nebulasdk.presenter;
import android.content.Context;
import android.util.Log;
import com.android.MXQConfig;
import com.android.api.ServerInterface;
import com.android.api.biz.Biz;
import com.android.api.biz.OnBaseListener;
import com.android.api.biz.bizimpl.BizImpl;
import com.android.api.response.EventResponse;
import com.android.nebulasdk.bean.ADInfoResponse;
import com.android.nebulasdk.bean.UploadADBean;
import com.android.nebulasdk.presenter.callback.AppnetCallback;
import com.android.util.DeviceUtil;
import com.android.util.GsonUtil;
import com.android.util.LogUtils;
import com.android.util.RKDeviceUtil;
import java.util.ArrayList;
public class DownLoadAdPresenter {
private Biz biz;
private AppnetCallback mAppnetCallback;
public DownLoadAdPresenter(AppnetCallback mAppnetCallback) {
this.mAppnetCallback = mAppnetCallback;
biz = new BizImpl(ServerInterface.createHttpUrl());
}
public void postDownLoadAds(Context context,ArrayList<UploadADBean.RecordsBean> recordsBeans){
UploadADBean uploadADBean=new UploadADBean();
String cpuId ="";
if(MXQConfig.ALLWINNER_PLATFORM.equalsIgnoreCase(MXQConfig.getManufacturer())) {
cpuId = DeviceUtil.getCpu();
}else if(MXQConfig.RK_PLATFORM.equalsIgnoreCase(MXQConfig.getManufacturer())){
cpuId = RKDeviceUtil.getCpu();
}
uploadADBean.setCpu(cpuId);
uploadADBean.setMac(DeviceUtil.getEthernetMac());
uploadADBean.setRecords(recordsBeans);
biz.postDownloadAd(uploadADBean, new OnBaseListener() {
@Override
public void onResponse(String result) {
LogUtils.loge(GsonUtil.GsonString(result));
if(GsonUtil.isJson(result)){
try {
EventResponse eventResponse = GsonUtil.GsonToBean(result, EventResponse.class);
if (eventResponse.getCode() == ServerInterface.SUCCESS) {
mAppnetCallback.onResult(eventResponse.getData());
} else {
mAppnetCallback.onViewFailureString(eventResponse.getCode(), eventResponse.getMsg());
}
} catch (Exception e) {
e.printStackTrace();
mAppnetCallback.onExceptionFailure("json 解析异常:"+e.getMessage());
}
}else {
mAppnetCallback.onServerFailure(0,"获取签到信息,服务器繁忙··");
}
}
@Override
public void onFailure(String e, int code) {
mAppnetCallback.onServerFailure(code,e);
}
});
}
}