Explorar o código

添加辅助功能并合并

zengjiebin %!s(int64=8) %!d(string=hai) anos
pai
achega
026ff4068f

+ 19 - 0
app/src/main/AndroidManifest.xml

@@ -67,6 +67,7 @@
         android:name=".SheepApp"
         android:allowBackup="true"
         android:icon="@mipmap/icon"
+        android:persistent="true"
         android:label="@string/app_name"
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
@@ -80,7 +81,25 @@
             android:screenOrientation="portrait"/>
 
         <service android:name=".service.DownloadService"/>
+        <service
+            android:name=".service.FloatService"
+            android:enabled="true"
+            android:exported="true">
+        </service>
+        <service
+            android:name=".service.MonitorAppService"
+            android:enabled="true"
+            android:exported="true"
+            android:label="@string/app_name"
+            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+            </intent-filter>
 
+            <meta-data
+                android:name="android.accessibilityservice"
+                android:resource="@xml/accessibility" />
+        </service>
         <provider
             android:name=".provider.SheepFileProvider"
             android:authorities="${applicationId}.fileprovider"

+ 0 - 1
app/src/main/java/com/kfzs/duanduan/BaseCompatActivity.java

@@ -74,7 +74,6 @@ public abstract class BaseCompatActivity extends CompatActivity {
         return (T) super.findViewById(id);
     }
 
-
     @Override
     protected void onDestroy() {
         super.onDestroy();

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

@@ -282,7 +282,7 @@ public interface ApiService {
     @GET("app/bulletin")
     Observable<BaseMessage> bulletin(@Query("page") int page, @Query("per_page") int per_page);
     /**
-     *
+     * 获取微信辅助h5链接
      */
     @GET("qr/task/get_url")
     Observable<BaseMessage> wxfzGetUrl();

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

@@ -1,11 +1,16 @@
 package com.sheep.gamegroup.util;
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.text.TextUtils;
+import android.view.WindowManager;
 
 import com.alibaba.fastjson.JSON;
 import com.kfzs.duanduan.ActMain;
@@ -63,6 +68,8 @@ import com.sheep.gamegroup.view.activity.WithdrawalResultAct;
 import com.sheep.jiuyan.samllsheep.BuildConfig;
 import com.sheep.jiuyan.samllsheep.R;
 import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.service.FloatService;
+import com.sheep.jiuyan.samllsheep.service.MonitorAppService;
 import com.sheep.jiuyan.samllsheep.utils.G;
 import com.sheep.jiuyan.samllsheep.utils.SpUtils;
 
@@ -723,4 +730,47 @@ public class Jump2View {
         Intent intent = new Intent(context, ActMainGame.class);
         context.startActivity(intent);
     }
+
+
+    /**
+     * 启动小绵羊悬浮窗
+     * @param context
+     */
+    public void startFloat(Context context, boolean isShow) {
+        Intent intent = new Intent(context, FloatService.class);
+        intent.putExtra("isShow", isShow);
+        context.startService(intent);
+    }
+    private AlertDialog tipToOpernAccessibilityDialog;
+    public void clearAlertDialog(){
+        tipToOpernAccessibilityDialog = null;
+    }
+    /**
+     * 启动小绵羊辅助
+     * @param context
+     */
+    public void startAccessibility(final Context context) {
+        if(MonitorAppService.isAccessibilitySettingsOn(SheepApp.getInstance()))
+            return;
+        if(tipToOpernAccessibilityDialog != null){
+            return;
+        }
+        AlertDialog.Builder  builder = new AlertDialog.Builder(context)
+                .setTitle("温馨提示!")
+                .setMessage("亲!要赚钱需要手动开启小绵羊辅助功能哟!")
+                .setPositiveButton("去开启", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
+                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        context.startActivity(intent);
+                    }
+                });
+        builder.setCancelable(false);
+        tipToOpernAccessibilityDialog = builder.create();
+        if(tipToOpernAccessibilityDialog.getWindow() != null) {
+            tipToOpernAccessibilityDialog.getWindow().setType(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? WindowManager.LayoutParams.TYPE_PHONE : WindowManager.LayoutParams.TYPE_TOAST);
+            tipToOpernAccessibilityDialog.show();
+        }
+    }
 }

