Bladeren bron

修复有些8.0及以上手机无法监听到截图的问题;
监听截图修改为可以上传所有截图;
提交截图接口添加设备信息(用来查看哪些机型不调配);
任务审核中添加重新提交的判断

zengjiebin 7 jaren geleden
bovenliggende
commit
7df7e4c726

+ 6 - 2
app/src/main/AndroidManifest.xml

@@ -128,9 +128,13 @@
             android:name=".service.FloatShotScreenService" />
         <service
             android:name=".service.ListenerShotService"
-            android:priority="1000"
-            android:exported="false"
+            android:enabled="true"
+            android:exported="true"
             android:process=":listener" />
+        <service
+            android:name=".service.ListenerShotNewService"
+            android:enabled="true"
+            android:exported="true" />
 
         <provider
             android:name=".provider.SheepFileProvider"

+ 1 - 1
app/src/main/java/com/sheep/gamegroup/absBase/AbsChooseImageActivity.java

@@ -197,7 +197,7 @@ public abstract class AbsChooseImageActivity extends BaseActivity implements UpF
      * 上传图片前的回调
      * @return
      */
-    protected ICallBack<String> getCallBack(){
+    protected ICallBack<Boolean> getCallBack(){
         return null;
     }
 

+ 13 - 0
app/src/main/java/com/sheep/gamegroup/greendao/DDProviderHelper.java

@@ -397,4 +397,17 @@ public class DDProviderHelper {
                 .build()
                 .list();
     }
+    /**
+     * 是否监听到该截图
+     *
+     * @param ctx
+     */
+    public ScreenShotRecord getScreenShotRecord(Context ctx, String packageName, String imagePath) {
+        return getDaossion(ctx)
+                .getScreenShotRecordDao()
+                .queryBuilder()
+                .where(ScreenShotRecordDao.Properties.PackageName.eq(packageName), ScreenShotRecordDao.Properties.Path.eq(imagePath), ScreenShotRecordDao.Properties.UserId.eq(DataUtil.getInstance().getUserId()))
+                .build()
+                .unique();
+    }
 }

+ 13 - 1
app/src/main/java/com/sheep/gamegroup/model/api/ICallBack.java

@@ -1,9 +1,21 @@
 package com.sheep.gamegroup.model.api;
 
+import android.support.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Created by realicing on 2018/8/28.
  * realicing@sina.com
  */
 public interface ICallBack<T> {
-    T call(Object...args);
+    T call(@CALL_BACK_TYPE int type, Object...args);
+    int DECODE_PNG = 1;
+    int IS_RECORD = 2;
+
+    @IntDef({DECODE_PNG, IS_RECORD})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface CALL_BACK_TYPE {
+    }
 }

+ 23 - 0
app/src/main/java/com/sheep/gamegroup/model/entity/TaskAcceptedEty.java

