Procházet zdrojové kódy

小绵阳移动端-项目创建

zhaoyi před 8 roky
revize
875f9c922f
52 změnil soubory, kde provedl 2121 přidání a 0 odebrání
  1. 9 0
      .gitignore
  2. 1 0
      app/.gitignore
  3. 44 0
      app/build.gradle
  4. 31 0
      app/proguard-rules.pro
  5. 56 0
      app/src/main/AndroidManifest.xml
  6. 13 0
      app/src/main/java/com/jiuyan/sheep_children/Config.java
  7. 147 0
      app/src/main/java/com/jiuyan/sheep_children/floatwindow/FloatService.java
  8. 33 0
      app/src/main/java/com/jiuyan/sheep_children/floatwindow/FloatWindow.java
  9. 217 0
      app/src/main/java/com/jiuyan/sheep_children/floatwindow/ShotScreen.java
  10. 92 0
      app/src/main/java/com/jiuyan/sheep_children/net/NetManager.java
  11. 11 0
      app/src/main/java/com/jiuyan/sheep_children/net/Url.java
  12. 223 0
      app/src/main/java/com/jiuyan/sheep_children/page/DownloadActivity.java
  13. 130 0
      app/src/main/java/com/jiuyan/sheep_children/page/MainActivity.java
  14. 111 0
      app/src/main/java/com/jiuyan/sheep_children/page/ShotScreenActivity.java
  15. 29 0
      app/src/main/java/com/jiuyan/sheep_children/page/UserCenterActivity.java
  16. 20 0
      app/src/main/java/com/jiuyan/sheep_children/page/WithdrawActivity.java
  17. 79 0
      app/src/main/java/com/jiuyan/sheep_children/page/adapter/TaskAdapter.java
  18. 19 0
      app/src/main/java/com/jiuyan/sheep_children/utils/DeviceInfo.java
  19. 44 0
      app/src/main/java/com/jiuyan/sheep_children/utils/PackageUtil.java
  20. binární
      app/src/main/res/drawable-hdpi/back.png
  21. binární
      app/src/main/res/drawable-hdpi/icon.png
  22. binární
      app/src/main/res/drawable-hdpi/sheep.png
  23. 56 0
      app/src/main/res/layout/download_activity.xml
  24. 40 0
      app/src/main/res/layout/float_window.xml
  25. 13 0
      app/src/main/res/layout/line_h_1px.xml
  26. 14 0
      app/src/main/res/layout/main_activity.xml
  27. 74 0
      app/src/main/res/layout/task_head.xml
  28. 79 0
      app/src/main/res/layout/task_item.xml
  29. 25 0
      app/src/main/res/layout/title.xml
  30. 111 0
      app/src/main/res/layout/usercenter_activity.xml
  31. 42 0
      app/src/main/res/layout/withdraw_activity.xml
  32. binární
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  33. binární
      app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  34. binární
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  35. binární
      app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  36. binární
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  37. binární
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  38. binární
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  39. binární
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  40. binární
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  41. binární
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  42. 12 0
      app/src/main/res/values/colors.xml
  43. 8 0
      app/src/main/res/values/strings.xml
  44. 35 0
      app/src/main/res/values/styles.xml
  45. 6 0
      app/src/main/res/xml/file_paths.xml
  46. 23 0
      build.gradle
  47. 17 0
      gradle.properties
  48. binární
      gradle/wrapper/gradle-wrapper.jar
  49. 6 0
      gradle/wrapper/gradle-wrapper.properties
  50. 160 0
      gradlew
  51. 90 0
      gradlew.bat
  52. 1 0
      settings.gradle

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
+/build

+ 44 - 0
app/build.gradle