+ 7 - 2
app/src/main/java/com/sheep/gamegroup/util/ListUtil.java

@@ -9,14 +9,19 @@ import java.util.List;
  * realicing@sina.com
  */
 public class ListUtil {
-    public static <T> boolean hasIndex(List<T> list, int i) {
-        return !ListUtil.isEmpty(list) && list.size() > i;
+    public static <T> boolean hasIndex(List<T> list, int index) {
+        return !ListUtil.isEmpty(list) && list.size() > index;
     }
 
     private static <T> boolean isEmpty(List<T> list) {
         return list == null || list.isEmpty();
     }
 
+    public static <T> T getIndex(List<T> list, int index) {
+        return hasIndex(list, index) ? list.get(index) : null;
+    }
+
+
     public static int getTotalPage(int count, int per_page) {
         return (count - 1) / per_page + 1;
     }

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

@@ -11,10 +11,10 @@ import com.sheep.gamegroup.di.components.DaggerNetComponent;
 import com.sheep.gamegroup.di.components.NetComponent;
 import com.sheep.gamegroup.di.modules.NetModule;
 import com.sheep.gamegroup.util.ConnectAddress;
+import com.sheep.gamegroup.util.Jump2View;
 import com.sheep.gamegroup.util.UMConfigUtils;
 import com.sheep.jiuyan.samllsheep.utils.G;
 import com.tencent.bugly.Bugly;
-import com.tencent.mm.opensdk.openapi.IWXAPI;
 
 /**
  * Created by kemllor on 2017/12/21.
@@ -98,6 +98,9 @@ public class SheepApp extends BaseApplication {
         @Override
         public void onActivityResumed(Activity activity) {
             UMConfigUtils.onPageStart(activity);
+            if (mActivityAount > 0) {
+                Jump2View.getInstance().startFloat(activity, false);
+            }
         }
 
         @Override
@@ -108,6 +111,9 @@ public class SheepApp extends BaseApplication {
         @Override
         public void onActivityStopped(Activity activity) {
             mActivityAount--;
+            if (mActivityAount <= 0) {
+                Jump2View.getInstance().startFloat(activity, true);
+            }
         }
 
         @Override

+ 1 - 0
app/src/main/java/com/sheep/jiuyan/samllsheep/base/BaseFragment.java

@@ -113,6 +113,7 @@ public abstract class BaseFragment extends Fragment {
         onViewCreated();
     }
 
+
     /**
      * 万能的找View类
      *

+ 241 - 0
app/src/main/java/com/sheep/jiuyan/samllsheep/service/FloatService.java

@@ -0,0 +1,241 @@
+package com.sheep.jiuyan.samllsheep.service;
+
+import android.app.AlertDialog;
+import android.app.Service;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.os.Build;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.sheep.gamegroup.util.Jump2View;
+import com.sheep.jiuyan.samllsheep.R;
+import com.sheep.jiuyan.samllsheep.utils.DeviceInfo;
+import com.sheep.jiuyan.samllsheep.utils.OpenService;
+
+
+import java.util.concurrent.TimeUnit;
+
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+import rx.schedulers.Schedulers;
+
+/**
+ * Created by realicing on 2018/5/8.
+ * realicing@sina.com
+ */
+public class FloatService extends Service implements View.OnClickListener {
+
+    private static final String TAG = "MainService";
+
+    LinearLayout mFloatwindow;
+    WindowManager.LayoutParams params;
+    WindowManager mWm;
+
+    ImageView floaticon;
+
+    //状态栏高度.
+    int statusBarHeight = -1;
+    private Point mSize;
+    private View mLeft;
+    private View mRight;
+
+    //不与Activity进行绑定.
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "MainService Created");
+        mSize = DeviceInfo.getDeviceSize(this);
+        createToucher();
+        startTimer();
+    }
+
+    private void stopTimer() {
+        if(subscription != null){
+            subscription.unsubscribe();
+        }
+        subscription = null;
+    }
+
+    private Subscription subscription;
+    private void startTimer() {
+        if(subscription == null)
+            subscription = Observable.interval(1000, TimeUnit.MILLISECONDS)
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe(new Action1<Long>() {
+                        @Override
+                        public void call(Long aLong) {
+                            Jump2View.getInstance().startAccessibility(getApplication());
+                        }
+                    });
+    }
+
+
+    private void createToucher() {
+        //赋值WindowManager&LayoutParam.
+        params = new WindowManager.LayoutParams();
+        if(mWm==null) {
+            mWm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+        }
+        //设置type.系统提示型窗口,一般都在应用程序窗口之上.
+        //设置效果为背景透明.
+        params.format = PixelFormat.RGBA_8888;
+        //设置flags.不可聚焦及不可使用按钮对悬浮窗进行操控.
+        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+//
+//        //设置窗口初始停靠位置.
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            //  大于等于 24 即为 7.0 及以上执行内容
+            Log.e("qx", "7.0");
+            params.type = WindowManager.LayoutParams.TYPE_PHONE; // 7.1
+        } else {
+            //  低于 24 即为 7.0 以下执行内容
+            params.type = WindowManager.LayoutParams.TYPE_TOAST;   // 4.4
+            Log.e("qx", "4.4");
+
+        }
+
+        params.gravity = Gravity.LEFT | Gravity.TOP;
+        params.x = 0;
+        params.y = DeviceInfo.dip2px(getApplicationContext(), 25);
+
+        //设置悬浮窗口长宽数据.
+        params.width = -2;
+        params.height = DeviceInfo.dip2px(getApplicationContext(), 40f);
+
+        LayoutInflater inflater = LayoutInflater.from(getApplication());
+        //获取浮动窗口视图所在布局.
+        mFloatwindow = (LinearLayout) inflater.inflate(R.layout.float_window, null);
+        //添加toucherlayout
+        Log.i(TAG, "toucherlayout-->left:" + mFloatwindow.getLeft());
+        Log.i(TAG, "toucherlayout-->right:" + mFloatwindow.getRight());
+        Log.i(TAG, "toucherlayout-->top:" + mFloatwindow.getTop());
+        Log.i(TAG, "toucherlayout-->bottom:" + mFloatwindow.getBottom());
+
+        //主动计算出当前View的宽高信息.
+        mFloatwindow.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+
+        //用于检测状态栏高度.
+        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
+        if (resourceId > 0) {
+            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
+        }
+        Log.i(TAG, "状态栏高度为:" + statusBarHeight);
+
+        //浮动窗口按钮.
+        floaticon = (ImageView) mFloatwindow.findViewById(R.id.floate_icon);
+        mLeft = mFloatwindow.findViewById(R.id.ll_info_left);
+        mRight = mFloatwindow.findViewById(R.id.ll_info_right);
+        ImageView imgCommitRight = (ImageView) mFloatwindow.findViewById(R.id.img_commit_right);
+        ImageView imgCommitLeft = (ImageView) mFloatwindow.findViewById(R.id.img_commit_left);
+        ImageView imgOpenRight = (ImageView) mFloatwindow.findViewById(R.id.img_open_right);
+        ImageView imgOpenLeft = (ImageView) mFloatwindow.findViewById(R.id.img_open_left);
+
+        imgCommitRight.setOnClickListener(this);
+        imgCommitLeft.setOnClickListener(this);
+        imgOpenRight.setOnClickListener(this);
+        imgOpenLeft.setOnClickListener(this);
+        floaticon.setOnClickListener(this);
+
+        floaticon.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                params.x = (int) event.getRawX() - 20;
+                params.y = (int) event.getRawY() - 20 - statusBarHeight;
+                mWm.updateViewLayout(mFloatwindow, params);
+                switch (event.getAction()) {
+                    case MotionEvent.ACTION_UP:
+                    case MotionEvent.ACTION_CANCEL:
+                        int x = (int) event.getRawX();
+                        if (x > mSize.x / 2) {
+                            params.x = mSize.x;
+                        } else {
+                            params.x = 0;
+                        }
+                        mWm.updateViewLayout(mFloatwindow, params);
+                        break;
+                }
+                return false;
+            }
+        });
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        try {
+            if (intent != null && intent.getBooleanExtra("isShow", true)) {
+                if (mFloatwindow != null) {
+                    mWm.addView(mFloatwindow, params);
+                }
+            } else {
+                if (mFloatwindow != null)
+                    mWm.removeViewImmediate(mFloatwindow);
+
+            }
+        } catch (Exception ignore) {
+        }
+        return super.onStartCommand(intent, flags, START_STICKY);
+    }
+    @Override
+    public void onDestroy() {
+        if (floaticon != null) {
+            mWm.removeView(mFloatwindow);
+        }
+        stopTimer();
+        super.onDestroy();
+    }
+
+
+
+    /**
+     * 前往开启辅助服务界面
+     */
+    private void goAccess() {
+        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        startActivity(intent);
+
+        Intent intent2 = new Intent(this, MonitorAppService.class);
+        startService(intent2);
+
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (!new OpenService().isAccessibilitySettingsOn(this)) {
+            AlertDialog.Builder  builder=    new AlertDialog.Builder(this)
+                    .setTitle("温馨提示!")
+                    .setMessage("亲!要赚钱需要手动开启小绵羊辅助功能哟!")
+                    .setPositiveButton("去开启", new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            goAccess();
+                        }
+                    });
+            builder.setCancelable(false);
+            builder.show();
+            return ;
+        }
+    }
+
+}

