From 50beff3dc7debd94c3fd2970764723b52b91a41e Mon Sep 17 00:00:00 2001 From: Ming <18642047181@163.com> Date: Tue, 15 Mar 2022 18:39:48 +0800 Subject: [PATCH] first commit --- .gitignore | 15 + .idea/.gitignore | 3 + .idea/compiler.xml | 6 + .idea/gradle.xml | 24 ++ .idea/inspectionProfiles/Project_Default.xml | 36 +++ .idea/jarRepositories.xml | 30 ++ .idea/misc.xml | 9 + .idea/vcs.xml | 6 + app/.gitignore | 1 + app/build.gradle | 41 +++ app/libs/loopminisdk.aar | Bin 0 -> 48290 bytes app/proguard-rules.pro | 21 ++ .../com/skipping/ExampleInstrumentedTest.java | 26 ++ app/src/main/AndroidManifest.xml | 37 +++ app/src/main/java/com/skipping/APP.java | 12 + app/src/main/java/com/skipping/Contants.java | 20 ++ .../main/java/com/skipping/MainPresenter.java | 10 + .../com/skipping/activity/HostActivity.java | 269 ++++++++++++++++++ .../com/skipping/activity/MainActivity.java | 70 +++++ .../com/skipping/activity/MainActivity2.java | 163 +++++++++++ .../com/skipping/activity/NetActivity.java | 215 ++++++++++++++ app/src/main/java/com/skipping/net/API.java | 78 +++++ .../java/com/skipping/net/ActivityBean.java | 165 +++++++++++ .../com/skipping/net/ActivityReqBean.java | 108 +++++++ .../com/skipping/net/AddActivityBean.java | 156 ++++++++++ .../com/skipping/net/AddActivityReqBean.java | 86 ++++++ .../main/java/com/skipping/net/BaseBean.java | 47 +++ .../com/skipping/net/DetailActivityBean.java | 189 ++++++++++++ .../java/com/skipping/net/GradleBean.java | 42 +++ .../java/com/skipping/net/ScoreReqBean.java | 135 +++++++++ .../main/java/com/skipping/net/TokenBean.java | 40 +++ .../java/com/skipping/net/TokenReqBean.java | 44 +++ .../com/skipping/utils/ThreadPoolUtil.java | 130 +++++++++ .../drawable-v24/ic_launcher_foreground.xml | 30 ++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++++ app/src/main/res/layout/activity_host.xml | 47 +++ app/src/main/res/layout/activity_main.xml | 23 ++ app/src/main/res/layout/activity_main2.xml | 105 +++++++ app/src/main/res/layout/activity_net.xml | 51 ++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3593 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5339 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2636 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3388 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4926 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7472 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7909 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 11873 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10652 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 16570 bytes app/src/main/res/values-night/themes.xml | 16 ++ app/src/main/res/values/colors.xml | 10 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/themes.xml | 16 ++ .../java/com/skipping/ExampleUnitTest.java | 17 ++ build.gradle | 26 ++ gradle.properties | 19 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++++++++++ gradlew.bat | 84 ++++++ libs/.gitignore | 1 + libs/build.gradle | 47 +++ libs/consumer-rules.pro | 0 libs/proguard-rules.pro | 21 ++ .../com/libs/ExampleInstrumentedTest.java | 26 ++ libs/src/main/AndroidManifest.xml | 5 + .../java/com/libs/fragment/BaseActivity.java | 208 ++++++++++++++ .../com/libs/fragment/BaseApplication.java | 104 +++++++ .../java/com/libs/fragment/BaseFragment.java | 114 ++++++++ .../java/com/libs/fragment/BasePresenter.java | 31 ++ .../main/java/com/libs/fragment/BaseView.java | 13 + .../main/java/com/libs/network/CallBack.java | 19 ++ .../main/java/com/libs/network/Concise.java | 223 +++++++++++++++ .../com/libs/network/DefaultObserver.java | 37 +++ .../main/java/com/libs/network/HttpDns.java | 68 +++++ .../interceptor/ErrCodeInterceptor.java | 59 ++++ .../interceptor/ErrorCodeCallBack.java | 9 + .../interceptor/HeaderInterceptor.java | 32 +++ .../main/java/com/libs/threadpool/Pool.java | 143 ++++++++++ .../com/libs/threadpool/RunnableWrapper.java | 47 +++ .../java/com/libs/threadpool/TaskBean.java | 43 +++ .../com/libs/threadpool/ThreadConfigs.java | 32 +++ .../com/libs/threadpool/ThreadManager.java | 156 ++++++++++ .../libs/threadpool/ThreadPoolInternal.java | 56 ++++ .../com/libs/threadpool/TranRunnable.java | 35 +++ .../main/java/com/libs/threadpool/Type.java | 31 ++ .../threadpool/callback/AsyncCallback.java | 32 +++ .../threadpool/callback/DefLogCallBack.java | 26 ++ .../threadpool/callback/MergeCallback.java | 98 +++++++ .../libs/threadpool/callback/OnTaskStart.java | 11 + .../threadpool/callback/ThreadCallback.java | 30 ++ .../java/com/libs/utils/ActivityManager.java | 172 +++++++++++ .../main/java/com/libs/utils/DataUtil.java | 85 ++++++ .../src/main/java/com/libs/utils/LogUtil.java | 210 ++++++++++++++ .../main/java/com/libs/utils/MainLooper.java | 29 ++ .../main/java/com/libs/utils/ScreenUtil.java | 194 +++++++++++++ .../main/java/com/libs/utils/ToastUtil.java | 38 +++ .../com/libs/views/toolbar/CommonToolBar.java | 246 ++++++++++++++++ .../libs/views/toolbar/OnToolBarClick.java | 11 + libs/src/main/res/layout/commontoolbar.xml | 33 +++ libs/src/main/res/values/attr.xml | 7 + libs/src/main/res/values/colors.xml | 34 +++ .../test/java/com/libs/ExampleUnitTest.java | 17 ++ settings.gradle | 3 + 106 files changed, 5875 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/libs/loopminisdk.aar create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/skipping/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/skipping/APP.java create mode 100644 app/src/main/java/com/skipping/Contants.java create mode 100644 app/src/main/java/com/skipping/MainPresenter.java create mode 100644 app/src/main/java/com/skipping/activity/HostActivity.java create mode 100644 app/src/main/java/com/skipping/activity/MainActivity.java create mode 100644 app/src/main/java/com/skipping/activity/MainActivity2.java create mode 100644 app/src/main/java/com/skipping/activity/NetActivity.java create mode 100644 app/src/main/java/com/skipping/net/API.java create mode 100644 app/src/main/java/com/skipping/net/ActivityBean.java create mode 100644 app/src/main/java/com/skipping/net/ActivityReqBean.java create mode 100644 app/src/main/java/com/skipping/net/AddActivityBean.java create mode 100644 app/src/main/java/com/skipping/net/AddActivityReqBean.java create mode 100644 app/src/main/java/com/skipping/net/BaseBean.java create mode 100644 app/src/main/java/com/skipping/net/DetailActivityBean.java create mode 100644 app/src/main/java/com/skipping/net/GradleBean.java create mode 100644 app/src/main/java/com/skipping/net/ScoreReqBean.java create mode 100644 app/src/main/java/com/skipping/net/TokenBean.java create mode 100644 app/src/main/java/com/skipping/net/TokenReqBean.java create mode 100644 app/src/main/java/com/skipping/utils/ThreadPoolUtil.java create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/activity_host.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_main2.xml create mode 100644 app/src/main/res/layout/activity_net.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/test/java/com/skipping/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 libs/.gitignore create mode 100644 libs/build.gradle create mode 100644 libs/consumer-rules.pro create mode 100644 libs/proguard-rules.pro create mode 100644 libs/src/androidTest/java/com/libs/ExampleInstrumentedTest.java create mode 100644 libs/src/main/AndroidManifest.xml create mode 100644 libs/src/main/java/com/libs/fragment/BaseActivity.java create mode 100644 libs/src/main/java/com/libs/fragment/BaseApplication.java create mode 100644 libs/src/main/java/com/libs/fragment/BaseFragment.java create mode 100644 libs/src/main/java/com/libs/fragment/BasePresenter.java create mode 100644 libs/src/main/java/com/libs/fragment/BaseView.java create mode 100644 libs/src/main/java/com/libs/network/CallBack.java create mode 100644 libs/src/main/java/com/libs/network/Concise.java create mode 100644 libs/src/main/java/com/libs/network/DefaultObserver.java create mode 100644 libs/src/main/java/com/libs/network/HttpDns.java create mode 100644 libs/src/main/java/com/libs/network/interceptor/ErrCodeInterceptor.java create mode 100644 libs/src/main/java/com/libs/network/interceptor/ErrorCodeCallBack.java create mode 100644 libs/src/main/java/com/libs/network/interceptor/HeaderInterceptor.java create mode 100644 libs/src/main/java/com/libs/threadpool/Pool.java create mode 100644 libs/src/main/java/com/libs/threadpool/RunnableWrapper.java create mode 100644 libs/src/main/java/com/libs/threadpool/TaskBean.java create mode 100644 libs/src/main/java/com/libs/threadpool/ThreadConfigs.java create mode 100644 libs/src/main/java/com/libs/threadpool/ThreadManager.java create mode 100644 libs/src/main/java/com/libs/threadpool/ThreadPoolInternal.java create mode 100644 libs/src/main/java/com/libs/threadpool/TranRunnable.java create mode 100644 libs/src/main/java/com/libs/threadpool/Type.java create mode 100644 libs/src/main/java/com/libs/threadpool/callback/AsyncCallback.java create mode 100644 libs/src/main/java/com/libs/threadpool/callback/DefLogCallBack.java create mode 100644 libs/src/main/java/com/libs/threadpool/callback/MergeCallback.java create mode 100644 libs/src/main/java/com/libs/threadpool/callback/OnTaskStart.java create mode 100644 libs/src/main/java/com/libs/threadpool/callback/ThreadCallback.java create mode 100644 libs/src/main/java/com/libs/utils/ActivityManager.java create mode 100644 libs/src/main/java/com/libs/utils/DataUtil.java create mode 100644 libs/src/main/java/com/libs/utils/LogUtil.java create mode 100644 libs/src/main/java/com/libs/utils/MainLooper.java create mode 100644 libs/src/main/java/com/libs/utils/ScreenUtil.java create mode 100644 libs/src/main/java/com/libs/utils/ToastUtil.java create mode 100644 libs/src/main/java/com/libs/views/toolbar/CommonToolBar.java create mode 100644 libs/src/main/java/com/libs/views/toolbar/OnToolBarClick.java create mode 100644 libs/src/main/res/layout/commontoolbar.xml create mode 100644 libs/src/main/res/values/attr.xml create mode 100644 libs/src/main/res/values/colors.xml create mode 100644 libs/src/test/java/com/libs/ExampleUnitTest.java create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7b57752 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..6560a98 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..2370474 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d5d35ec --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..295d3e2 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,41 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdkVersion 28 + buildToolsVersion "29.0.2" + + defaultConfig { + applicationId "com.skipping" + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation project(path: ':libs') + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'com.github.felHR85:UsbSerial:6.1.0' +} \ No newline at end of file diff --git a/app/libs/loopminisdk.aar b/app/libs/loopminisdk.aar new file mode 100644 index 0000000000000000000000000000000000000000..5653382dcf85be3038569e23d228224267dbd81d GIT binary patch literal 48290 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 YTNk4BA+3 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 ixbm;%pRu9o_Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.skipping", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..226b770 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/skipping/APP.java b/app/src/main/java/com/skipping/APP.java new file mode 100644 index 0000000..8c81dab --- /dev/null +++ b/app/src/main/java/com/skipping/APP.java @@ -0,0 +1,12 @@ +package com.skipping; + + + +import com.libs.fragment.BaseApplication; + +/** + * @author Ming + * 3/14/22 + */ +public class APP extends BaseApplication { +} diff --git a/app/src/main/java/com/skipping/Contants.java b/app/src/main/java/com/skipping/Contants.java new file mode 100644 index 0000000..61d2e81 --- /dev/null +++ b/app/src/main/java/com/skipping/Contants.java @@ -0,0 +1,20 @@ +package com.skipping; + +/** + * @author Ming + * 3/14/22 + */ +public class Contants { + + /** + * url路径 + */ + public final static String BASE_URL = "https://api.xintijiao.com/ijustjump/"; + + + public final static String CLASS = "class"; + + public final static String GRADE = "grade"; + + public final static String UNFINISHED = "未完成"; +} diff --git a/app/src/main/java/com/skipping/MainPresenter.java b/app/src/main/java/com/skipping/MainPresenter.java new file mode 100644 index 0000000..609de94 --- /dev/null +++ b/app/src/main/java/com/skipping/MainPresenter.java @@ -0,0 +1,10 @@ +package com.skipping; + +import com.libs.fragment.BaseApplication; + +/** + * @author Ming + * 3/14/22 + */ +public class MainPresenter extends BaseApplication { +} diff --git a/app/src/main/java/com/skipping/activity/HostActivity.java b/app/src/main/java/com/skipping/activity/HostActivity.java new file mode 100644 index 0000000..b30f11d --- /dev/null +++ b/app/src/main/java/com/skipping/activity/HostActivity.java @@ -0,0 +1,269 @@ +package com.skipping.activity; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; + +import com.libs.fragment.BaseActivity; +import com.libs.utils.LogUtil; +import com.libs.utils.ToastUtil; +import com.loop.loopminisdk.LoopDevice; +import com.loop.loopminisdk.LoopHost; +import com.loop.loopminisdk.LoopMessage; +import com.loop.loopminisdk.LoopMini; +import com.skipping.R; +import com.skipping.utils.ThreadPoolUtil; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ScheduledFuture; +import java.util.stream.Collectors; + +/** + * @author Ming + * 3/15/22 + */ +public class HostActivity extends BaseActivity { + private LoopMini loopMax; + private Set loopDeviceSet = new HashSet<>(); + private LoopDevice loopDevice; + private EditText editText; + private LoopHost loopHost; + private MyHandler mHandler; + private int position; + private ScheduledFuture scheduledFuture; + private Button btn, btn2, btn3, btn4, btn5; + private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case LoopMini.ACTION_USB_PERMISSION_GRANTED: + ToastUtil.longToast("确认设备权限"); + break; + case LoopMini.ACTION_USB_PERMISSION_NOT_GRANTED: + ToastUtil.longToast("取消设备权限"); + break; + case LoopMini.ACTION_NO_USB: + ToastUtil.longToast("没有插入设备"); + break; + case LoopMini.ACTION_USB_DISCONNECTED: + ToastUtil.longToast("拔出设备"); + break; + case LoopMini.ACTION_USB_NOT_SUPPORTED: + ToastUtil.longToast("设备无法识别"); + break; + } + } + }; + private final ServiceConnection usbConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName arg0, IBinder arg1) { + loopMax = ((LoopMini.UsbBinder) arg1).getService(); + loopMax.setHandler(mHandler); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + loopMax = null; + } + }; + + @Override + protected int getContentViewResId() { + return R.layout.activity_host; + } + + @Override + protected void initView() { + btn = findViewById(R.id.btn); + btn2 = findViewById(R.id.btn2); + btn3 = findViewById(R.id.btn3); + btn4 = findViewById(R.id.btn4); + btn5 = findViewById(R.id.btn5); + editText = findViewById(R.id.edittext); + btn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getHostInfo(); + openPairMode(); + } + }); + btn2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + pairDevice(Integer.valueOf(editText.getText().toString())); + } + }); + btn3.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + LogUtil.e("设备数据", loopDeviceSet); + } + }); + btn4.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + closePairMode(); + connectDevice(); + } + }); + btn5.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + closePairMode(); + disconnectDevice(); + } + }); + + + } + + @Override + protected void initData() { + mHandler = new MyHandler(); + } + + + /** + * 连接主机 + */ + private void getHostInfo() { + loopMax.getHostInfo(); + } + + /** + * 开启配对模式 + */ + private void openPairMode() { + loopMax.openPairMode(); + } + + /** + * 关闭配对模式 + */ + private void closePairMode() { + loopMax.closePairMode(); + } + + /** + * 匹配设备到指定id + * + * @param id + */ + private void pairDevice(int id) { + loopMax.pairDevice(id); + } + + /** + * 连接设备 + */ + private void connectDevice() { + connectDeviceInner(loopDevice -> loopMax.connectDevice(loopDevice)); + } + + private void disconnectDevice() { + connectDeviceInner(loopDevice -> loopMax.disconnectDevice(loopDevice)); + } + + + private void connectDeviceInner(ConnectInterface connectInterface) { + if (loopDeviceSet.size() == 0) { + return; + } + if (scheduledFuture != null) { + scheduledFuture.cancel(false); + } + List deviceList = loopDeviceSet.stream().collect(Collectors.toList()); + position = 0; + scheduledFuture = ThreadPoolUtil.getSingleton().scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + if (position > deviceList.size()) { + scheduledFuture.cancel(false); + } + connectInterface.connect(deviceList.get(position)); + position++; + } + }, 0, 10); + } + + public interface ConnectInterface { + void connect(LoopDevice loopDevice); + } + + @Override + protected void onResume() { + super.onResume(); + setFilters(); + startService(usbConnection); + } + + @Override + public void onPause() { + super.onPause(); + unregisterReceiver(mUsbReceiver); + unbindService(usbConnection); + } + + private void startService(ServiceConnection serviceConnection) { + if (!LoopMini.SERVICE_CONNECTED) { + Intent startService = new Intent(this, LoopMini.class); + startService(startService); + } + Intent bindingIntent = new Intent(this, LoopMini.class); + bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE); + } + + private void setFilters() { + IntentFilter filter = new IntentFilter(); + filter.addAction(LoopMini.ACTION_USB_PERMISSION_GRANTED); + filter.addAction(LoopMini.ACTION_NO_USB); + filter.addAction(LoopMini.ACTION_USB_DISCONNECTED); + filter.addAction(LoopMini.ACTION_USB_NOT_SUPPORTED); + filter.addAction(LoopMini.ACTION_USB_PERMISSION_NOT_GRANTED); + registerReceiver(mUsbReceiver, filter); + } + + + private class MyHandler extends Handler { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what) { + case LoopMini.LOOP_PAIR_DEVICE_INFO: + loopDevice = (LoopDevice) msg.obj; + addDevice(loopDevice); + LogUtil.e("连接LoopDevice", loopDevice.toString()); + break; + case LoopMini.Loop_GET_HOST_INFO: + loopHost = (LoopHost) msg.obj; + LogUtil.e("LoopHost", loopHost.toString()); + break; + case LoopMini.LOOP_GET_DEVICE_INFO: + loopDevice = (LoopDevice) msg.obj; + addDevice(loopDevice); + LogUtil.e("获取LoopDevice", loopDevice.toString()); + break; + case LoopMini.LOOP_MESSAGE: + LoopMessage loopMessage = (LoopMessage) msg.obj; + LogUtil.e("LoopMessage", loopMessage.toString()); + break; + } + } + } + + private void addDevice(LoopDevice loopDevice) { + loopDeviceSet.add(loopDevice); + } + +} diff --git a/app/src/main/java/com/skipping/activity/MainActivity.java b/app/src/main/java/com/skipping/activity/MainActivity.java new file mode 100644 index 0000000..aa15078 --- /dev/null +++ b/app/src/main/java/com/skipping/activity/MainActivity.java @@ -0,0 +1,70 @@ +package com.skipping.activity; + + +import android.content.Intent; +import android.view.View; +import android.widget.Button; + +import com.libs.fragment.BaseActivity; +import com.libs.network.CallBack; +import com.libs.network.Concise; +import com.skipping.Contants; +import com.skipping.R; +import com.skipping.net.API; +import com.skipping.net.BaseBean; +import com.skipping.net.TokenBean; +import com.skipping.net.TokenReqBean; + +public class MainActivity extends BaseActivity { + private Concise concise; + private Button btn, btn2; + + @Override + protected int getContentViewResId() { + return R.layout.activity_main; + } + + @Override + protected void initView() { + btn = findViewById(R.id.btn); + btn2 = findViewById(R.id.btn2); + btn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(MainActivity.this, HostActivity.class); + startActivity(intent); + } + }); + btn2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(MainActivity.this, NetActivity.class); + startActivity(intent); + } + }); + } + + @Override + protected void initData() { + concise = new Concise(Contants.BASE_URL) { + } + .build(); + } + + + private void login() { + TokenReqBean tokenReqBean = new TokenReqBean(); + concise.request(this, concise.api.token(tokenReqBean), new CallBack>() { + @Override + public void onSuccess(BaseBean tokenBeanBaseBean) { + + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/skipping/activity/MainActivity2.java b/app/src/main/java/com/skipping/activity/MainActivity2.java new file mode 100644 index 0000000..356626a --- /dev/null +++ b/app/src/main/java/com/skipping/activity/MainActivity2.java @@ -0,0 +1,163 @@ +package com.skipping.activity; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.util.Log; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + +import com.loop.loopminisdk.LoopDevice; +import com.loop.loopminisdk.LoopHost; +import com.loop.loopminisdk.LoopMessage; +import com.loop.loopminisdk.LoopMini; +import com.skipping.R; + +/** + * @author Ming + * 3/14/22 + */ +public class MainActivity2 extends AppCompatActivity { + private LoopMini loopMax; + private LoopDevice loopDevice; + private EditText editText; + private LoopHost loopHost; + private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case LoopMini.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED + Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show(); + break; + case LoopMini.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED + Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show(); + break; + case LoopMini.ACTION_NO_USB: // NO USB CONNECTED + Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show(); + break; + case LoopMini.ACTION_USB_DISCONNECTED: // USB DISCONNECTED + Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show(); + break; + case LoopMini.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED + Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show(); + break; + } + } + }; + private MyHandler mHandler; + private final ServiceConnection usbConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName arg0, IBinder arg1) { + loopMax = ((LoopMini.UsbBinder) arg1).getService(); + loopMax.setHandler(mHandler); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + loopMax = null; + } + }; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main2); + mHandler = new MyHandler(); + editText = findViewById(R.id.edittext); + Button button1 = findViewById(R.id.button); + Button button2 = findViewById(R.id.button2); + Button button3 = findViewById(R.id.button3); + Button button4 = findViewById(R.id.button4); + Button button5 = findViewById(R.id.button5); + Button button6 = findViewById(R.id.button6); + Button button7 = findViewById(R.id.button7); + Button button8 = findViewById(R.id.button8); + Button button9 = findViewById(R.id.button9); + Button button10 = findViewById(R.id.button10); + button1.setOnClickListener(v -> loopMax.getHostInfo()); + button2.setOnClickListener(v -> loopMax.openPairMode()); + button3.setOnClickListener(v -> loopMax.closePairMode()); + button4.setOnClickListener(v -> loopMax.pairDevice(Integer.valueOf(editText.getText().toString()))); + button5.setOnClickListener(v -> { + if (loopDevice != null) { + loopMax.connectDevice(loopDevice); + } + }); + button6.setOnClickListener(v -> { + if (loopDevice != null) { + loopMax.disconnectDevice(loopDevice); + } + }); + button7.setOnClickListener(v -> loopMax.getPower()); + button8.setOnClickListener(v -> loopMax.getCount()); + button9.setOnClickListener(v -> loopMax.startJumpLimitTime(30)); + button10.setOnClickListener(v -> loopMax.stopJump()); + } + + @Override + protected void onResume() { + super.onResume(); + setFilters(); // Start listening notifications from UsbService + startService(usbConnection); // Start UsbService(if it was not started before) and Bind it + } + + @Override + public void onPause() { + super.onPause(); + unregisterReceiver(mUsbReceiver); + unbindService(usbConnection); + } + + private void startService(ServiceConnection serviceConnection) { + if (!LoopMini.SERVICE_CONNECTED) { + Intent startService = new Intent(this, LoopMini.class); + startService(startService); + } + Intent bindingIntent = new Intent(this, LoopMini.class); + bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE); + } + + private void setFilters() { + IntentFilter filter = new IntentFilter(); + filter.addAction(LoopMini.ACTION_USB_PERMISSION_GRANTED); + filter.addAction(LoopMini.ACTION_NO_USB); + filter.addAction(LoopMini.ACTION_USB_DISCONNECTED); + filter.addAction(LoopMini.ACTION_USB_NOT_SUPPORTED); + filter.addAction(LoopMini.ACTION_USB_PERMISSION_NOT_GRANTED); + registerReceiver(mUsbReceiver, filter); + } + + private class MyHandler extends Handler { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what) { + case LoopMini.LOOP_PAIR_DEVICE_INFO: + loopDevice = (LoopDevice) msg.obj; + Log.d("LoopDevice", loopDevice.toString()); + break; + case LoopMini.Loop_GET_HOST_INFO: + loopHost = (LoopHost) msg.obj; + Log.d("LoopHost", loopHost.toString()); + break; + case LoopMini.LOOP_GET_DEVICE_INFO: + LoopDevice loopDevice = (LoopDevice) msg.obj; + Log.d("LoopDevice", loopDevice.toString()); + break; + case LoopMini.LOOP_MESSAGE: + LoopMessage loopMessage = (LoopMessage) msg.obj; + Log.d("LoopMessage", loopMessage.toString()); + break; + } + } + } +} diff --git a/app/src/main/java/com/skipping/activity/NetActivity.java b/app/src/main/java/com/skipping/activity/NetActivity.java new file mode 100644 index 0000000..5e21509 --- /dev/null +++ b/app/src/main/java/com/skipping/activity/NetActivity.java @@ -0,0 +1,215 @@ +package com.skipping.activity; + +import android.view.View; +import android.widget.Button; + +import com.libs.fragment.BaseActivity; +import com.libs.network.CallBack; +import com.libs.network.Concise; +import com.libs.utils.LogUtil; +import com.skipping.Contants; +import com.skipping.R; +import com.skipping.net.API; +import com.skipping.net.ActivityBean; +import com.skipping.net.ActivityReqBean; +import com.skipping.net.AddActivityBean; +import com.skipping.net.AddActivityReqBean; +import com.skipping.net.BaseBean; +import com.skipping.net.DetailActivityBean; +import com.skipping.net.GradleBean; +import com.skipping.net.ScoreReqBean; +import com.skipping.net.TokenBean; +import com.skipping.net.TokenReqBean; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Ming + * 3/15/22 + */ +public class NetActivity extends BaseActivity { + private Button btn, btn2, btn3, btn4, btn5, btn6, btn7; + private Concise tokenConcise = new Concise(Contants.BASE_URL) { + }.build(); + private Concise concise; + + @Override + protected int getContentViewResId() { + return R.layout.activity_net; + } + + @Override + protected void initView() { + btn = findViewById(R.id.btn); + btn2 = findViewById(R.id.btn2); + btn3 = findViewById(R.id.btn3); + btn4 = findViewById(R.id.btn4); + btn5 = findViewById(R.id.btn5); + btn6 = findViewById(R.id.btn6); + btn7 = findViewById(R.id.btn7); + + btn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + TokenReqBean tokenReqBean = new TokenReqBean(); + tokenReqBean.setDeviceID("466e9c"); + tokenReqBean.setLogName("loop"); + tokenReqBean.setLogPwd("123456"); + tokenConcise.request(NetActivity.this, tokenConcise.api.token(tokenReqBean), new CallBack>() { + @Override + public void onSuccess(BaseBean tokenBeanBaseBean) { + concise = new Concise(Contants.BASE_URL) { + }.addHeader("Token", tokenBeanBaseBean.getData().getToken()).build(); + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + btn2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + concise.request(NetActivity.this, concise.api.getGrade(), new CallBack>>() { + @Override + public void onSuccess(BaseBean> listBaseBean) { + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + btn3.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + concise.request(NetActivity.this, concise.api.getClass("6b76e9770a4eafbcee213121d4ad6b"), new CallBack>>() { + @Override + public void onSuccess(BaseBean> listBaseBean) { + LogUtil.e("数据",listBaseBean.getData()); + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + btn4.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ActivityReqBean bean = new ActivityReqBean(); + bean.setGenre(Contants.CLASS); + bean.setActivityType("timing"); + bean.setGroupID("77bba9124a4281bc9f92f965561cd5"); + bean.setIndex(1); + bean.setPageSize(10); + bean.setStatus(Contants.UNFINISHED); + concise.request(NetActivity.this, concise.api.getActivityList(bean), new CallBack>>() { + @Override + public void onSuccess(BaseBean> listBaseBean) { + + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + btn5.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + AddActivityReqBean bean = new AddActivityReqBean(); + bean.setName("test001"); + bean.setActivityType("timing"); + bean.setValue(60); + bean.setGroupID("77bba9124a4281bc9f92f965561cd5"); + bean.setPersonNumber(6); + bean.setStep(2); + concise.request(NetActivity.this, concise.api.addActivity(bean), new CallBack>>() { + @Override + public void onSuccess(BaseBean> listBaseBean) { + + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + btn6.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + concise.request(NetActivity.this, concise.api.detailActivity("15"), new CallBack>>() { + @Override + public void onSuccess(BaseBean> listBaseBean) { + + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + btn7.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ScoreReqBean bean = new ScoreReqBean(); + bean.setId(15); + bean.setStep(2); + List candidatesBeanList = new ArrayList<>(); + ScoreReqBean.CandidatesBean candidatesBean = new ScoreReqBean.CandidatesBean(); + candidatesBean.setComplateTime(1646975055); + ScoreReqBean.CandidatesBean.InfoBean infoBean = new ScoreReqBean.CandidatesBean.InfoBean(); + List list = new ArrayList<>(); + list.add(1); + list.add(1); + list.add(1); + list.add(1); + infoBean.setDetail(list); + infoBean.setPersonID("a12e6f5a4383855caa2bd36958a2"); + infoBean.setScore(10); + List infoBeans = new ArrayList<>(); + infoBeans.add(infoBean); + candidatesBean.setInfo(infoBeans); + candidatesBeanList.add(new ScoreReqBean.CandidatesBean()); + bean.setCandidates(candidatesBeanList); + concise.request(NetActivity.this, concise.api.score(bean), new CallBack() { + @Override + public void onSuccess(BaseBean baseBean) { + + } + + @Override + public void onFailed(Throwable e) { + + } + }); + } + }); + + } + + @Override + protected void initData() { + + } +} diff --git a/app/src/main/java/com/skipping/net/API.java b/app/src/main/java/com/skipping/net/API.java new file mode 100644 index 0000000..3125815 --- /dev/null +++ b/app/src/main/java/com/skipping/net/API.java @@ -0,0 +1,78 @@ +package com.skipping.net; + +import java.util.List; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Path; +import retrofit2.http.Query; + +/** + * @author Ming + * 1/24/22 + */ +public interface API { + + /** + * 登录 + * @param tokenReq + * @return + */ + @POST("auth") + Observable> token(@Body TokenReqBean tokenReq); + + + /** + * 获取年级列表 + * @return + */ + @GET("groupmap?genre=grade") + Observable>> getGrade(); + + + /** + * 获取班级列表 + * @param pid + * @return + */ + @GET("groupmap?genre=class") + Observable>> getClass(@Query("pid") String pid); + + + /** + * 获取活动列表 + * @param activityReqBean + * @return + */ + @POST("activity/list") + Observable>> getActivityList(@Body ActivityReqBean activityReqBean); + + + /** + * 添加活动 + * @param addActivityReqBean + * @return + */ + @POST("activity/create") + Observable>> addActivity(@Body AddActivityReqBean addActivityReqBean); + + /** + * 活动详情 + * @param id + * @return + */ + @GET("activity/detail") + Observable>> detailActivity(@Query("activityid") String id); + + /** + * 上报 + * @param scoreReqBean + * @return + */ + @POST("activity/score") + Observable score(@Body ScoreReqBean scoreReqBean); + + +} diff --git a/app/src/main/java/com/skipping/net/ActivityBean.java b/app/src/main/java/com/skipping/net/ActivityBean.java new file mode 100644 index 0000000..100dce7 --- /dev/null +++ b/app/src/main/java/com/skipping/net/ActivityBean.java @@ -0,0 +1,165 @@ +package com.skipping.net; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +/** + * @author Ming + * 3/15/22 + */ +public class ActivityBean implements Serializable { + + /** + * ID : 13 + * Name : loop2 + * ActivityType : timing + * Value : 60 + * OrgID : ae428145b8a466e9c72f6047b8 + * GreadID : 6b76e9770a4eafbcee213121d4ad6b + * ClassID : 77bba9124a4281bc9f92f965561cd5 + * Status : 未完成 + * Step : 2 + * CompleteTime : null + * PersonNumber : 6 + * GroupID : + * CreatedAt : 2022-03-14T08:38:21.495+08:00 + */ + + private Integer id; + private String Name; + private String ActivityType; + private Integer Value; + private String OrgID; + private String GreadID; + private String ClassID; + private String Status; + private Integer Step; + private Object CompleteTime; + private Integer PersonNumber; + private String GroupID; + private String CreatedAt; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return Name; + } + + public void setName(String name) { + Name = name; + } + + public String getActivityType() { + return ActivityType; + } + + public void setActivityType(String activityType) { + ActivityType = activityType; + } + + public Integer getValue() { + return Value; + } + + public void setValue(Integer value) { + Value = value; + } + + public String getOrgID() { + return OrgID; + } + + public void setOrgID(String orgID) { + OrgID = orgID; + } + + public String getGreadID() { + return GreadID; + } + + public void setGreadID(String greadID) { + GreadID = greadID; + } + + public String getClassID() { + return ClassID; + } + + public void setClassID(String classID) { + ClassID = classID; + } + + public String getStatus() { + return Status; + } + + public void setStatus(String status) { + Status = status; + } + + public Integer getStep() { + return Step; + } + + public void setStep(Integer step) { + Step = step; + } + + public Object getCompleteTime() { + return CompleteTime; + } + + public void setCompleteTime(Object completeTime) { + CompleteTime = completeTime; + } + + public Integer getPersonNumber() { + return PersonNumber; + } + + public void setPersonNumber(Integer personNumber) { + PersonNumber = personNumber; + } + + public String getGroupID() { + return GroupID; + } + + public void setGroupID(String groupID) { + GroupID = groupID; + } + + public String getCreatedAt() { + return CreatedAt; + } + + public void setCreatedAt(String createdAt) { + CreatedAt = createdAt; + } + + @Override + public String toString() { + return "ActivityBean{" + + "id=" + id + + ", Name='" + Name + '\'' + + ", ActivityType='" + ActivityType + '\'' + + ", Value=" + Value + + ", OrgID='" + OrgID + '\'' + + ", GreadID='" + GreadID + '\'' + + ", ClassID='" + ClassID + '\'' + + ", Status='" + Status + '\'' + + ", Step=" + Step + + ", CompleteTime=" + CompleteTime + + ", PersonNumber=" + PersonNumber + + ", GroupID='" + GroupID + '\'' + + ", CreatedAt='" + CreatedAt + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/net/ActivityReqBean.java b/app/src/main/java/com/skipping/net/ActivityReqBean.java new file mode 100644 index 0000000..9e4458c --- /dev/null +++ b/app/src/main/java/com/skipping/net/ActivityReqBean.java @@ -0,0 +1,108 @@ +package com.skipping.net; + +import java.io.Serializable; + +/** + * @author Ming + * 3/15/22 + */ +public class ActivityReqBean implements Serializable { + + /** + * Genre : class + * ActivityType : timing + * GroupID : f3f80d8e934e0d85a01f608978d64d + * Index : 1 + * PageSize : 10 + * Status : 未完成 + * STime : 1646975055 + * ETime : 1646986281 + */ + + private String Genre; + private String ActivityType; + private String GroupID; + private Integer Index; + private Integer PageSize; + private String Status; + private Integer STime; + private Integer ETime; + + public String getGenre() { + return Genre; + } + + public void setGenre(String genre) { + Genre = genre; + } + + public String getActivityType() { + return ActivityType; + } + + public void setActivityType(String activityType) { + ActivityType = activityType; + } + + public String getGroupID() { + return GroupID; + } + + public void setGroupID(String groupID) { + GroupID = groupID; + } + + public Integer getIndex() { + return Index; + } + + public void setIndex(Integer index) { + Index = index; + } + + public Integer getPageSize() { + return PageSize; + } + + public void setPageSize(Integer pageSize) { + PageSize = pageSize; + } + + public String getStatus() { + return Status; + } + + public void setStatus(String status) { + Status = status; + } + + public Integer getSTime() { + return STime; + } + + public void setSTime(Integer STime) { + this.STime = STime; + } + + public Integer getETime() { + return ETime; + } + + public void setETime(Integer ETime) { + this.ETime = ETime; + } + + @Override + public String toString() { + return "ActivityReqBean{" + + "Genre='" + Genre + '\'' + + ", ActivityType='" + ActivityType + '\'' + + ", GroupID='" + GroupID + '\'' + + ", Index=" + Index + + ", PageSize=" + PageSize + + ", Status='" + Status + '\'' + + ", STime=" + STime + + ", ETime=" + ETime + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/net/AddActivityBean.java b/app/src/main/java/com/skipping/net/AddActivityBean.java new file mode 100644 index 0000000..1a61310 --- /dev/null +++ b/app/src/main/java/com/skipping/net/AddActivityBean.java @@ -0,0 +1,156 @@ +package com.skipping.net; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Ming + * 3/15/22 + */ +public class AddActivityBean implements Serializable { + + /** + * ID : 14 + * ActivityName : test001 + * ActivityType : timing + * ActivityValue : 60 + * Step : 2 + * Candidates : [[{"PersonID":"4414550b40b38fd171ba2e319dc2","Name":"xiaowang","StudentID":"1005","Score":0,"Detail":[]},{"PersonID":"8d34508b457780a298efba2a9c28","Name":"xiaohua","StudentID":"1006","Score":0,"Detail":[]}]] + */ + + private Integer id; + private String ActivityName; + private String ActivityType; + private Integer ActivityValue; + private Integer Step; + private List> Candidates; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getActivityName() { + return ActivityName; + } + + public void setActivityName(String activityName) { + ActivityName = activityName; + } + + public String getActivityType() { + return ActivityType; + } + + public void setActivityType(String activityType) { + ActivityType = activityType; + } + + public Integer getActivityValue() { + return ActivityValue; + } + + public void setActivityValue(Integer activityValue) { + ActivityValue = activityValue; + } + + public Integer getStep() { + return Step; + } + + public void setStep(Integer step) { + Step = step; + } + + public List> getCandidates() { + return Candidates; + } + + public void setCandidates(List> candidates) { + Candidates = candidates; + } + + @Override + public String toString() { + return "AddActivityBean{" + + "id=" + id + + ", ActivityName='" + ActivityName + '\'' + + ", ActivityType='" + ActivityType + '\'' + + ", ActivityValue=" + ActivityValue + + ", Step=" + Step + + ", Candidates=" + Candidates + + '}'; + } + + public static class CandidatesBean implements Serializable { + /** + * PersonID : 4414550b40b38fd171ba2e319dc2 + * Name : xiaowang + * StudentID : 1005 + * Score : 0 + * Detail : [] + */ + + private String PersonID; + private String Name; + private String StudentID; + private Integer Score; + private List Detail; + + public String getPersonID() { + return PersonID; + } + + public void setPersonID(String personID) { + PersonID = personID; + } + + public String getName() { + return Name; + } + + public void setName(String name) { + Name = name; + } + + public String getStudentID() { + return StudentID; + } + + public void setStudentID(String studentID) { + StudentID = studentID; + } + + public Integer getScore() { + return Score; + } + + public void setScore(Integer score) { + Score = score; + } + + public List getDetail() { + return Detail; + } + + public void setDetail(List detail) { + Detail = detail; + } + + @Override + public String toString() { + return "CandidatesBean{" + + "PersonID='" + PersonID + '\'' + + ", Name='" + Name + '\'' + + ", StudentID='" + StudentID + '\'' + + ", Score=" + Score + + ", Detail=" + Detail + + '}'; + } + } +} diff --git a/app/src/main/java/com/skipping/net/AddActivityReqBean.java b/app/src/main/java/com/skipping/net/AddActivityReqBean.java new file mode 100644 index 0000000..9378e4e --- /dev/null +++ b/app/src/main/java/com/skipping/net/AddActivityReqBean.java @@ -0,0 +1,86 @@ +package com.skipping.net; + +import java.io.Serializable; + +/** + * @author Ming + * 3/15/22 + */ +public class AddActivityReqBean implements Serializable { + + /** + * Name : loop2 + * ActivityType : timing + * Value : 60 + * GroupID : f3f80d8e934e0d85a01f608978d64d + * PersonNumber : 6 + * Step : 2 + */ + + private String Name; + private String ActivityType; + private Integer Value; + private String GroupID; + private Integer PersonNumber; + private Integer Step; + + public String getName() { + return Name; + } + + public void setName(String name) { + Name = name; + } + + public String getActivityType() { + return ActivityType; + } + + public void setActivityType(String activityType) { + ActivityType = activityType; + } + + public Integer getValue() { + return Value; + } + + public void setValue(Integer value) { + Value = value; + } + + public String getGroupID() { + return GroupID; + } + + public void setGroupID(String groupID) { + GroupID = groupID; + } + + public Integer getPersonNumber() { + return PersonNumber; + } + + public void setPersonNumber(Integer personNumber) { + PersonNumber = personNumber; + } + + public Integer getStep() { + return Step; + } + + public void setStep(Integer step) { + Step = step; + } + + @Override + public String toString() { + return "AddActivityReqBean{" + + "Name='" + Name + '\'' + + ", ActivityType='" + ActivityType + '\'' + + ", Value=" + Value + + ", GroupID='" + GroupID + '\'' + + ", PersonNumber=" + PersonNumber + + ", Step=" + Step + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/net/BaseBean.java b/app/src/main/java/com/skipping/net/BaseBean.java new file mode 100644 index 0000000..7fa54e7 --- /dev/null +++ b/app/src/main/java/com/skipping/net/BaseBean.java @@ -0,0 +1,47 @@ +package com.skipping.net; + +/** + * @author Ming + * 3/14/22 + */ +public class BaseBean { + private Integer code; + private String msg; + private T data; + + public BaseBean() { + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + @Override + public String toString() { + return "BaseBean{" + + "code=" + code + + ", msg='" + msg + '\'' + + ", data=" + data + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/net/DetailActivityBean.java b/app/src/main/java/com/skipping/net/DetailActivityBean.java new file mode 100644 index 0000000..615c237 --- /dev/null +++ b/app/src/main/java/com/skipping/net/DetailActivityBean.java @@ -0,0 +1,189 @@ +package com.skipping.net; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Ming + * 3/15/22 + */ +public class DetailActivityBean implements Serializable { + + /** + * ID : 1 + * ActivityName : 活动1 + * ActivityType : timing + * ActivityValue : 60 + * Step : 2 + * Max : 12 + * Avg : 9.75 + * Median : 9.5 + * Candidates : [[{"PersonID":"329b20b046f5888bcd5165d115f1","Name":"xiaofang","StudentID":"1002","Score":12,"Detail":null},{"PersonID":"4557de13408aaf9057752285c81a","Name":"xiaohai","StudentID":"1003","Score":8,"Detail":null},{"PersonID":"4dee38df466fa8469f0e62f672fb","Name":"xiaoli","StudentID":"1004","Score":9,"Detail":null}]] + */ + + private Integer id; + private String ActivityName; + private String ActivityType; + private Integer ActivityValue; + private Integer Step; + private Integer Max; + private Double Avg; + private Double Median; + private List> Candidates; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getActivityName() { + return ActivityName; + } + + public void setActivityName(String activityName) { + ActivityName = activityName; + } + + public String getActivityType() { + return ActivityType; + } + + public void setActivityType(String activityType) { + ActivityType = activityType; + } + + public Integer getActivityValue() { + return ActivityValue; + } + + public void setActivityValue(Integer activityValue) { + ActivityValue = activityValue; + } + + public Integer getStep() { + return Step; + } + + public void setStep(Integer step) { + Step = step; + } + + public Integer getMax() { + return Max; + } + + public void setMax(Integer max) { + Max = max; + } + + public Double getAvg() { + return Avg; + } + + public void setAvg(Double avg) { + Avg = avg; + } + + public Double getMedian() { + return Median; + } + + public void setMedian(Double median) { + Median = median; + } + + public List> getCandidates() { + return Candidates; + } + + public void setCandidates(List> candidates) { + Candidates = candidates; + } + + @Override + public String toString() { + return "DetailActivityBean{" + + "id=" + id + + ", ActivityName='" + ActivityName + '\'' + + ", ActivityType='" + ActivityType + '\'' + + ", ActivityValue=" + ActivityValue + + ", Step=" + Step + + ", Max=" + Max + + ", Avg=" + Avg + + ", Median=" + Median + + ", Candidates=" + Candidates + + '}'; + } + + public static class CandidatesBean implements Serializable { + /** + * PersonID : 329b20b046f5888bcd5165d115f1 + * Name : xiaofang + * StudentID : 1002 + * Score : 12 + * Detail : null + */ + + private String PersonID; + private String Name; + private String StudentID; + private Integer Score; + private Object Detail; + + public String getPersonID() { + return PersonID; + } + + public void setPersonID(String personID) { + PersonID = personID; + } + + public String getName() { + return Name; + } + + public void setName(String name) { + Name = name; + } + + public String getStudentID() { + return StudentID; + } + + public void setStudentID(String studentID) { + StudentID = studentID; + } + + public Integer getScore() { + return Score; + } + + public void setScore(Integer score) { + Score = score; + } + + public Object getDetail() { + return Detail; + } + + public void setDetail(Object detail) { + Detail = detail; + } + + @Override + public String toString() { + return "CandidatesBean{" + + "PersonID='" + PersonID + '\'' + + ", Name='" + Name + '\'' + + ", StudentID='" + StudentID + '\'' + + ", Score=" + Score + + ", Detail=" + Detail + + '}'; + } + } +} diff --git a/app/src/main/java/com/skipping/net/GradleBean.java b/app/src/main/java/com/skipping/net/GradleBean.java new file mode 100644 index 0000000..526d24f --- /dev/null +++ b/app/src/main/java/com/skipping/net/GradleBean.java @@ -0,0 +1,42 @@ +package com.skipping.net; + +import java.io.Serializable; + +/** + * @author Ming + * 3/15/22 + */ +public class GradleBean implements Serializable { + + /** + * GroupID : 6b76e9770a4eafbcee213121d4ad6b + * GroupName : 101 + */ + + private String GroupID; + private String GroupName; + + public String getGroupID() { + return GroupID; + } + + public void setGroupID(String groupID) { + GroupID = groupID; + } + + public String getGroupName() { + return GroupName; + } + + public void setGroupName(String groupName) { + GroupName = groupName; + } + + @Override + public String toString() { + return "GradleBean{" + + "GroupID='" + GroupID + '\'' + + ", GroupName='" + GroupName + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/net/ScoreReqBean.java b/app/src/main/java/com/skipping/net/ScoreReqBean.java new file mode 100644 index 0000000..175b4c7 --- /dev/null +++ b/app/src/main/java/com/skipping/net/ScoreReqBean.java @@ -0,0 +1,135 @@ +package com.skipping.net; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Ming + * 3/15/22 + */ +public class ScoreReqBean implements Serializable { + + /** + * ID : 4 + * Step : 2 + * Candidates : [{"ComplateTime":1646975055,"Info":[{"PersonID":"a12e6f5a4383855caa2bd36958a2","Score":10,"Detail":[0,0,0,0,1,2,3,4]},{"PersonID":"329b20b046f5888bcd5165d115f1","Score":12,"Detail":[1,2,2,1,1,2,3,0]},{"PersonID":"4557de13408aaf9057752285c81a","Score":8,"Detail":[0,0,0,0,1,2,3,2]}]}] + */ + + private Integer id; + private Integer Step; + private List Candidates; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getStep() { + return Step; + } + + public void setStep(Integer step) { + Step = step; + } + + public List getCandidates() { + return Candidates; + } + + public void setCandidates(List candidates) { + Candidates = candidates; + } + + @Override + public String toString() { + return "ScoreReqBean{" + + "id=" + id + + ", Step=" + Step + + ", Candidates=" + Candidates + + '}'; + } + + public static class CandidatesBean implements Serializable { + /** + * ComplateTime : 1646975055 + * Info : [{"PersonID":"a12e6f5a4383855caa2bd36958a2","Score":10,"Detail":[0,0,0,0,1,2,3,4]},{"PersonID":"329b20b046f5888bcd5165d115f1","Score":12,"Detail":[1,2,2,1,1,2,3,0]},{"PersonID":"4557de13408aaf9057752285c81a","Score":8,"Detail":[0,0,0,0,1,2,3,2]}] + */ + + private Integer ComplateTime; + private List Info; + + public Integer getComplateTime() { + return ComplateTime; + } + + public void setComplateTime(Integer complateTime) { + ComplateTime = complateTime; + } + + public List getInfo() { + return Info; + } + + public void setInfo(List info) { + Info = info; + } + + @Override + public String toString() { + return "CandidatesBean{" + + "ComplateTime=" + ComplateTime + + ", Info=" + Info + + '}'; + } + + public static class InfoBean implements Serializable { + /** + * PersonID : a12e6f5a4383855caa2bd36958a2 + * Score : 10 + * Detail : [0,0,0,0,1,2,3,4] + */ + + private String PersonID; + private Integer Score; + private List Detail; + + public String getPersonID() { + return PersonID; + } + + public void setPersonID(String personID) { + PersonID = personID; + } + + public Integer getScore() { + return Score; + } + + public void setScore(Integer score) { + Score = score; + } + + public List getDetail() { + return Detail; + } + + public void setDetail(List detail) { + Detail = detail; + } + + @Override + public String toString() { + return "InfoBean{" + + "PersonID='" + PersonID + '\'' + + ", Score=" + Score + + ", Detail=" + Detail + + '}'; + } + } + } +} diff --git a/app/src/main/java/com/skipping/net/TokenBean.java b/app/src/main/java/com/skipping/net/TokenBean.java new file mode 100644 index 0000000..9498a60 --- /dev/null +++ b/app/src/main/java/com/skipping/net/TokenBean.java @@ -0,0 +1,40 @@ +package com.skipping.net; + +import java.io.Serializable; + +/** + * @author Ming + * 3/14/22 + */ +public class TokenBean implements Serializable { + + private String Token; + private Integer ExpireIn; + + public TokenBean() { + } + + public String getToken() { + return Token; + } + + public void setToken(String token) { + Token = token; + } + + public Integer getExpireIn() { + return ExpireIn; + } + + public void setExpireIn(Integer expireIn) { + ExpireIn = expireIn; + } + + @Override + public String toString() { + return "TokenBean{" + + "Token='" + Token + '\'' + + ", ExpireIn=" + ExpireIn + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/net/TokenReqBean.java b/app/src/main/java/com/skipping/net/TokenReqBean.java new file mode 100644 index 0000000..96d021e --- /dev/null +++ b/app/src/main/java/com/skipping/net/TokenReqBean.java @@ -0,0 +1,44 @@ +package com.skipping.net; + +/** + * @author Ming + * 3/14/22 + */ +public class TokenReqBean { + private String LogName; + private String LogPwd; + private String DeviceID; + + public String getLogName() { + return LogName; + } + + public void setLogName(String logName) { + LogName = logName; + } + + public String getLogPwd() { + return LogPwd; + } + + public void setLogPwd(String logPwd) { + LogPwd = logPwd; + } + + public String getDeviceID() { + return DeviceID; + } + + public void setDeviceID(String deviceID) { + DeviceID = deviceID; + } + + @Override + public String toString() { + return "TokenReq{" + + "LogName='" + LogName + '\'' + + ", LogPwd='" + LogPwd + '\'' + + ", DeviceID='" + DeviceID + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/skipping/utils/ThreadPoolUtil.java b/app/src/main/java/com/skipping/utils/ThreadPoolUtil.java new file mode 100644 index 0000000..03c8087 --- /dev/null +++ b/app/src/main/java/com/skipping/utils/ThreadPoolUtil.java @@ -0,0 +1,130 @@ +package com.skipping.utils; + +import com.libs.threadpool.Pool; +import com.libs.threadpool.Type; +import com.libs.threadpool.callback.DefLogCallBack; +import com.libs.utils.MainLooper; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * @author Ming + * 12/22/21 + * 线程池管理类 + */ +public class ThreadPoolUtil { + private ScheduledExecutorService scheduledPool; + private static volatile ThreadPoolUtil threadPoolManager; + + public ThreadPoolUtil() { + initPool(); + } + + public static ThreadPoolUtil getSingleton() { + if (threadPoolManager == null) { + synchronized (ThreadPoolUtil.class) { + if (threadPoolManager == null) { + threadPoolManager = new ThreadPoolUtil(); + } + } + } + return threadPoolManager; + } + + + private void initPool() { + scheduledPool = (ScheduledExecutorService) new Pool.Builder() + .setThreadType(Type.SCHEDULED) + .setLog(new DefLogCallBack()) + .setSize(12) + .build() + .getThreadPool(); + } + + /** + * 单次延迟任务 + * + * @param command Runnable + * @param delay 延迟时间 + */ + public ScheduledFuture schedule(Runnable command, long delay) { + if (scheduledPool == null) { + initPool(); + } + return scheduledPool.schedule(command, delay, TimeUnit.MILLISECONDS); + } + + /** + * 单次延迟任务 + * + * @param command Runnable + * @param delay 延迟时间 + */ + public ScheduledFuture scheduleMain(Runnable command, long delay) { + if (scheduledPool == null) { + initPool(); + } + return scheduledPool.schedule(() -> MainLooper.runOnUiThread(command), delay, TimeUnit.MILLISECONDS); + } + + + + /** + * 重复任务 + * + * @param command Runnable + * @param initDelay 首次延迟时间 + * @param delay 间隔时间 + */ + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initDelay, long delay) { + if (scheduledPool == null) { + initPool(); + } + return scheduledPool.scheduleWithFixedDelay(command, initDelay, delay, TimeUnit.MILLISECONDS); + } + + /** + * 重复任务 + * + * @param command Runnable + * @param initDelay 首次延迟时间 + * @param delay 间隔时间 + */ + public ScheduledFuture scheduleWithFixedDelayMain(Runnable command, long initDelay, long delay) { + if (scheduledPool == null) { + initPool(); + } + return scheduledPool.scheduleWithFixedDelay(() -> MainLooper.runOnUiThread(command), initDelay, delay, TimeUnit.MILLISECONDS); + } + + /** + * 重复任务 第一个执行之后定时再执行 + * + * @param command Runnable + * @param initDelay 首次延迟时间 + * @param delay 间隔时间 + */ + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initDelay, long delay) { + if (scheduledPool == null) { + initPool(); + } + return scheduledPool.scheduleAtFixedRate(command, initDelay, delay, TimeUnit.MILLISECONDS); + } + + + /** + * 重复任务 第一个执行之后定时再执行 + * + * @param command Runnable + * @param initDelay 首次延迟时间 + * @param delay 间隔时间 + */ + public ScheduledFuture scheduleAtFixedRateMain(Runnable command, long initDelay, long delay) { + if (scheduledPool == null) { + initPool(); + } + return scheduledPool.scheduleAtFixedRate(() -> MainLooper.runOnUiThread(command), initDelay, delay, TimeUnit.MILLISECONDS); + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_host.xml b/app/src/main/res/layout/activity_host.xml new file mode 100644 index 0000000..ad043f1 --- /dev/null +++ b/app/src/main/res/layout/activity_host.xml @@ -0,0 +1,47 @@ + + + + + +