@@ -0,0 +1,44 @@
+apply plugin: 'com.android.application'
+
+
+android {
+    compileSdkVersion 26
+    buildToolsVersion "26.0.2"
+    defaultConfig {
+        applicationId "com.jiuyan.sheep_children"
+        minSdkVersion 21
+        targetSdkVersion 26
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    /* compile fileTree(dir: 'libs', include: ['*.jar'])
+         androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+             exclude group: 'com.android.support', module: 'support-annotations'
+         })*/
+    compile 'com.android.support.constraint:constraint-layout:1.0.2'
+    compile 'com.didi.virtualapk:core:0.9.1'
+    testCompile 'junit:junit:4.12'
+    compile 'com.shark:screencapture:1.0.0'
+    compile 'com.jcodecraeer:xrecyclerview:1.5.2'
+    compile 'com.squareup.okhttp3:okhttp:3.9.1'
+    debugCompile 'com.readystatesoftware.chuck:library:1.1.0'
+    releaseCompile 'com.readystatesoftware.chuck:library-no-op:1.1.0'
+}
+
+apply plugin: 'com.didi.virtualapk.plugin'
+
+virtualApk {
+    packageId = 0x6f // the package id of Resources.
+    targetHost = '../../VirtualAPK/app' // the path of application module in host project.
+    applyHostMapping = true //optional, default value: true.
+}

+ 31 - 0
app/proguard-rules.pro

@@ -0,0 +1,31 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\work\software\SDK/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+
+-dontwarn okhttp3.**
+-dontwarn okio.**
+-dontwarn javax.annotation.**
+# A resource is loaded with a relative path so the package of this class must be preserved.
+-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase

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

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.jiuyan.sheep_children">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
+    <uses-permission android:name="android.permission.REQUEST_MEDIA_PROJECTION"/>
+    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/icon"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name=".page.MainActivity"
+            android:exported="true"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".floatwindow.FloatWindow"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"/>
+        <activity
+            android:name=".page.ShotScreenActivity"
+            android:exported="true"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"/>
+        <activity android:name=".page.UserCenterActivity"/>
+        <activity android:name=".page.WithdrawActivity"/>
+        <activity android:name=".page.DownloadActivity"/>
+
+        <service
+            android:name=".floatwindow.FloatService"
+            android:enabled="true"
+            android:exported="true">
+        </service>
+
+        <provider
+            android:name="android.support.v4.content.FileProvider"
+            android:authorities="com.jiuyan.sheep_children"
+            android:exported="false"
+            android:grantUriPermissions="true">
+            <!--元数据-->
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths"/>
+        </provider>
+    </application>
+
+</manifest>

+ 13 - 0
app/src/main/java/com/jiuyan/sheep_children/Config.java

@@ -0,0 +1,13 @@
+package com.jiuyan.sheep_children;
+
+/**
+ * Created by kemllor on 2017/12/14.
+ */
+
+public class Config {
+    public static String mBaseUrl = "http://10.8.220.213:8088";
+
+    public String getBaseUrl() {
+        return mBaseUrl;
+    }
+}

+ 147 - 0
app/src/main/java/com/jiuyan/sheep_children/floatwindow/FloatService.java

@@ -0,0 +1,147 @@
+package com.jiuyan.sheep_children.floatwindow;
+
+import android.app.ActivityManager;
+import android.app.Service;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.os.Build;
+import android.os.IBinder;
+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 android.widget.TextView;
+import android.widget.Toast;
+
+import com.jiuyan.sheep_children.R;
+import com.jiuyan.sheep_children.page.MainActivity;
+import com.jiuyan.sheep_children.page.ShotScreenActivity;
+
+import java.util.List;
+
+
+public class FloatService extends Service {
+
+    private static final String TAG = "MainService";
+
+    LinearLayout mFloatwindow;
+    WindowManager.LayoutParams params;
+    WindowManager mWm;
+
+    ImageView floaticon;
+
+    //状态栏高度.
+    int statusBarHeight = -1;
+
+    //不与Activity进行绑定.
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "MainService Created");
+        createToucher();
+    }
+
+    private void createToucher() {
+        //赋值WindowManager&LayoutParam.
+        params = new WindowManager.LayoutParams();
+        mWm = (WindowManager) getApplication().getSystemService(Context.WINDOW_SERVICE);
+        //设置type.系统提示型窗口,一般都在应用程序窗口之上.
+        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+        //设置效果为背景透明.
+        params.format = PixelFormat.RGBA_8888;
+        //设置flags.不可聚焦及不可使用按钮对悬浮窗进行操控.
+        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+
+        //设置窗口初始停靠位置.
+        params.gravity = Gravity.LEFT | Gravity.TOP;
+        params.x = 0;
+        params.y = 0;
+
+        //设置悬浮窗口长宽数据.
+        params.width = -2;
+        params.height = 50;
+
+        LayoutInflater inflater = LayoutInflater.from(getApplication());
+        //获取浮动窗口视图所在布局.
+        mFloatwindow = (LinearLayout) inflater.inflate(R.layout.float_window, null);
+        //添加toucherlayout
+        mWm.addView(mFloatwindow, params);
+
+        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.floaticon);
+        final View view = mFloatwindow.findViewById(R.id.ll_info);
+        TextView tvCommit = (TextView) mFloatwindow.findViewById(R.id.tv_commit);
+        TextView tvOpen = (TextView) mFloatwindow.findViewById(R.id.tv_open);
+
+        tvCommit.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                view.setVisibility(View.GONE);
+                Intent intent = new Intent(FloatService.this, ShotScreenActivity.class);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivity(intent);
+            }
+        });
+        tvOpen.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                view.setVisibility(View.GONE);
+                Intent intent = new Intent(FloatService.this, MainActivity.class);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivity(intent);
+            }
+        });
+        floaticon.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                view.setVisibility(View.VISIBLE);
+            }
+        });
+
+        floaticon.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                params.x = (int) event.getRawX() - 25;
+                params.y = (int) event.getRawY() - 25 - statusBarHeight;
+                mWm.updateViewLayout(mFloatwindow, params);
+                return false;
+            }
+        });
+    }
+
+    @Override
+    public void onDestroy() {
+        if (floaticon != null) {
+            mWm.removeView(mFloatwindow);
+        }
+        super.onDestroy();
+    }
+
+}

+ 33 - 0
app/src/main/java/com/jiuyan/sheep_children/floatwindow/FloatWindow.java

@@ -0,0 +1,33 @@
+package com.jiuyan.sheep_children.floatwindow;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v7.app.AppCompatActivity;
+import android.widget.Toast;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class FloatWindow extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (Build.VERSION.SDK_INT >= 23)
+            if (Settings.canDrawOverlays(FloatWindow.this)) {
+                Intent intent = new Intent(FloatWindow.this, FloatService.class);
+                startService(intent);
+                finish();
+            } else {
+                //若没有权限,提示获取.
+                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
+                Toast.makeText(FloatWindow.this, "需要取得权限以使用悬浮窗", Toast.LENGTH_SHORT).show();
+                startActivity(intent);
+                finish();
+            }
+    }
+}

+ 217 - 0
app/src/main/java/com/jiuyan/sheep_children/floatwindow/ShotScreen.java