+ 88 - 0
app/src/main/java/com/sheep/jiuyan/samllsheep/service/MonitorAppService.java

@@ -0,0 +1,88 @@
+package com.sheep.jiuyan.samllsheep.service;
+
+import android.accessibilityservice.AccessibilityService;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.sheep.gamegroup.util.Jump2View;
+import com.sheep.gamegroup.util.ListUtil;
+
+import java.util.List;
+
+/**
+ * Created by realicing on 2018/5/4.
+ * realicing@sina.com
+ */
+public class MonitorAppService extends AccessibilityService {
+    @Override
+    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
+        // 此方法是在主线程中回调过来的,所以消息是阻塞执行的
+        // 获取包名
+        CharSequence packageName = accessibilityEvent.getPackageName();
+        CharSequence className = accessibilityEvent.getClassName();
+        int eventType = accessibilityEvent.getEventType();
+        List<CharSequence> textList = accessibilityEvent.getText();
+        switch (eventType) {
+            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+                System.out.println("MonitorAppService TYPE_WINDOW_STATE_CHANGED: " + " pkgName: " + packageName + " className: " + className + " source: " + ListUtil.getIndex(textList, 0));
+                break;
+//            case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
+//                System.out.println("MonitorAppService TYPE_WINDOW_CONTENT_CHANGED: " + " packageName: " + packageName + " source: " + ListUtil.getIndex(textList, 0));
+//                break;
+            case AccessibilityEvent.TYPE_VIEW_CLICKED:
+                System.out.println("MonitorAppService TYPE_VIEW_CLICKED: " + " pkgName: " + packageName + " className: " + className  + " source: " + ListUtil.getIndex(textList, 0));
+                break;
+        }
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Jump2View.getInstance().clearAlertDialog();
+        return super.onStartCommand(intent, flags, START_STICKY);
+    }
+
+    @Override
+    public void onInterrupt() {
+        Jump2View.getInstance().startAccessibility(getApplicationContext());
+        System.out.println("MonitorAppService onInterrupt");
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        Jump2View.getInstance().startAccessibility(getApplicationContext());
+        System.out.println("MonitorAppService onUnbind");
+        return super.onUnbind(intent);
+    }
+
+    public static boolean isAccessibilitySettingsOn(Context mContext) {
+        int accessibilityEnabled = 0;
+        final String service = mContext.getPackageName() + "/" + MonitorAppService.class.getCanonicalName();
+        // com.z.buildingaccessibilityservices/android.accessibilityservice.AccessibilityService
+        try {
+            accessibilityEnabled = Settings.Secure.getInt(mContext.getApplicationContext().getContentResolver(),
+                    android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
+        } catch (Settings.SettingNotFoundException e) {
+        }
+        TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
+
+        if (accessibilityEnabled == 1) {
+            String settingValue = Settings.Secure.getString(mContext.getApplicationContext().getContentResolver(),
+                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+            // com.z.buildingaccessibilityservices/com.z.buildingaccessibilityservices.TestService
+            if (settingValue != null) {
+                mStringColonSplitter.setString(settingValue);
+                while (mStringColonSplitter.hasNext()) {
+                    String accessibilityService = mStringColonSplitter.next();
+
+                    if (accessibilityService.equalsIgnoreCase(service)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+}

+ 70 - 0
app/src/main/res/layout/float_window.xml

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:id="@+id/ll_info_left"
+        android:layout_width="110dp"
+        android:layout_height="40dp"
+        android:layout_gravity="center_vertical"
+        android:background="@drawable/x_shap_shadow_bg_rectgangle_white"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:visibility="gone">
+
+        <ImageView
+            android:id="@+id/img_commit_left"
+            android:layout_width="40dp"
+            android:padding="5dp"
+            android:layout_height="40dp"
+            android:layout_marginLeft="10dp"
+            android:src="@drawable/tab_task_click"/>
+
+        <ImageView
+            android:id="@+id/img_open_left"
+            android:padding="5dp"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:src="@drawable/index_more"/>
+    </LinearLayout>
+
+    <ImageView
+        android:id="@+id/floate_icon"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/icon"/>
+
+    <LinearLayout
+        android:id="@+id/ll_info_right"
+        android:layout_width="110dp"
+        android:layout_height="40dp"
+        android:layout_gravity="center_vertical"
+        android:background="@drawable/x_shap_shadow_bg_rectgangle_white"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:visibility="gone">
+
+        <ImageView
+            android:id="@+id/img_commit_right"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:padding="5dp"
+            android:layout_marginLeft="10dp"
+            android:src="@drawable/tab_task_click"/>
+
+        <ImageView
+            android:padding="5dp"
+            android:id="@+id/img_open_right"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:src="@drawable/index_more"/>
+    </LinearLayout>
+
+</LinearLayout>

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

@@ -14,6 +14,7 @@
     <string name="coming_soon">敬请期待</string>
     <string name="last_page">&#060;</string>
     <string name="next_page">&#062;</string>
+
     <string name="total_money">绵羊币总资产:%s元</string>
     <string name="task_reward">任务奖励:%s元</string>
     <string name="agent_extract">代理提成:%s元</string>
@@ -27,4 +28,5 @@
     <string name="feedback_notice_input_email_address">请输入您的邮箱地址</string>
     <string name="contact_qq_email">联系QQ/邮箱</string>
     <string name="input_notice_feedback">请留下您的联系方式,我们会不定期地给予优质建议提供丰厚奖励哦!</string>
+    <string name="accessibility_desc">小绵羊任务</string>
 </resources>

+ 8 - 0
app/src/main/res/xml/accessibility.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:accessibilityEventTypes="typeAllMask"
+    android:accessibilityFeedbackType="feedbackAllMask"
+    android:accessibilityFlags="flagDefault"
+    android:canRetrieveWindowContent="true"
+    android:description="@string/accessibility_desc"
+    android:notificationTimeout="1" />