@@ -25,6 +25,7 @@ public class TaskAcceptedEty implements Serializable{
     private TaskReleaseEty release_task;
     private int child_task_id;//0 1开始子任务  2完成第二个子任务
     private int task_child_id;
+    private int allowSubmit;//失败或者下线后,是否可以再次提交截图 2 不可以 1 可以
 
     public int getChild_task_id() {
         return child_task_id;
@@ -146,6 +147,14 @@ public class TaskAcceptedEty implements Serializable{
         this.task_child_id = task_child_id;
     }
 
+    public int getAllowSubmit() {
+        return allowSubmit;
+    }
+
+    public void setAllowSubmit(int allowSubmit) {
+        this.allowSubmit = allowSubmit;
+    }
+
     @Override
     public boolean equals(Object obj) {
         return obj instanceof TaskAcceptedEty &&
@@ -174,4 +183,18 @@ public class TaskAcceptedEty implements Serializable{
     public static final int IS_SUCCESSION_ALL = 3;//所有
     public static final int SHOW_GAME_TASK_NO = 0;//不获取游戏任务
     public static final int SHOW_GAME_TASK_YES = 1;//要获取游戏任务
+    //status  1,已接受任务 2,正在进行中,3完成任务,4放弃任务,5任务失败,6审核失败,7提交审核,8任务已下线,9至少完成了一个任务了
+    public static final int STATUS_ACCEPTED_TASK = 1;
+    public static final int STATUS_RUNNING = 2;
+    public static final int STATUS_FINISHED = 3;
+    public static final int STATUS_GIVE_UP = 4;
+    public static final int STATUS_TASK_FAIL = 5;
+    public static final int STATUS_AUDIT_FAILURE = 6;
+    public static final int STATUS_SUBMIT = 7;
+    public static final int STATUS_OFF_LINE = 8;
+    public static final int STATUS_AT_LEAST_COMPLETE_ONE = 9;
+    //canSubmit 失败或者下线后,是否可以再次提交截图 2 不可以 1 可以
+    public static final int ALLOW_SUBMIT_NO = 2;
+    public static final int ALLOW_SUBMIT_YES = 1;
+
 }

+ 2 - 1
app/src/main/java/com/sheep/gamegroup/util/ConnectAddress.java

@@ -25,7 +25,8 @@ public enum ConnectAddress {
 
         @Override
         public String getAppUrl() {
-            return "http://10.8.220.229:8080/";
+            return "http://10.8.220.245:8080/";
+//            return "http://10.8.220.229:8080/";
         }
         @Override
         public String getName() {

+ 19 - 15
app/src/main/java/com/sheep/gamegroup/util/DataUtil.java

@@ -297,25 +297,29 @@ public class DataUtil {
     public static boolean IS_USE_SCREEN_SHOT = false;//默认开启小剪刀截图,有很多问题,调整到单独的后台进程再测试
     //是否监听媒体库图片变化
     public static boolean IS_LISTEN_SCREEN_SHOT = true;
+    //是否上传截图时使用所有图片
+    public static boolean IS_USE_ALL_IMAGE = true;
     //初始化是否启用小绵羊两种截图方案
     private void initScreenShotConfig() {
-        SheepApp.getInstance().getNetComponent().getApiService().needShotScreen()
-                        .subscribeOn(Schedulers.io())
-                        .observeOn(AndroidSchedulers.mainThread())
-                        .subscribe(new SheepSubscriber<BaseMessage>(SheepApp.getInstance()) {
-                            @Override
-                            public void onNext(BaseMessage baseMessage) {
-                                ScreenShotConfig config = baseMessage.getData(ScreenShotConfig.class);
-                                if(config != null) {
-                                    IS_USE_SCREEN_SHOT &= config.isNeed();//默认开启才可配置为false
-                                    IS_LISTEN_SCREEN_SHOT = config.isNeed();
-                                }
+        if(!IS_USE_ALL_IMAGE) {//不启用上传所有截图时才更新截图方案配置
+            SheepApp.getInstance().getNetComponent().getApiService().needShotScreen()
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe(new SheepSubscriber<BaseMessage>(SheepApp.getInstance()) {
+                        @Override
+                        public void onNext(BaseMessage baseMessage) {
+                            ScreenShotConfig config = baseMessage.getData(ScreenShotConfig.class);
+                            if (config != null) {
+                                IS_USE_SCREEN_SHOT &= config.isNeed();//默认开启才可配置为false
+                                IS_LISTEN_SCREEN_SHOT = config.isNeed();
                             }
+                        }
 
-                            @Override
-                            public void onError(BaseMessage baseMessage) {
-                            }
-                        });
+                        @Override
+                        public void onError(BaseMessage baseMessage) {
+                        }
+                    });
+        }
     }
     /**
      * 截图路径

+ 24 - 0
app/src/main/java/com/sheep/gamegroup/util/Jump2View.java

@@ -5,6 +5,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.text.TextUtils;
@@ -109,6 +110,8 @@ import com.sheep.jiuyan.samllsheep.R;
 import com.sheep.jiuyan.samllsheep.SheepApp;
 import com.sheep.jiuyan.samllsheep.service.AutoCheckService;
 import com.sheep.jiuyan.samllsheep.service.FloatShotScreenService;
+import com.sheep.jiuyan.samllsheep.service.ListenerShotNewService;
+import com.sheep.jiuyan.samllsheep.service.ListenerShotService;
 import com.sheep.jiuyan.samllsheep.utils.G;
 import com.sheep.jiuyan.samllsheep.utils.SpUtils;
 
@@ -149,6 +152,7 @@ import static com.sheep.gamegroup.util.UMConfigUtils.Event.USER_NEW_VERSION;
 import static com.sheep.gamegroup.util.UMConfigUtils.Event.USER_TASK_RECORD;
 import static com.sheep.gamegroup.util.UMConfigUtils.Event.XIAOMI_GAME_LIST;
 import static com.sheep.jiuyan.samllsheep.service.FloatShotScreenService.SET_SHOW_OR_HIDE;
+import static com.sheep.jiuyan.samllsheep.service.ListenerShotService.IS_RECORD_PATH;
 
 /**
  * Created by ljy on 2018/3/18.
@@ -266,6 +270,8 @@ public class Jump2View {
         } else {
             context.startActivity(intent);
         }
+        //登录后尝试启动监听截图后台
+        Jump2View.getInstance().startListenerShotService(context);
     }
 
     /**
@@ -1106,6 +1112,24 @@ public class Jump2View {
             }
         }
     }
+    /**
+     * 启动小绵羊悬浮窗
+     *
+     * @param context
+     */
+    public void startListenerShotService(Context context) {
+        if (DataUtil.IS_LISTEN_SCREEN_SHOT && (!IS_RECORD_PATH || !TextUtils.isEmpty(DataUtil.getInstance().getUserId()))) {
+            if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                Intent intent = new Intent(context, ListenerShotNewService.class);
+                intent.putExtra(AutoCheckService.EXTRA_KEY_USER_ID, DataUtil.getInstance().getUserId());//记录用户截图方案需要记录当前用户id
+                context.startForegroundService(intent);
+            } else {
+                Intent intent = new Intent(context, ListenerShotService.class);
+                intent.putExtra(AutoCheckService.EXTRA_KEY_USER_ID, DataUtil.getInstance().getUserId());//记录用户截图方案需要记录当前用户id
+                context.startService(intent);
+            }
+    }
+    }
 
 
     /**

+ 50 - 0
app/src/main/java/com/sheep/gamegroup/util/SysAppUtil.java

@@ -642,4 +642,54 @@ public class SysAppUtil {
         }
         return null;
     }
+
+    //获取设备的信息
+    public static String getUserAgentOrDeviceInfo(){
+        StringBuilder sb = null;
+        try {
+            String userAgent;
+            sb = new StringBuilder();
+            userAgent = System.getProperty("http.agent");//Dalvik/2.1.0 (Linux; U; Android 6.0.1; vivo X9L Build/MMB29M)
+
+            for (int i = 0, length = userAgent.length(); i < length; i++) {
+                char c = userAgent.charAt(i);
+                if (c <= '\u001f' || c >= '\u007f') {
+                    sb.append(String.format("\\u%04x", (int) c));
+                } else {
+                    sb.append(c);
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return TextUtils.isEmpty(sb) ? String.format(Locale.CHINA, "Android %s/%d; Model %s; Brand %s", getSystemVersion(), Build.VERSION.SDK_INT, getSystemModel(), getDeviceBrand()) : sb.toString();
+    }
+
+    /**
+     * 获取当前手机系统版本号
+     *
+     * @return  系统版本号
+     */
+    public static String getSystemVersion() {
+        return android.os.Build.VERSION.RELEASE;
+    }
+
+    /**
+     * 获取手机型号
+     *
+     * @return  手机型号
+     */
+    public static String getSystemModel() {
+        return android.os.Build.MODEL;
+    }
+
+    /**
+     * 获取手机厂商
+     *
+     * @return  手机厂商
+     */
+    public static String getDeviceBrand() {
+        return android.os.Build.BRAND;
+    }
 }

+ 15 - 8
app/src/main/java/com/sheep/gamegroup/util/upfile/UpFileUtils.java

@@ -6,6 +6,7 @@ import android.graphics.Bitmap;
 import com.nanchen.compresshelper.CompressHelper;
 import com.sheep.gamegroup.model.api.ICallBack;
 import com.sheep.gamegroup.model.util.ExceptionHandle;
+import com.sheep.gamegroup.util.DataUtil;
 import com.sheep.jiuyan.samllsheep.SheepApp;
 import com.sheep.jiuyan.samllsheep.service.ListenerShotService;
 import com.sheep.jiuyan.samllsheep.utils.FileUtil;
@@ -61,21 +62,27 @@ public class UpFileUtils {
 
     }
 
-    public static void upImages(ArrayList<String> photos, final UpFileListener upFileListener, ICallBack<String> action1) {
+    public static void upImages(ArrayList<String> photos, final UpFileListener upFileListener, ICallBack<Boolean> action1) {
         upImages(photos, upFileListener, action1, 0);
     }
-    public static void upImages(final ArrayList<String> photos, final UpFileListener upFileListener, final ICallBack<String> action1, final int index) {
+    public static void upImages(final ArrayList<String> photos, final UpFileListener upFileListener, final ICallBack<Boolean> action1, final int index) {
         int size = photos.size();
         if (index < size) {
             File file;
             if ((file = new File(photos.get(index))).exists()) {
                 File newFile = null;
+                boolean convertFile = false;
                 if(ListenerShotService.IS_RECORD_PATH) {
                     try {
-                        if (!Kfzssafe.isPng(file.getAbsolutePath())) {
-                            String toFilePath = String.format(Locale.CHINA, "%s%s_%d.png", file.getParent(), File.separator, System.currentTimeMillis());
-                            FileUtil.convertImage(file.getAbsolutePath(), toFilePath, Bitmap.CompressFormat.PNG);
-                            file = new File(toFilePath);
+                        //是否需要转换图片:不启用上传所有图片时,或者记录到图片时需要转换
+                        boolean needConvertImage = !DataUtil.IS_USE_ALL_IMAGE || (action1 != null && action1.call(ICallBack.IS_RECORD, file.getAbsolutePath()));
+                        if(needConvertImage) {
+                            if (!Kfzssafe.isPng(file.getAbsolutePath())) {//非png图片才转换
+                                String toFilePath = String.format(Locale.CHINA, "%s%s_%d.png", file.getParent(), File.separator, System.currentTimeMillis());
+                                FileUtil.convertImage(file.getAbsolutePath(), toFilePath, Bitmap.CompressFormat.PNG);
+                                file = new File(toFilePath);
+                                convertFile = true;
+                            }
                         }
                     } catch (Exception e) {
                         e.printStackTrace();
@@ -94,7 +101,7 @@ public class UpFileUtils {
                 if(newFile == null || !newFile.exists()){
                     newFile = file;
                 } else {
-                    if(ListenerShotService.IS_RECORD_PATH) {
+                    if(convertFile) {//如果转换了图片,就需要删除掉转换的图片
                         if(file.delete()){
                             file = null;
                         }
@@ -102,7 +109,7 @@ public class UpFileUtils {
                 }
                 try {
                     if(action1 != null)
-                        action1.call(newFile.getAbsolutePath(), size, index);
+                        action1.call(ICallBack.DECODE_PNG, newFile.getAbsolutePath(), size, index);
                 } catch (Exception e) {
                     e.printStackTrace();
                 }

+ 27 - 13
app/src/main/java/com/sheep/gamegroup/view/activity/TaskDetailAct.java

@@ -59,6 +59,7 @@ import com.sheep.gamegroup.util.LogUtil;
 import com.sheep.gamegroup.util.MyListview;
 import com.sheep.gamegroup.util.PngUtil;
 import com.sheep.gamegroup.util.SelfCountDownTimer;
+import com.sheep.gamegroup.util.SysAppUtil;
 import com.sheep.gamegroup.util.TimeUtil;
 import com.sheep.gamegroup.util.UMConfigUtils;
 import com.sheep.gamegroup.util.ViewUtil;
@@ -938,7 +939,9 @@ public class TaskDetailAct extends AbsChooseImageActivity implements TaskDetailC
                 break;
         }
         if (commitScreenShotTaskId > 0) {
-            if ((DataUtil.IS_USE_SCREEN_SHOT || DataUtil.IS_LISTEN_SCREEN_SHOT) && taskEty.needShotScreen()) {//小绵羊截图方案与监听方案
+            if(DataUtil.IS_USE_ALL_IMAGE) {//可以上传任意图片
+                showChooseDialog(false, true, DEFAULT_MAX_COUNT);
+            } else if ((DataUtil.IS_USE_SCREEN_SHOT || DataUtil.IS_LISTEN_SCREEN_SHOT) && taskEty.needShotScreen()) {//小绵羊截图方案与监听方案
                 if(ListenerShotService.IS_RECORD_PATH){//使用记录的方式来获取用户的截图
                     List<ScreenShotRecord> list = DDProviderHelper.getInstance().getScreenShotRecordList(activity, taskEty.getPackage_names());
                     showChooseListDialog(false, true, DEFAULT_MAX_COUNT, ListUtil.asList(new ListUtil.CallBack<ScreenShotRecord, String>() {
@@ -1182,26 +1185,36 @@ public class TaskDetailAct extends AbsChooseImageActivity implements TaskDetailC
     protected void onGetImage(String path) {
 
     }
-    private ICallBack<String> callBack = new ICallBack<String>() {
+    private ICallBack<Boolean> callBack = new ICallBack<Boolean>() {
         @Override
-        public String call(Object... args) {
-            String pngFilePath = (String) args[0];
-            int size = (int) args[1];
-            int index = (int) args[2];
-            try {
-                //加密文本内容:包名;签名md5;试玩应用包名;试玩应用签名md5;用户token;任务id;图片总数;图片位置
-                return PngUtil.decodePng(pngFilePath, taskEty.getPackage_names(), String.format(Locale.CHINA, "%s;%d;%d;%d", SpUtils.getToken(SheepApp.getInstance()), commitScreenShotTaskId, size, index));
-            } catch (Exception e) {
-                e.printStackTrace();
+        public Boolean call(@CALL_BACK_TYPE int type, Object... args) {
+            String imagePath = (String) args[0];
+            switch (type){
+                case IS_RECORD:
+                    if(DDProviderHelper.getInstance().getScreenShotRecord(activity.getApplication(), taskEty.getPackage_names(), imagePath) != null){
+                        return true;
+                    }
+                    break;
+                case DECODE_PNG:
+                    int size = (int) args[1];
+                    int index = (int) args[2];
+                    try {
+                        //加密文本内容:包名;签名md5;试玩应用包名;试玩应用签名md5;用户token;任务id;图片总数;图片位置
+                        PngUtil.decodePng(imagePath, taskEty.getPackage_names(), String.format(Locale.CHINA, "%s;%d;%d;%d", SpUtils.getToken(SheepApp.getInstance()), commitScreenShotTaskId, size, index));
+                        return true;
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    break;
             }
-            return null;
+            return false;
         }
     };
     /**
      * 上传图片前的回调
      * @return
      */
-    protected ICallBack<String> getCallBack(){
+    protected ICallBack<Boolean> getCallBack(){
         if ((DataUtil.IS_USE_SCREEN_SHOT || DataUtil.IS_LISTEN_SCREEN_SHOT) && taskEty.needShotScreen()) {//小绵羊截图方案或者监听方案:上传截图成功后删除之前的截图
             return callBack;
         }
@@ -1218,6 +1231,7 @@ public class TaskDetailAct extends AbsChooseImageActivity implements TaskDetailC
         jsonObject.put("remark", /*taskEty.getRemarks() +*/ "");
         jsonObject.put("package_name", taskEty.getPackage_names() + "");
         jsonObject.put("status", 7 + "");
+        jsonObject.put("device", SysAppUtil.getUserAgentOrDeviceInfo());
         presenter.taskStatus(jsonObject);
         taskEty.setScreenshots(data);
     }

+ 36 - 60
app/src/main/java/com/sheep/gamegroup/view/adapter/TaskListItemAdp.java

@@ -14,10 +14,8 @@ import com.bumptech.glide.Glide;
 import com.bumptech.glide.request.RequestOptions;
 import com.kfzs.duanduan.utils.NumberFormatUtils;
 import com.sheep.gamegroup.model.entity.TaskAcceptedEty;
-import com.sheep.gamegroup.presenter.TaskListPresenter;
 import com.sheep.gamegroup.util.CommonUtil;
 import com.sheep.gamegroup.util.Jump2View;
-import com.sheep.gamegroup.util.TestUtil;
 import com.sheep.gamegroup.util.TimeUtil;
 import com.sheep.gamegroup.util.ViewUtil;
 import com.sheep.jiuyan.samllsheep.R;
@@ -26,7 +24,6 @@ import com.sheep.jiuyan.samllsheep.service.DownloadService;
 import java.util.List;
 import java.util.Locale;
 
-import javax.inject.Inject;
 
 /**
  * Created by ljy on 2018/3/21.
@@ -35,20 +32,12 @@ import javax.inject.Inject;
 public class TaskListItemAdp extends BaseAdapter {
     private Context context;
     private List<TaskAcceptedEty> etyList;
-    @Inject
-    TaskListPresenter presenter;
 
     public TaskListItemAdp(Context context, List<TaskAcceptedEty> etyList) {
         this.context = context;
         this.etyList = etyList;
     }
 
-    /**
-     * 传入presenter
-     */
-    public void addPresenter(TaskListPresenter presenter){
-        this.presenter = presenter;
-    }
     @Override
     public int getCount() {
         return etyList.size();
@@ -109,7 +98,7 @@ public class TaskListItemAdp extends BaseAdapter {
             }
         });
         DownloadService.setDownLoadLongClick(convertView, ety.getRelease_task().getTask());
-        returnValue3(ety, holder.detail_task_tv,holder.desc_tv);
+        setTaskStatusText(ety, holder.detail_task_tv,holder.desc_tv);
         Glide.with(context)
                 .load(ety.getRelease_task().getTask().getIcon())
                 .apply(new RequestOptions().placeholder(R.mipmap.icon))
@@ -122,73 +111,60 @@ public class TaskListItemAdp extends BaseAdapter {
         TextView name_tv, date_tv, price_tv,detail_task_tv,desc_tv;
     }
 
-    /**
-     * 1,已接受任务 2,正在进行中,3完成任务,4放弃任务,5任务失败,6审核失败,7提交审核8任务已下线9连续任务
-     * @return
-     */
-    private String returnValue(TaskAcceptedEty ety){
-        String stateStr = "已接受任务";
-        switch (ety.getStatus()){
-            case 1:
-                stateStr = "已接受任务";
-                break;
-            case 2:
-                stateStr = "正在进行中";
-                break;
-            case 3:
-                stateStr = "+"+ ety.getRelease_task().getBonusText() +"元";
-                break;
-            case 4:
-                stateStr = "放弃任务";
-                break;
-            case 5:
-                stateStr = "任务失败";
-                break;
-            case 6:
-                stateStr = "审核失败";
-                break;
-            case 7:
-                stateStr = "提交审核";
-                break;
-            case 8:
-                stateStr = "任务已下线";
-                break;
-        }
-        return stateStr;
-    }
-    private String returnValue3(TaskAcceptedEty ety, TextView textView, TextView desc_tv){
+    //设置任务完成状态与失败原因
+    private void setTaskStatusText(TaskAcceptedEty ety, TextView textView, TextView desc_tv){
         desc_tv.setVisibility(View.GONE);
-        String stateStr = "已接受任务";
         switch (ety.getStatus()){
             default:
-            case 1://提交中
-            case 2:
-            case 7:
+            case TaskAcceptedEty.STATUS_ACCEPTED_TASK://提交中
+            case TaskAcceptedEty.STATUS_RUNNING:
+            case TaskAcceptedEty.STATUS_SUBMIT:
                 textView.setBackgroundResource(R.drawable.shape_blue_stroke_rectangle_10_radius);
                 textView.setTextColor(context.getResources().getColor(R.color.btn_color_main_stroke));
                 textView.setText("审核中");
                 break;
-            case 3://完成
-            case 9:
+            case TaskAcceptedEty.STATUS_FINISHED://完成
+            case TaskAcceptedEty.STATUS_AT_LEAST_COMPLETE_ONE:
                 textView.setBackgroundResource(R.drawable.shape_gray_stroke_rectangle_10_radius);
                 textView.setTextColor(context.getResources().getColor(R.color.gray_CCCCCC));
                 textView.setText("已完成");
                 break;
-            case 4://失败
-            case 5:
-            case 8:
+            case TaskAcceptedEty.STATUS_GIVE_UP://失败
+            case TaskAcceptedEty.STATUS_TASK_FAIL:
+            case TaskAcceptedEty.STATUS_OFF_LINE:
+                textView.setBackgroundResource(R.drawable.shape_gray_stroke_rectangle_10_radius);
+                textView.setTextColor(context.getResources().getColor(R.color.gray_CCCCCC));
+                textView.setText("任务失败");
+                break;
+            case TaskAcceptedEty.STATUS_AUDIT_FAILURE:
+                textView.setBackgroundResource(R.drawable.shape_red_stroke_rectangle_10_radius);
+                textView.setTextColor(context.getResources().getColor(R.color.red_FD2D54));
+                textView.setText("重新提交");
+                if (!TextUtils.isEmpty(ety.getRemarks())) {
+                    desc_tv.setVisibility(View.VISIBLE);
+                    desc_tv.setText(context.getString(R.string.fail_reason, ety.getRemarks()));
+                }
+                break;
+        }
+        switch (ety.getAllowSubmit()){
+            case TaskAcceptedEty.ALLOW_SUBMIT_NO:
                 textView.setBackgroundResource(R.drawable.shape_gray_stroke_rectangle_10_radius);
                 textView.setTextColor(context.getResources().getColor(R.color.gray_CCCCCC));
                 textView.setText("任务失败");
+                if (!TextUtils.isEmpty(ety.getRemarks())) {
+                    desc_tv.setVisibility(View.VISIBLE);
+                    desc_tv.setText(context.getString(R.string.fail_reason, ety.getRemarks()));
+                }
                 break;
-            case 6:
+            case TaskAcceptedEty.ALLOW_SUBMIT_YES:
                 textView.setBackgroundResource(R.drawable.shape_red_stroke_rectangle_10_radius);
                 textView.setTextColor(context.getResources().getColor(R.color.red_FD2D54));
                 textView.setText("重新提交");
-                desc_tv.setVisibility(View.VISIBLE);
-                desc_tv.setText(TextUtils.isEmpty(ety.getRemarks())?"":"失败原因:"+ety.getRemarks());
+                if (!TextUtils.isEmpty(ety.getRemarks())) {
+                    desc_tv.setVisibility(View.VISIBLE);
+                    desc_tv.setText(context.getString(R.string.fail_reason, ety.getRemarks()));
+                }
                 break;
         }
-        return stateStr;
     }
 }

+ 1 - 8
app/src/main/java/com/sheep/jiuyan/samllsheep/SheepApp.java

@@ -37,7 +37,6 @@ import com.sheep.gamegroup.view.activity.LoginAct;
 import com.sheep.jiuyan.samllsheep.service.AutoCheckService;
 import com.sheep.jiuyan.samllsheep.service.DownloadService;
 import com.sheep.jiuyan.samllsheep.service.FloatShotScreenService;
-import com.sheep.jiuyan.samllsheep.service.ListenerShotService;
 import com.sheep.jiuyan.samllsheep.utils.G;
 import com.sheep.jiuyan.samllsheep.utils.SpUtils;
 import com.tencent.bugly.Bugly;
@@ -52,8 +51,6 @@ import org.xutils.x;
 import cn.jpush.android.api.JPushInterface;
 import rx.functions.Action1;
 
-import static com.sheep.jiuyan.samllsheep.service.ListenerShotService.IS_RECORD_PATH;
-
 /**
  * Created by kemllor on 2017/12/21.
  */
@@ -367,11 +364,7 @@ public class SheepApp extends MultiDexApplication {
                     LogUtil.println("SheepApp onActivityStarted", activity.getClass().getSimpleName(), mActivityCount);
                     UMConfigUtils.Event.SHEEP_STARTED.onEvent();
                     startService(new Intent(activity, DownloadService.class));
-                    if (DataUtil.IS_LISTEN_SCREEN_SHOT && (!IS_RECORD_PATH || !TextUtils.isEmpty(DataUtil.getInstance().getUserId()))) {
-                        Intent intent = new Intent(activity, ListenerShotService.class);
-                        intent.putExtra(AutoCheckService.EXTRA_KEY_USER_ID, DataUtil.getInstance().getUserId());//记录用户截图方案需要记录当前用户id
-                        startService(intent);
-                    }
+                    Jump2View.getInstance().startListenerShotService(activity);
                     Jump2View.getInstance().startShotScreenFloat(activity, false);
                 }
             }

+ 250 - 0
app/src/main/java/com/sheep/jiuyan/samllsheep/service/ListenerShotNewService.java

@@ -0,0 +1,250 @@
+package com.sheep.jiuyan.samllsheep.service;
+
+import android.annotation.SuppressLint;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.os.Build;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.widget.RemoteViews;
+
+import com.sheep.gamegroup.greendao.DDProviderHelper;
+import com.sheep.gamegroup.greendao.download.ScreenShotRecord;
+import com.sheep.gamegroup.util.ListUtil;
+import com.sheep.gamegroup.util.LogUtil;
+import com.sheep.gamegroup.util.RunningTaskUtil;
+import com.sheep.gamegroup.util.ScreenShotListenManager;
+import com.sheep.gamegroup.view.activity.SplashAct;
+import com.sheep.jiuyan.samllsheep.R;
+import com.sheep.jiuyan.samllsheep.utils.FileUtil;
+
+import java.io.File;
+import java.util.List;
+import java.util.Locale;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+import go.kfzssafe.Kfzssafe;
+import rx.Observable;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+import rx.schedulers.Schedulers;
+
+import static com.sheep.jiuyan.samllsheep.service.AutoCheckService.EXTRA_KEY_USER_ID;
+
+/**
+ * Created by realicing on 2018/9/20.
+ * realicing@sina.com
+ * 监听截图---8.0启用
+ */
+public class ListenerShotNewService extends Service {
+
+    private RunningTaskUtil runningTaskUtil;
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    //登录的用户id
+    private String userId;
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (intent != null) {
+            userId = intent.getStringExtra(EXTRA_KEY_USER_ID);
+        }
+        if(runningTaskUtil == null) {
+            //初始化获取当前应用的工具类
+            runningTaskUtil = new RunningTaskUtil(getApplicationContext());
+        }
+        if(manager == null) {
+            //开启监听
+            manager = ScreenShotListenManager.newInstance(getApplicationContext());
+            manager.setListener(
+                    new ScreenShotListenManager.OnScreenShotListener() {
+                        public void onShot(String imagePath) {
+                            addPng(imagePath);
+                        }
+                    }
+            );
+            manager.startListen();
+        }
+
+        Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext());
+
+        String CHANNEL_ONE_ID = getPackageName()+".ListenerShotService";
+        String CHANNEL_ONE_NAME = "smallSheep";
+        NotificationChannel notificationChannel;
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+            notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
+                    CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH);
+            notificationChannel.enableLights(true);
+            notificationChannel.setLightColor(Color.RED);
+            notificationChannel.setShowBadge(true);
+            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
+            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+            if(manager != null)
+                manager.createNotificationChannel(notificationChannel);
+            notificationBuilder.setChannelId(CHANNEL_ONE_ID);
+        }
+        //点击通知栏跳转到相应的应用里面
+        Intent notificationIntent = new Intent(this, SplashAct.class);
+        notificationIntent.setAction(Intent.ACTION_MAIN);
+        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
+                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        Notification notification = notificationBuilder.setSmallIcon(R.mipmap.remenyx)
+                .setWhen(System.currentTimeMillis())
+                .setTicker("小绵羊")
+                .setContentTitle("小绵羊正在运行")
+                .setContentText("点击回到小绵羊")
+                .setOngoing(true)
+                .setPriority(Notification.PRIORITY_MAX)
+                .setContentIntent(pendingIntent)
+                .setAutoCancel(false)
+                .build();
+        notification.flags |= Notification.FLAG_NO_CLEAR;
+        //这里的id不能是0
+        startForeground(113922, notification);
+        return super.onStartCommand(intent, flags, startId);
+    }
+    private ScreenShotListenManager manager;
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (manager != null)
+            manager.stopListen();
+    }
+
+
+    /**
+     * 获取前台运行的程序的包名
+     *
+     * @return
+     */
+    @SuppressLint("NewApi")
+    public String getPackageNameInForeground1(Context context) {
+        String topPackageName = runningTaskUtil.getTopRunningTasks();
+        if (TextUtils.isEmpty(topPackageName)) {
+            return getProcessPackageNameInForeground(context);
+        }
+        return topPackageName;
+    }
+
+    /**
+     * 获取前台运行的程序的包名
+     *
+     * @return
+     */
+    @SuppressLint("NewApi")
+    public static String getPackageNameInForeground(Context context) {
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
+            UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);//usagestats
+            long time = System.currentTimeMillis();
+            if (mUsageStatsManager != null) {
+                List<UsageStats> usageStatsList = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, time - 5000L, time);
+
+                if (!ListUtil.isEmpty(usageStatsList)) {
+                    TreeMap<Long, UsageStats> mySortedMap = new TreeMap<>();
+                    for (UsageStats item : usageStatsList) {
+                        mySortedMap.put(item.getLastTimeUsed(), item);
+                    }
+
+                    UsageStats usageStats = mySortedMap.get(mySortedMap.lastKey());
+
+                    return usageStats.getPackageName();
+                }
+            }
+        }
+        return getProcessPackageNameInForeground(context);
+    }
+
+    public static String getProcessPackageNameInForeground(Context context) {
+        android.app.ActivityManager manager = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        List<android.app.ActivityManager.RunningAppProcessInfo> processList = manager == null ? null : manager.getRunningAppProcesses();
+        if (!ListUtil.isEmpty(processList)) {
+            for (android.app.ActivityManager.RunningAppProcessInfo item : processList) {
+                if (item != null && item.importance == android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
+                    return item.processName;
+                }
+            }
+        }
+        return null;
+    }
+
+    public void addPng(final String imagePath) {
+        final String packageName = getPackageNameInForeground1(getApplicationContext());
+        if (TextUtils.isEmpty(packageName)) {
+            LogUtil.println("ScreenShotListenManager", "无法获取到当前运行的应用的包名");
+            return;
+        }
+        LogUtil.println("ScreenShotListenManager", packageName);
+        if (IS_RECORD_PATH) {//使用记录的方式来获取用户的截图
+            ScreenShotRecord screenShotRecord = new ScreenShotRecord();
+            screenShotRecord.setCreateTime(System.currentTimeMillis());
+            screenShotRecord.setPackageName(packageName);
+            screenShotRecord.setPath(imagePath);
+            screenShotRecord.setUserId(userId);
+            DDProviderHelper.getInstance().addScreenShotRecord(getApplicationContext(), screenShotRecord);
+        } else {
+            delayCopyImage(imagePath, packageName);
+        }
+    }
+    public static final boolean IS_RECORD_PATH = true;//是否直接记录截图文件路径,而不是复制截图到私有目录
+    private void delayCopyImage(final String imagePath, final String packageName) {
+        Observable.just(1).delay(1, TimeUnit.SECONDS)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Action1<Integer>() {
+                    @Override
+                    public void call(Integer integer) {
+                        try {
+                            File toDir = getScreenShotsDir(getApplicationContext(), packageName);
+                            if (Kfzssafe.isPng(imagePath)) {
+                                FileUtil.copyFileToDir(new File(imagePath), toDir);
+                            } else {
+                                String toFilePath = String.format(Locale.CHINA, "%s%s%s_%d.png", toDir.getAbsolutePath(), File.separator, packageName, System.currentTimeMillis());
+                                FileUtil.convertImage(imagePath, toFilePath, Bitmap.CompressFormat.PNG);
+                            }
+                        } catch (Exception e) {
+                            LogUtil.println("ScreenShotListenManager", "复制截屏图片失败", e.getMessage());
+                        }
+                    }
+                });
+    }
+
+    /**
+     * 截图目录
+     *
+     * @return
+     */
+    public static File getScreenShotsDir(Context context) {
+        return context.getDir("ScreenShots", Context.MODE_PRIVATE);
+    }
+
+    /**
+     * 指定程序的截图目录
+     *
+     * @return
+     */
+    public static File getScreenShotsDir(Context context, String packageName) {
+        File dir = new File(getScreenShotsDir(context), packageName);
+        if (!dir.exists())
+            dir.mkdirs();
+        return dir;
+    }
+
+}

+ 38 - 36
app/src/main/java/com/sheep/jiuyan/samllsheep/service/ListenerShotService.java

@@ -13,7 +13,6 @@ import android.os.Build;
 import android.os.IBinder;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
-import android.widget.RemoteViews;
 
 import com.sheep.gamegroup.greendao.DDProviderHelper;
 import com.sheep.gamegroup.greendao.download.ScreenShotRecord;
@@ -48,41 +47,6 @@ public class ListenerShotService extends Service {
 
     private RunningTaskUtil runningTaskUtil;
 
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        //初始化获取当前应用的工具类
-        runningTaskUtil = new RunningTaskUtil(getApplicationContext());
-        //开启监听
-        manager = ScreenShotListenManager.newInstance(getApplicationContext());
-        manager.setListener(
-                new ScreenShotListenManager.OnScreenShotListener() {
-                    public void onShot(String imagePath) {
-                        addPng(imagePath);
-                    }
-                }
-        );
-        manager.startListen();
-        //发送一个通知栏,保证存活
-        Notification notification = new Notification();
-        //通知栏没有展开时的显示内容
-        notification.icon = R.mipmap.remenyx;
-        notification.tickerText = "回到小绵羊";
-
-        //下拉通知栏的显示内容
-        notification.contentView = new RemoteViews(getPackageName(), R.layout.notification_sheep_shot_screen);
-
-        //点击通知栏跳转到相应的应用里面
-        Intent notificationIntent = new Intent(this, SplashAct.class);
-        notificationIntent.setAction(Intent.ACTION_MAIN);
-        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-        //这一句加不加没什么影响
-// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        notification.contentIntent = PendingIntent.getActivity(this, 1, notificationIntent, 0);
-
-        //这里的id不能是0
-        startForeground(113922, notification);
-    }
     @Nullable
     @Override
     public IBinder onBind(Intent intent) {
@@ -96,6 +60,44 @@ public class ListenerShotService extends Service {
         if (intent != null) {
             userId = intent.getStringExtra(EXTRA_KEY_USER_ID);
         }
+        if(runningTaskUtil == null) {
+            //初始化获取当前应用的工具类
+            runningTaskUtil = new RunningTaskUtil(getApplicationContext());
+        }
+        if(manager == null) {
+            //开启监听
+            manager = ScreenShotListenManager.newInstance(getApplicationContext());
+            manager.setListener(
+                    new ScreenShotListenManager.OnScreenShotListener() {
+                        public void onShot(String imagePath) {
+                            addPng(imagePath);
+                        }
+                    }
+            );
+            manager.startListen();
+        }
+
+        Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext());
+        //点击通知栏跳转到相应的应用里面
+        Intent notificationIntent = new Intent(this, SplashAct.class);
+        notificationIntent.setAction(Intent.ACTION_MAIN);
+        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
+                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        Notification notification = notificationBuilder.setSmallIcon(R.mipmap.remenyx)
+                .setWhen(System.currentTimeMillis())
+                .setTicker("小绵羊")
+                .setContentTitle("小绵羊正在运行")
+                .setContentText("点击回到小绵羊")
+                .setOngoing(true)
+                .setPriority(Notification.PRIORITY_MAX)
+                .setContentIntent(pendingIntent)
+                .setAutoCancel(false)
+                .build();
+        notification.flags |= Notification.FLAG_NO_CLEAR;
+        //这里的id不能是0
+        startForeground(113922, notification);
         return super.onStartCommand(intent, flags, startId);
     }
     private ScreenShotListenManager manager;

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -91,4 +91,5 @@
 
     <string name="login_success">登录成功</string>
     <string name="commit_time_point">提交时间:</string>
+    <string name="fail_reason">失败原因:%s</string>
 </resources>