@@ -0,0 +1,217 @@
+package com.jiuyan.sheep_children.floatwindow;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.graphics.PixelFormat;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.projection.MediaProjection;
+import android.media.projection.MediaProjectionManager;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.support.v4.os.AsyncTaskCompat;
+import android.text.TextUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.nio.ByteBuffer;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class ShotScreen {
+
+    private final SoftReference<Context> mRefContext;
+    private ImageReader mImageReader;
+
+    private MediaProjection mMediaProjection;
+    private VirtualDisplay mVirtualDisplay;
+
+    public String mLocalUrl = "";
+
+    private OnShotListener mOnShotListener;
+
+
+    public ShotScreen(Context context, Intent data) {
+        this.mRefContext = new SoftReference<>(context);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+
+
+            mMediaProjection = getMediaProjectionManager().getMediaProjection(Activity.RESULT_OK,
+                    data);
+
+            mImageReader = ImageReader.newInstance(
+                    getScreenWidth(),
+                    getScreenHeight(),
+                    PixelFormat.RGBA_8888,// a pixel两节省一些内存 个2个字节 此处RGB_565 必须和下面 buffer处理一致的格式
+                    1);
+        }
+    }
+
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    private void virtualDisplay() {
+
+        mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
+                getScreenWidth(),
+                getScreenHeight(),
+                Resources.getSystem().getDisplayMetrics().densityDpi,
+                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
+                mImageReader.getSurface(), null, null);
+
+    }
+
+    public void startScreenShot(OnShotListener onShotListener, String loc_url) {
+        mLocalUrl = loc_url;
+        startScreenShot(onShotListener);
+    }
+
+
+    @TargetApi(Build.VERSION_CODES.KITKAT)
+    public void startScreenShot(OnShotListener onShotListener) {
+
+        mOnShotListener = onShotListener;
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+
+            virtualDisplay();
+
+            Handler handler = new Handler();
+
+            handler.postDelayed(new Runnable() {
+                                    @Override
+                                    public void run() {
+
+                                        Image image = mImageReader.acquireLatestImage();
+
+                                        AsyncTaskCompat.executeParallel(new SaveTask(), image);
+                                    }
+                                },
+                    1000);
+
+        }
+
+    }
+
+
+    public class SaveTask extends AsyncTask<Image, Void, Bitmap> {
+
+        @TargetApi(Build.VERSION_CODES.KITKAT)
+        @Override
+        protected Bitmap doInBackground(Image... params) {
+
+            if (params == null || params.length < 1 || params[0] == null) {
+
+                return null;
+            }
+
+            Image image = params[0];
+
+            int width = image.getWidth();
+            int height = image.getHeight();
+            final Image.Plane[] planes = image.getPlanes();
+            final ByteBuffer buffer = planes[0].getBuffer();
+            //每个像素的间距
+            int pixelStride = planes[0].getPixelStride();
+            //总的间距
+            int rowStride = planes[0].getRowStride();
+            int rowPadding = rowStride - pixelStride * width;
+            Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height,
+                    Bitmap.Config.ARGB_8888);
+            bitmap.copyPixelsFromBuffer(buffer);
+            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
+            image.close();
+            File fileImage = null;
+            if (bitmap != null) {
+                try {
+                    if (TextUtils.isEmpty(mLocalUrl)) {
+                        mLocalUrl = getContext().getExternalFilesDir("screenshot").getAbsoluteFile()
+                                + "/" + SystemClock.currentThreadTimeMillis() + ".png";
+                    }
+                    fileImage = new File(mLocalUrl);
+
+                    if (!fileImage.exists()) {
+                        fileImage.createNewFile();
+                    }
+                    FileOutputStream out = new FileOutputStream(fileImage);
+                    if (out != null) {
+                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
+                        out.flush();
+                        out.close();
+                    }
+
+                } catch (FileNotFoundException e) {
+                    e.printStackTrace();
+                    fileImage = null;
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    fileImage = null;
+                }
+            }
+
+            if (fileImage != null) {
+                return bitmap;
+            }
+            return null;
+        }
+
+        @TargetApi(Build.VERSION_CODES.KITKAT)
+        @Override
+        protected void onPostExecute(Bitmap bitmap) {
+            super.onPostExecute(bitmap);
+
+            if (bitmap != null && !bitmap.isRecycled()) {
+                bitmap.recycle();
+            }
+
+            if (mVirtualDisplay != null) {
+                mVirtualDisplay.release();
+            }
+
+            if (mOnShotListener != null) {
+                mOnShotListener.onFinish(mLocalUrl);
+            }
+
+        }
+    }
+
+
+    private MediaProjectionManager getMediaProjectionManager() {
+
+        return (MediaProjectionManager) getContext().getSystemService(
+                Context.MEDIA_PROJECTION_SERVICE);
+    }
+
+    private Context getContext() {
+        return mRefContext.get();
+    }
+
+
+    private int getScreenWidth() {
+        return Resources.getSystem().getDisplayMetrics().widthPixels;
+    }
+
+    private int getScreenHeight() {
+        return Resources.getSystem().getDisplayMetrics().heightPixels;
+    }
+
+
+    // a  call back listener
+    public interface OnShotListener {
+        void onFinish(String path);
+    }
+}

+ 92 - 0
app/src/main/java/com/jiuyan/sheep_children/net/NetManager.java

@@ -0,0 +1,92 @@
+package com.jiuyan.sheep_children.net;
+
+import android.content.Context;
+
+import com.readystatesoftware.chuck.ChuckInterceptor;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.FormBody;
+import okhttp3.Headers;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+/**
+ * Created by kemllor on 2017/12/14.
+ */
+
+public class NetManager {
+
+    private static OkHttpClient mClint;
+
+    public static OkHttpClient getInstancce(Context context) {
+        if (mClint == null) {
+            ChuckInterceptor interceptor = new ChuckInterceptor(context);
+            interceptor.showNotification(false);
+
+            mClint = new OkHttpClient.Builder()
+                    .connectTimeout(30, TimeUnit.SECONDS)
+                    .readTimeout(30, TimeUnit.SECONDS)
+                    .writeTimeout(30, TimeUnit.SECONDS)
+                    .addInterceptor(interceptor)
+                    .build();
+        }
+        return mClint;
+    }
+
+
+    public static void get(String url, Callback callback, Context context) {
+        Request request = new Request.Builder().url(url).get().build();
+        getInstancce(context).newCall(request).enqueue(callback);
+    }
+
+    public static void post(String url, Map<String, String> parma, Callback callback, Context context) {
+        FormBody.Builder builder = new FormBody.Builder();
+        for (Map.Entry<String, String> el : parma.entrySet()) {
+            builder.add(el.getKey(), el.getValue());
+        }
+        FormBody body = builder.build();
+        Request request = new Request.Builder().url(url).post(body).build();
+        getInstancce(context).newCall(request).enqueue(callback);
+    }
+
+    public static void upload(String url, Map<String, String> parma, File file, Callback callback, Context context) {
+        FormBody.Builder builder = new FormBody.Builder();
+        for (Map.Entry<String, String> el : parma.entrySet()) {
+            builder.add(el.getKey(), el.getValue());
+        }
+        FormBody body = builder.build();
+
+        MediaType type = MediaType.parse("application/octet-stream");
+        RequestBody fileBody = RequestBody.create(type, file);
+
+        RequestBody multipartBody = new MultipartBody.Builder()
+                .setType(MultipartBody.FORM)
+                .addPart(Headers.of(
+                        "Content-Disposition",
+                        "form-data; name=\"params\""), body)
+                .addPart(Headers.of(
+                        "Content-Disposition",
+                        "form-data; name=\"file\"; filename=\"screenshot.png\""), fileBody)
+                .build();
+
+        Request request = new Request.Builder().url(url)
+                .addHeader("User-Agent", "android")
+                .header("Content-Type", "multipart/form-data")
+                .post(multipartBody)
+                .build();
+        getInstancce(context).newCall(request).enqueue(callback);
+    }
+}
+

+ 11 - 0
app/src/main/java/com/jiuyan/sheep_children/net/Url.java

@@ -0,0 +1,11 @@
+package com.jiuyan.sheep_children.net;
+
+import com.jiuyan.sheep_children.Config;
+
+/**
+ * Created by kemllor on 2017/12/14.
+ */
+
+public class Url {
+    public  String Upload_img= Config.mBaseUrl+"/v1/up/";
+}

+ 223 - 0
app/src/main/java/com/jiuyan/sheep_children/page/DownloadActivity.java

@@ -0,0 +1,223 @@
+package com.jiuyan.sheep_children.page;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.support.annotation.Nullable;
+import android.support.v4.content.FileProvider;
+import android.system.Os;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.jiuyan.sheep_children.R;
+import com.jiuyan.sheep_children.net.NetManager;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Path;
+import java.util.Date;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import static com.jiuyan.sheep_children.page.DownloadActivity.DownloadState.DONE;
+import static com.jiuyan.sheep_children.page.DownloadActivity.DownloadState.DOWNLOADING;
+import static com.jiuyan.sheep_children.page.DownloadActivity.DownloadState.PAUSE;
+import static com.jiuyan.sheep_children.page.DownloadActivity.DownloadState.PENDING;
+
+
+/**
+ * 下载界面
+ * Created by kemllor on 2017/12/14.
+ */
+
+public class DownloadActivity extends Activity implements View.OnClickListener {
+
+
+    private static final String DOWNLOAD_URL = "https://qiniu.kuaifazs.com/fszhskp_12493_haowan_2.1.2.apk";
+
+    private OkHttpClient mClint;
+
+
+    private int mTotal;
+
+    private static final int DELTA = 4 * 1024 * 1024;
+
+    private OutputStream mDstOutputStream;
+
+    private int mCurrentDownload;
+
+    private TextView mTvDownload;
+    private ProgressBar mPbDownload;
+
+    private DownloadState mState = PENDING;
+    private String mPath;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.download_activity);
+        findViews();
+        initClient();
+    }
+
+    private void initClient() {
+        if (mClint == null) {
+            mClint = NetManager.getInstancce(getApplicationContext());
+        }
+    }
+
+    private void findViews() {
+        mTvDownload = (TextView) findViewById(R.id.tv_download);
+        mPbDownload = (ProgressBar) findViewById(R.id.pb_download);
+
+        mTvDownload.setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (R.id.tv_download == v.getId()) {
+            switch (mState) {
+                case PENDING:
+                    startDownloadSelf();
+                    mState = DOWNLOADING;
+                    break;
+                case DOWNLOADING:
+                    mState = PAUSE;
+                    break;
+                case PAUSE:
+                    mState = DOWNLOADING;
+                    downloadRange(mCurrentDownload);
+                    break;
+            }
+            refreshButton();
+        }
+    }
+
+    public enum DownloadState {
+        PENDING,
+        DOWNLOADING,
+        PAUSE,
+        DONE
+    }
+
+
+    private void refreshButton() {
+        switch (mState) {
+            case DOWNLOADING:
+                mTvDownload.setText(R.string.pause);
+                break;
+            case PENDING:
+                mTvDownload.setText(R.string.start_download);
+                break;
+            case PAUSE:
+                mTvDownload.setText(R.string.resume);
+                break;
+            case DONE:
+                mTvDownload.setText(R.string.done);
+                break;
+        }
+    }
+
+    //开始下载
+    private void startDownloadSelf() {
+        getFileLength(DOWNLOAD_URL, new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                if (response.isSuccessful()) {
+                    //获取下载文件长度
+                    mTotal = Integer.valueOf(response.header("Content-Length"));
+                    mPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+                            .getAbsolutePath() + "/" + SystemClock.currentThreadTimeMillis() + "sheepTask.apk";
+                    mDstOutputStream = new FileOutputStream(mPath);
+                    downloadRange(0);
+                }
+            }
+        });
+    }
+
+    //获取文件大小
+    private void getFileLength(String url, Callback callback) {
+        Request request = new Request.Builder()
+                .url(url)
+                .method("HEAD", null).build();
+
+        mClint.newCall(request).enqueue(callback);
+    }
+
+    private void downloadRange(int start) {
+        Request request = new Request.Builder()
+                .url(DOWNLOAD_URL)
+                .addHeader("range", "bytes=" + start + "-" + Math.min(start + DELTA, mTotal)).build();
+
+        mClint.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                if (response.isSuccessful() && mState == DOWNLOADING) {
+                    final byte[] bytes = response.body().bytes();
+                    mDstOutputStream.write(bytes);
+                    mCurrentDownload += bytes.length;
+                    mPbDownload.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            int progress = (int) (mCurrentDownload * 1.0 / mTotal * 100);
+                            mPbDownload.setProgress(progress);
+
+                            if (100 == progress) {
+                                mState = DONE;
+                                refreshButton();
+                                if (!TextUtils.isEmpty(mPath)) {
+                                    installApk(mPath);
+                                }
+                            }
+                        }
+                    });
+
+                    if (mCurrentDownload >= mTotal) {
+                        mDstOutputStream.flush();
+                        mDstOutputStream.close();
+                        return;
+                    }
+
+                    downloadRange(mCurrentDownload);
+                }
+            }
+        });
+    }
+
+    public void installApk(String path) {
+        File file = new File(path);
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (Build.VERSION.SDK_INT >= 24) { //判读版本是否在7.0以上
+            Uri apkUri = FileProvider.getUriForFile(this, "com.jiuyan.sheep_children", file);
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
+        } else {
+            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
+        }
+        startActivity(intent);
+    }
+
+}

+ 130 - 0
app/src/main/java/com/jiuyan/sheep_children/page/MainActivity.java

@@ -0,0 +1,130 @@
+package com.jiuyan.sheep_children.page;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Point;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.widget.AppCompatAutoCompleteTextView;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.jcodecraeer.xrecyclerview.XRecyclerView;
+import com.jiuyan.sheep_children.R;
+import com.jiuyan.sheep_children.floatwindow.FloatService;
+import com.jiuyan.sheep_children.floatwindow.FloatWindow;
+import com.jiuyan.sheep_children.page.adapter.TaskAdapter;
+import com.jiuyan.sheep_children.utils.DeviceInfo;
+import com.readystatesoftware.chuck.Chuck;
+
+import java.util.ArrayList;
+
+public class MainActivity extends Activity implements View.OnClickListener {
+
+    private XRecyclerView mRecyclerView;
+    private TaskAdapter mAdapter;
+    private TextView mTvWithdraw;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main_activity);
+        findviews();
+
+
+        requestPermission();
+        Point deviceSize = DeviceInfo.getDeviceSize(this);
+        View head = View.inflate(this, R.layout.task_head, null);
+        findViewHead(head);
+        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(deviceSize.x, LinearLayout.LayoutParams.WRAP_CONTENT);
+        head.setLayoutParams(params);
+        mRecyclerView.addHeaderView(head);
+
+        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
+        mRecyclerView.setLayoutManager(layoutManager);
+        mAdapter = new TaskAdapter(new ArrayList<String>());
+        mAdapter.setClickCallBack(new TaskAdapter.ItemClickCallBack<String>() {
+            @Override
+            public void onItemClick(String pos) {
+                Intent intent = new Intent(MainActivity.this, DownloadActivity.class);
+                intent.putExtra("data", pos);
+                startActivity(intent);
+            }
+        });
+        mRecyclerView.setAdapter(mAdapter);
+        /*if (ContextCompat.checkSelfPermission(this, Manifest.permission.PACKAGE_USAGE_STATS) != PackageManager.PERMISSION_GRANTED) {
+            Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
+            startActivity(intent);
+        }*/
+
+        setListener();
+    }
+
+    private void requestPermission() {
+        if (Build.VERSION.SDK_INT >= 23)
+            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
+            }
+    }
+
+    private void findViewHead(View head) {
+        mTvWithdraw = (TextView) head.findViewById(R.id.tv_withdraw);
+    }
+
+
+    private void setListener() {
+        mTvWithdraw.setOnClickListener(this);
+        mTvWithdraw.setOnLongClickListener(new View.OnLongClickListener() {
+
+            @Override
+            public boolean onLongClick(View v) {
+                Intent intent = Chuck.getLaunchIntent(MainActivity.this);
+                startActivity(intent);
+                return true;
+            }
+        });
+    }
+
+    private void findviews() {
+        mRecyclerView = (XRecyclerView) findViewById(R.id.tasks);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    protected void onStop() {
+        Intent intent = new Intent(MainActivity.this, FloatWindow.class);
+        startActivity(intent);
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.tv_withdraw:
+                Intent intent = new Intent(MainActivity.this, UserCenterActivity.class);
+                startActivity(intent);
+                break;
+        }
+    }
+}

+ 111 - 0
app/src/main/java/com/jiuyan/sheep_children/page/ShotScreenActivity.java

@@ -0,0 +1,111 @@
+package com.jiuyan.sheep_children.page;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.ColorDrawable;
+import android.media.projection.MediaProjectionManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.Window;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.jiuyan.sheep_children.floatwindow.FloatService;
+import com.jiuyan.sheep_children.floatwindow.ShotScreen;
+import com.jiuyan.sheep_children.net.NetManager;
+import com.jiuyan.sheep_children.net.Url;
+import com.jiuyan.sheep_children.utils.PackageUtil;
+import com.shark.screencapture.ScreenCapture;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Response;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class ShotScreenActivity extends Activity {
+
+    public static final int REQUEST_MEDIA_PROJECTION = 0x2893;
+    private ScreenCapture mScreenCapture;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(new TextView(this));
+        requestScreenShot();
+    }
+
+
+    public void requestScreenShot() {
+        if (Build.VERSION.SDK_INT >= 21) {
+            startActivityForResult(
+                    ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE))
+                            .createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
+        } else {
+            toast("版本过低,无法截屏");
+        }
+    }
+
+    private void toast(String str) {
+        Toast.makeText(ShotScreenActivity.this, str, Toast.LENGTH_LONG).show();
+    }
+
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (requestCode) {
+            case REQUEST_MEDIA_PROJECTION: {
+                if (resultCode == -1 && data != null) {
+                    ShotScreen shotter = new ShotScreen(ShotScreenActivity.this, data);
+                    shotter.startScreenShot(new ShotScreen.OnShotListener() {
+                        @Override
+                        public void onFinish(String path) {
+                            commitTask(path);
+                        }
+                    });
+                }
+            }
+        }
+    }
+
+    private void commitTask(String path) {
+        String topApp = PackageUtil.getLauncherTopApp(getApplicationContext());
+        HashMap<String, String> parma = new HashMap<>();
+        parma.put("task_pkg", topApp);
+        NetManager.upload(new Url().Upload_img, parma, new File(path), new Callback() {
+            @Override
+            public void onFailure(Call call, final IOException e) {
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        toast(e.getMessage());
+                    }
+                });
+                finish();
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                final String msg = response.body().string();
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        toast(msg);
+                    }
+                });
+                finish();
+            }
+        }, getApplicationContext());
+    }
+
+
+}

+ 29 - 0
app/src/main/java/com/jiuyan/sheep_children/page/UserCenterActivity.java

@@ -0,0 +1,29 @@
+package com.jiuyan.sheep_children.page;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.support.annotation.Nullable;
+import android.view.View;
+
+import com.jiuyan.sheep_children.R;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class UserCenterActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.usercenter_activity);
+        findViewById(R.id.tv_withdraw).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(UserCenterActivity.this, WithdrawActivity.class);
+                startActivity(intent);
+            }
+        });
+    }
+}

+ 20 - 0
app/src/main/java/com/jiuyan/sheep_children/page/WithdrawActivity.java

@@ -0,0 +1,20 @@
+package com.jiuyan.sheep_children.page;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.support.annotation.Nullable;
+
+import com.jiuyan.sheep_children.R;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class WithdrawActivity  extends Activity{
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.withdraw_activity);
+    }
+}

+ 79 - 0
app/src/main/java/com/jiuyan/sheep_children/page/adapter/TaskAdapter.java

@@ -0,0 +1,79 @@
+package com.jiuyan.sheep_children.page.adapter;
+
+import android.content.Intent;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.jiuyan.sheep_children.R;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.ViewHolder> {
+
+
+    public void setClickCallBack(ItemClickCallBack clickCallBack) {
+        this.clickCallBack = clickCallBack;
+    }
+
+    public interface ItemClickCallBack<T> {
+        void onItemClick(T pos);
+    }
+
+    public ArrayList datas = null;
+    private ItemClickCallBack clickCallBack;
+
+    public TaskAdapter(ArrayList datas) {
+        this.datas = datas;
+    }
+
+    //创建新View,被LayoutManager所调用
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
+        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.task_item, viewGroup, false);
+        return new ViewHolder(view);
+    }
+
+    //将数据与界面进行绑定的操作
+    @Override
+    public void onBindViewHolder(ViewHolder viewHolder, final int position) {
+        //        viewHolder.mTextView.setText(datas.get(position));
+
+        viewHolder.mRootView.setOnClickListener(
+                new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        if (clickCallBack != null) {
+                            clickCallBack.onItemClick(null);
+                        }
+                    }
+                }
+        );
+    }
+
+    //获取数据的数量
+    @Override
+    public int getItemCount() {
+        //        return datas.size();
+        return 5;
+    }
+
+    //自定义的ViewHolder,持有每个Item的的所有界面元素
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+        public TextView mTextView;
+        public View mRootView;
+
+        public ViewHolder(View view) {
+            super(view);
+            mRootView = view;
+            mTextView = (TextView) view.findViewById(R.id.tv_guide);
+        }
+    }
+}

+ 19 - 0
app/src/main/java/com/jiuyan/sheep_children/utils/DeviceInfo.java

@@ -0,0 +1,19 @@
+package com.jiuyan.sheep_children.utils;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.view.WindowManager;
+
+/**
+ * Created by kemllor on 2017/12/13.
+ */
+
+public class DeviceInfo {
+
+    public  static  Point getDeviceSize(Context context){
+        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+        Point point = new Point();
+        wm.getDefaultDisplay().getSize(point);
+        return point;
+    }
+}

+ 44 - 0
app/src/main/java/com/jiuyan/sheep_children/utils/PackageUtil.java

@@ -0,0 +1,44 @@
+package com.jiuyan.sheep_children.utils;
+
+import android.app.ActivityManager;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.os.Build;
+
+import java.util.List;
+
+/**
+ * Created by kemllor on 2017/12/14.
+ */
+
+public class PackageUtil {
+
+
+    public static String getLauncherTopApp(Context context) {
+        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
+            ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+            List<ActivityManager.RunningTaskInfo> appTasks = activityManager.getRunningTasks(1);
+            if (null != appTasks && !appTasks.isEmpty()) {
+                return appTasks.get(0).topActivity.getPackageName();
+            }
+        } else {
+            long endTime = System.currentTimeMillis();
+            long beginTime = endTime - 10000;
+            UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
+            String result = "";
+            UsageEvents.Event event = new UsageEvents.Event();
+            UsageEvents usageEvents = mUsageStatsManager.queryEvents(beginTime, endTime);
+            while (usageEvents.hasNextEvent()) {
+                usageEvents.getNextEvent(event);
+                if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
+                    result = event.getPackageName();
+                }
+            }
+            if (!android.text.TextUtils.isEmpty(result)) {
+                return result;
+            }
+        }
+        return "";
+    }
+}

binární
app/src/main/res/drawable-hdpi/back.png


binární
app/src/main/res/drawable-hdpi/icon.png


binární
app/src/main/res/drawable-hdpi/sheep.png


+ 56 - 0
app/src/main/res/layout/download_activity.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="70dp">
+
+
+        <ImageView
+            android:id="@+id/img_icon"
+            android:layout_width="50dp"
+            android:layout_height="50dp"
+            android:layout_centerVertical="true"
+            android:layout_marginLeft="10dp"
+            android:src="@drawable/icon"/>
+
+        <TextView
+            android:layout_centerVertical="true"
+            android:id="@+id/tv_desc"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="5dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="某某游戏"
+            android:textColor="@color/black_dark"/>
+
+        <TextView
+            android:id="@+id/tv_download"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:layout_marginRight="10dp"
+            android:background="@color/theme"
+            android:padding="5dp"
+            android:text="下载"
+            android:textColor="@color/white"/>
+    </RelativeLayout>
+
+
+    <ProgressBar
+        android:id="@+id/pb_download"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="10dp"
+        android:layout_marginRight="10dp"/>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+
+</LinearLayout>

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

@@ -0,0 +1,40 @@
+<?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">
+
+    <ImageView
+        android:id="@+id/floaticon"
+        android:layout_width="40dp"
+        android:layout_height="50dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/sheep"/>
+
+    <LinearLayout
+        android:id="@+id/ll_info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:orientation="horizontal"
+        android:visibility="gone">
+
+        <TextView
+            android:id="@+id/tv_commit"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:text="提交任务"
+            android:textColor="@color/theme"/>
+
+        <TextView
+            android:id="@+id/tv_open"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:text="进入大厅"
+            android:textColor="@color/theme"/>
+    </LinearLayout>
+
+
+</LinearLayout>

+ 13 - 0
app/src/main/res/layout/line_h_1px.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+    <View
+        android:layout_marginTop="3dp"
+        android:layout_marginBottom="3dp"
+        android:layout_width="match_parent"
+        android:layout_height="1px"
+        android:background="@color/theme"/>
+
+</LinearLayout>

+ 14 - 0
app/src/main/res/layout/main_activity.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    >
+    <com.jcodecraeer.xrecyclerview.XRecyclerView
+        android:id="@+id/tasks"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    </com.jcodecraeer.xrecyclerview.XRecyclerView>
+
+</LinearLayout>

+ 74 - 0
app/src/main/res/layout/task_head.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="130dp"
+        android:background="@color/theme"
+        >
+
+        <TextView
+            android:id="@+id/tv_withdraw"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:layout_margin="5dp"
+            android:text="提现"
+            android:textColor="@color/white"
+            android:textSize="18sp"/>
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_marginTop="10dp"
+            android:text="我的羊毛"
+            android:textColor="@color/white"
+            />
+
+        <TextView
+            android:id="@+id/money"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/title"
+            android:layout_centerHorizontal="true"
+            android:layout_marginTop="20dp"
+            android:text="250.0"
+            android:textColor="@color/white_red"
+            android:textSize="30dp"
+            />
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/hostry"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true"
+                android:layout_gravity="center_vertical"
+                android:text="历史收入"
+                android:textColor="@color/white"/>
+
+            <TextView
+                android:id="@+id/today"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true"
+                android:layout_marginLeft="50dp"
+                android:text="今日收入"
+                android:textColor="@color/white"/>
+        </LinearLayout>
+    </RelativeLayout>
+
+</LinearLayout>

+ 79 - 0
app/src/main/res/layout/task_item.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="5dp">
+
+        <ImageView
+            android:id="@+id/img_icon"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_centerVertical="true"
+            android:src="@drawable/icon"/>
+
+        <TextView
+            android:id="@+id/tv_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="3dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="title"
+            android:textColor="@color/theme"
+            android:textSize="20sp"/>
+
+        <TextView
+            android:id="@+id/tv_desc"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/tv_title"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="3dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="下载游戏,试玩到5级,截图上报,完成任务"
+            android:textColor="@color/black_dark"
+            android:textSize="12sp"/>
+
+        <TextView
+            android:id="@+id/tv_count"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/tv_desc"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="3dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="250/250"
+            android:textColor="@color/black_dark"
+            android:textSize="12sp"/>
+
+        <TextView
+            android:id="@+id/tv_guide"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/tv_count"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="3dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="任务攻略"
+            android:textColor="@color/theme"
+            android:textSize="12sp"/>
+
+        <TextView
+            android:id="@+id/tv_money"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:layout_marginRight="5dp"
+            android:text="5.00"
+            android:textColor="@color/red"
+            android:textSize="25sp"/>
+
+    </RelativeLayout>
+
+</LinearLayout>

+ 25 - 0
app/src/main/res/layout/title.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="35dp"
+                android:background="@color/theme"
+                android:orientation="vertical">
+
+    <ImageView
+        android:id="@+id/img_back"
+        android:layout_width="25dp"
+        android:layout_height="20dp"
+        android:layout_centerVertical="true"
+        android:paddingLeft="5dp"
+        android:src="@drawable/back"/>
+
+    <TextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerInParent="true"
+        android:text="title"
+        android:textColor="@color/white"
+        android:textSize="20sp"/>
+
+</RelativeLayout>

+ 111 - 0
app/src/main/res/layout/usercenter_activity.xml

@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+
+    <include
+        layout="@layout/title"/>
+
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <ImageView
+            android:id="@+id/img_icon"
+            android:layout_width="80dp"
+            android:layout_height="80dp"
+            android:src="@drawable/icon"/>
+
+        <TextView
+            android:id="@+id/tv_nick"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="10dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="昵称"
+            android:textColor="@color/black_dark"
+            android:textSize="18sp"/>
+
+        <TextView
+            android:id="@+id/tv_level"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignBottom="@id/img_icon"
+            android:layout_marginBottom="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="10dp"
+            android:layout_toRightOf="@id/img_icon"
+            android:text="称号:撸大师"
+            android:textColor="@color/theme"
+            android:textSize="15sp"/>
+    </RelativeLayout>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+
+            android:id="@+id/tv_money"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_marginBottom="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="10dp"
+            android:text="我的羊毛:250"
+            android:textColor="@color/red"
+            android:textSize="20sp"/>
+
+        <TextView
+            android:id="@+id/tv_withdraw"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:layout_marginBottom="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginTop="10dp"
+            android:background="@color/red"
+            android:padding="3dp"
+            android:text="马上提现"
+            android:textColor="@color/white"
+            android:textSize="15sp"/>
+    </RelativeLayout>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+    <TextView
+        android:id="@+id/tv_task"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="5dp"
+        android:layout_marginTop="5dp"
+        android:text="任务记录"
+        android:textColor="@color/black_dark"
+        android:textSize="18sp"/>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+    <TextView
+        android:id="@+id/tv_withdraw_hostroy"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="5dp"
+        android:layout_marginTop="5dp"
+        android:text="提现记录"
+        android:textColor="@color/black_dark"
+        android:textSize="18sp"/>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+</LinearLayout>

+ 42 - 0
app/src/main/res/layout/withdraw_activity.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+
+    <include
+        layout="@layout/title"/>
+
+    <EditText
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:hint="输入提现金额"
+        android:textColor="@color/black_dark"/>
+
+    <TextView
+        android:id="@+id/tv_wx"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="5dp"
+        android:layout_marginTop="5dp"
+        android:text="提现到微信"
+        android:textColor="@color/black_dark"
+        android:textSize="18sp"/>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+    <TextView
+        android:id="@+id/tv_alpay"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="5dp"
+        android:layout_marginTop="5dp"
+        android:text="提现到支付宝"
+        android:textColor="@color/black_dark"
+        android:textSize="18sp"/>
+
+    <include
+        layout="@layout/line_h_1px"/>
+
+</LinearLayout>

binární
app/src/main/res/mipmap-hdpi/ic_launcher.png


binární
app/src/main/res/mipmap-hdpi/ic_launcher_round.png


binární
app/src/main/res/mipmap-mdpi/ic_launcher.png


binární
app/src/main/res/mipmap-mdpi/ic_launcher_round.png


binární
app/src/main/res/mipmap-xhdpi/ic_launcher.png


binární
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


binární
app/src/main/res/mipmap-xxhdpi/ic_launcher.png


binární
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


binární
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


binární
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 12 - 0
app/src/main/res/values/colors.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+    <color name="theme">#ff842c</color>
+    <color name="translate">#00ffffff</color>
+    <color name="white">#ffffff</color>
+    <color name="white_red">#fffbf9</color>
+    <color name="black_dark">#363636</color>
+    <color name="red">#f00</color>
+</resources>

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

@@ -0,0 +1,8 @@
+<resources>
+    <string name="app_name">SamllSheepPlugin</string>
+    <string name="pause">暂停</string>
+    <string name="start_download">开始下载</string>
+    <string name="resume">继续</string>
+    <string name="done">下载完成</string>
+
+</resources>

+ 35 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,35 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+    <style name="Trans" parent="Theme.AppCompat.Light.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+        <item name="android:background">@color/translate</item>
+    </style>
+    <!--全屏加透明-->
+    <style name="TranslucentFullScreenTheme" parent="FullScreenTheme">
+        <item name="android:windowBackground">@color/translate</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+    <!--全屏-->
+    <style name="FullScreenTheme" parent="Trans">
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+    <!--透明,有任务栏电量时间等-->
+    <style name="NoTitleTranslucentTheme" parent="Trans">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowBackground">@color/translate</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+
+</resources>

+ 6 - 0
app/src/main/res/xml/file_paths.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <paths>
+        <external-path name="download" path="."/>
+    </paths>
+</resources>

+ 23 - 0
build.gradle

@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:2.1.3'
+        classpath 'com.didi.virtualapk:gradle:0.9.1'
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 17 - 0
gradle.properties

@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1024m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true

binární
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Tue Dec 12 19:40:12 CST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

+ 160 - 0
gradlew

@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
settings.gradle

@@ -0,0 +1 @@
+include ':app'