Browse Source

no message

贾艺驰 3 years ago
parent
commit
ad470cc837
31 changed files with 1068 additions and 192 deletions
  1. 2 0
      app/build.gradle
  2. 4 1
      app/src/main/AndroidManifest.xml
  3. 19 36
      app/src/main/java/com/jyc/threegames/App.java
  4. 131 0
      app/src/main/java/com/jyc/threegames/activity/AlertActivity.java
  5. 22 3
      app/src/main/java/com/jyc/threegames/activity/GameActivity.java
  6. 2 1
      app/src/main/java/com/jyc/threegames/activity/InputParamActivity.java
  7. 3 2
      app/src/main/java/com/jyc/threegames/activity/LoginActivity.java
  8. 27 0
      app/src/main/java/com/jyc/threegames/activity/NormalUserActivity.java
  9. 181 57
      app/src/main/java/com/jyc/threegames/activity/RingActivity.java
  10. 21 8
      app/src/main/java/com/jyc/threegames/activity/ScaleActivity.java
  11. 74 1
      app/src/main/java/com/jyc/threegames/activity/base/BaseActivity.java
  12. 9 0
      app/src/main/java/com/jyc/threegames/bean/result/ResGameConfig.java
  13. 6 0
      app/src/main/java/com/jyc/threegames/bean/result/ResGameInfo.java
  14. 1 0
      app/src/main/java/com/jyc/threegames/bean/result/ResLogin.java
  15. 2 2
      app/src/main/java/com/jyc/threegames/controller/GameController.java
  16. 54 0
      app/src/main/java/com/jyc/threegames/controller/LoginController.java
  17. 3 2
      app/src/main/java/com/jyc/threegames/net/SimpleRequest.java
  18. 1 1
      app/src/main/java/com/jyc/threegames/net/api/GameService.java
  19. 7 0
      app/src/main/java/com/jyc/threegames/net/api/LoginService.java
  20. 3 0
      app/src/main/java/com/jyc/threegames/net/api/UserConfigService.java
  21. 37 28
      app/src/main/java/com/jyc/threegames/service/GameService.java
  22. 118 0
      app/src/main/java/com/jyc/threegames/utils/NotificationUtils.java
  23. 29 0
      app/src/main/java/com/jyc/threegames/utils/PhoneUtils.java
  24. 23 0
      app/src/main/java/com/jyc/threegames/utils/ToastUtil.java
  25. 31 0
      app/src/main/res/layout/activity_alert.xml
  26. 6 6
      app/src/main/res/layout/activity_game_one.xml
  27. 2 0
      app/src/main/res/layout/activity_normal_user.xml
  28. 189 33
      app/src/main/res/layout/activity_ring.xml
  29. 40 11
      app/src/main/res/layout/activity_scale.xml
  30. 21 0
      app/src/main/res/layout/toast.xml
  31. BIN
      app/src/main/res/raw/test.mp3

+ 2 - 0
app/build.gradle

@@ -51,4 +51,6 @@ dependencies {
     implementation 'com.github.sephiroth74:NumberSlidingPicker:v.1.1.1'
 
     implementation 'org.greenrobot:eventbus:3.2.0'
+
+    implementation 'com.orhanobut:logger:2.2.0'
 }

+ 4 - 1
app/src/main/AndroidManifest.xml

@@ -9,6 +9,8 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+<!--    <uses-permission android:name="android.permission.DEVICE_POWER"/>-->
 
     <application
         android:name=".App"
@@ -46,7 +48,8 @@
             android:launchMode="singleTask"
             android:screenOrientation="portrait" />
         <activity android:name=".activity.NormalUserActivity" android:launchMode="singleTask" />
-        <activity android:name=".activity.RingActivity" android:launchMode="singleTask" />
+        <activity android:name=".activity.RingActivity" android:excludeFromRecents="true" />
+        <activity android:name=".activity.AlertActivity" android:excludeFromRecents="true" android:launchMode="singleTop" />
 
         <service android:name=".service.GameService" />
     </application>

+ 19 - 36
app/src/main/java/com/jyc/threegames/App.java

@@ -1,12 +1,16 @@
 package com.jyc.threegames;
 
+import android.app.ActivityManager;
 import android.app.Application;
+import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
 import android.net.wifi.WifiManager;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
+import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 
@@ -16,40 +20,26 @@ import com.jyc.threegames.controller.GameController;
 import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
 import com.jyc.threegames.service.GameService;
+import com.orhanobut.logger.DiskLogAdapter;
+import com.orhanobut.logger.Logger;
 
+import java.util.ArrayList;
 import java.util.Timer;
 import java.util.TimerTask;
 
 public class App extends Application {
     public static Application app;
 
-//    public static final String SERVER_ADDRESS = "http://192.168.1.100:8080/";
+//    public static final String SERVER_ADDRESS = "http://192.168.1.105:8080/";
 
     public static final String SERVER_ADDRESS = "http://8.210.195.183:8080/";
 
     public static boolean CAN_PLAY_GAME = true;
 
-//    PowerManager.WakeLock mWakeLock;
-//    WifiManager.WifiLock mWifiLock;
-//
-//    private Handler mHandler = new Handler(new Handler.Callback() {
-//        @Override
-//        public boolean handleMessage(@NonNull Message message) {
-//            if (App.CAN_PLAY_GAME && LoginController.getInstance().getCurrentLoginInfo() != null && !LoginController.getInstance().isCurrentUserAdmin())
-//                new SimpleRequest<ResGameInfo>().request(App.app, GameController.getInstance().needPlayGame(), new SimpleRequest.Executor<ResGameInfo>() {
-//                    @Override
-//                    public void execute(ResGameInfo obj) {
-//                        if (App.CAN_PLAY_GAME && obj != null && obj.needDoGame) {
-//                            RingActivity.LAUNCH(App.app, obj);
-//                        }
-//                    }
-//                });
-//
-//            return true;
-//        }
-//    });
-//
-//    private Timer mTimer;
+    public static final long CHECK_TIME = 10 * 60 * 1000;
+
+    public static long LAST_TIME_CHECK_LOW_POWER = 0;
+    public static long LAST_TIME_CHECK_NO_NET_WORK = 0;
 
     @Override
     public void onCreate() {
@@ -57,26 +47,19 @@ public class App extends Application {
 
         app = this;
 
-//        PowerManager pm = (PowerManager) this.getSystemService(
-//                Context.POWER_SERVICE);
-//        mWakeLock = pm.newWakeLock(
-//                PowerManager.PARTIAL_WAKE_LOCK
-//                        | PowerManager.ON_AFTER_RELEASE,
-//                "three_game:weak_lock");
-//        mWakeLock.acquire();
-//
-//        WifiManager wMgr = (WifiManager) this.getSystemService(WIFI_SERVICE);
-//        mWifiLock = wMgr.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "three_game:wifi_lock");
-//        mWifiLock.acquire();
-//
+        Logger.addLogAdapter(new DiskLogAdapter());
+
 //        mTimer = new Timer();
 //        mTimer.schedule(new TimerTask() {
 //            @Override
 //            public void run() {
 //                mHandler.sendEmptyMessage(0);
 //            }
-//        }, 0, 10 * 1000);
+//        }, 0, 60 * 1000);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            startForegroundService(new Intent(App.this, GameService.class));
+        }else
+            startService(new Intent(App.this, GameService.class));
 
-        startService(new Intent(this, GameService.class));
     }
 }

+ 131 - 0
app/src/main/java/com/jyc/threegames/activity/AlertActivity.java

@@ -0,0 +1,131 @@
+package com.jyc.threegames.activity;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.util.Log;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.jyc.threegames.App;
+import com.jyc.threegames.R;
+import com.jyc.threegames.activity.base.BaseActivity;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+public class AlertActivity extends BaseActivity {
+    public static final String PARAM_TEXT = "text";
+
+    @BindView(R.id.label)
+    TextView mTVLabel;
+
+    private String mText;
+
+    private int mCurrentVolume = 0;
+    private Ringtone mRingTone;
+
+    @Override
+    protected void init(Bundle instance) {
+        super.init(instance);
+        if (instance == null)
+            mText = getIntent().getStringExtra(PARAM_TEXT);
+        else
+            mText = instance.getString(PARAM_TEXT);
+
+        mTVLabel.setText(mText);
+
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
+            setTurnScreenOn(true);
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+            keyguardManager.requestDismissKeyguard(this, null);
+        }
+
+        maxVolume();
+        playRing();
+
+        App.CAN_PLAY_GAME = false;
+    }
+
+    @Override
+    protected void onDestroy() {
+        App.CAN_PLAY_GAME = true;
+        stopPlay();
+        restoreVolume();
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        mText = savedInstanceState.getString(PARAM_TEXT);
+    }
+
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putString(PARAM_TEXT, mText);
+    }
+
+    @Override
+    protected int getRootLayout() {
+        return R.layout.activity_alert;
+    }
+
+    @OnClick(R.id.sure)
+    public void clickSure(){
+        finish();
+    }
+
+    private void playRing(){
+        try {
+            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
+            mRingTone = RingtoneManager.getRingtone(this, notification);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
+                mRingTone.setLooping(true);
+            mRingTone.play();
+        } catch (Exception e) {
+            e.printStackTrace();
+            Log.e("three_games", "播放鈴聲失敗");
+        }
+    }
+
+    private void maxVolume(){
+        mCurrentVolume = getAudioManager().getStreamVolume(AudioManager.STREAM_ALARM);
+        getAudioManager().setStreamVolume(AudioManager.STREAM_ALARM, getAudioManager().getStreamMaxVolume(AudioManager.STREAM_ALARM), 0);
+    }
+
+    private void restoreVolume(){
+        getAudioManager().setStreamVolume(AudioManager.STREAM_ALARM, mCurrentVolume, 0);
+    }
+
+    private AudioManager getAudioManager(){
+        return (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+    }
+
+    private void stopPlay(){
+        if (mRingTone != null && mRingTone.isPlaying()){
+            mRingTone.stop();
+        }
+    }
+
+    public static void LAUNCH(Context activity, String text){
+        Intent intent = new Intent(activity, AlertActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(PARAM_TEXT, text);
+        activity.startActivity(intent);
+    }
+}

+ 22 - 3
app/src/main/java/com/jyc/threegames/activity/GameActivity.java

@@ -131,6 +131,11 @@ public class GameActivity extends BaseActivity {
     @Override
     public void onBackPressed() {}
 
+    @Override
+    protected String getAlertText() {
+        return "您好,\n閒置超時,\n請繼續操作!";
+    }
+
     @OnClick(R.id.click_area)
     public void clickNumber(){
         if (mClickable && mClickTime == 0){
@@ -303,6 +308,7 @@ public class GameActivity extends BaseActivity {
         hideAllView();
         mCLForm.setVisibility(View.VISIBLE);
         mEndTime = System.currentTimeMillis();
+        startWatch();
     }
 
     private String getGameHint(){
@@ -366,15 +372,28 @@ public class GameActivity extends BaseActivity {
 
     private Integer[] getPractiseNumbers(int rightNumber, int otherNumberOccurrence){
         List<Integer> result = new ArrayList<>();
+
         for (int i = 0; i < otherNumberOccurrence; i ++)
-            result.add(getRandomNumber(mSpecialNumberOne));
+            result.add(mGameInfo.gameVersion != GameInfo.VERSION_GAME_TWO ? getRandomNumber(mSpecialNumberOne) : getRandomNumber());
+
+        int less = 0;
+        if (mGameInfo.gameVersion == GameInfo.VERSION_GAME_TWO && result.size() > 1)
+            for(int i = 0; i < result.size(); i ++){
+                if (i != result.size() - 1){
+                    if (result.get(i) == mSpecialNumberOne && result.get(i + 1) == mSpecialNumberTwo)
+                        less ++;
+                }
+            }
+
+        if (less > rightNumber)
+            return getPractiseNumbers(rightNumber, otherNumberOccurrence);
 
-        for (int i = 0; i < rightNumber; i ++) {
+        for (int i = 0; i < rightNumber - less; i ++) {
             int index = (int) (Math.random() * result.size());
             if (mGameInfo.gameVersion != GameInfo.VERSION_GAME_TWO)
                 result.add(index, mSpecialNumberOne);
             else{
-                if (index != 0 && index != result.size() - 1 && result.size() > 2 && ((result.get(index - 1) == mSpecialNumberOne && result.get(index) == mSpecialNumberTwo) || (result.get(index) == mSpecialNumberOne && result.get(index + 1) == mSpecialNumberTwo))){
+                if (index != result.size() - 1 && (result.get(index) == mSpecialNumberOne && result.get(index + 1) == mSpecialNumberTwo)){
                     i--;
                     continue;
                 }

+ 2 - 1
app/src/main/java/com/jyc/threegames/activity/InputParamActivity.java

@@ -14,6 +14,7 @@ import com.jyc.threegames.R;
 import com.jyc.threegames.activity.base.BaseActivity;
 import com.jyc.threegames.bean.GameInfo;
 import com.jyc.threegames.bean.result.ResGameInfo;
+import com.jyc.threegames.utils.ToastUtil;
 
 import butterknife.BindView;
 import butterknife.OnClick;
@@ -95,7 +96,7 @@ public class InputParamActivity extends BaseActivity {
     private boolean checkValue(String value, String message){
         int intValue = Integer.parseInt(value);
         if (TextUtils.isEmpty(value) || intValue <= 0){
-            Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, message);
             return false;
         }
 

+ 3 - 2
app/src/main/java/com/jyc/threegames/activity/LoginActivity.java

@@ -16,6 +16,7 @@ import com.jyc.threegames.activity.base.BaseActivity;
 import com.jyc.threegames.bean.result.ResLogin;
 import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
+import com.jyc.threegames.utils.ToastUtil;
 
 import java.security.Permission;
 import java.security.PermissionCollection;
@@ -58,9 +59,9 @@ public class LoginActivity extends BaseActivity {
     @OnClick(R.id.login)
     public void login(){
         if (TextUtils.isEmpty(mETUserName.getText().toString().trim()))
-            Toast.makeText(this, "请输入用户名", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "请输入用户名");
         else if(TextUtils.isEmpty(mETPassWord.getText().toString().trim()))
-            Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "请输入密码");
         else{
             Dialog loading = new ProgressDialog(this);
             loading.setTitle("登录中");

+ 27 - 0
app/src/main/java/com/jyc/threegames/activity/NormalUserActivity.java

@@ -1,7 +1,14 @@
 package com.jyc.threegames.activity;
 
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.MediaPlayer;
+import android.net.wifi.WifiManager;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
@@ -10,22 +17,31 @@ import android.widget.BaseAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 
+import com.jyc.threegames.App;
 import com.jyc.threegames.R;
 import com.jyc.threegames.activity.base.BaseActivity;
 import com.jyc.threegames.bean.EventMessage;
 import com.jyc.threegames.bean.result.ResGameInfo;
 import com.jyc.threegames.bean.result.ResGamePlayTime;
 import com.jyc.threegames.controller.GameController;
+import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
 import org.greenrobot.eventbus.ThreadMode;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.List;
+import java.util.Locale;
+import java.util.Timer;
+import java.util.TimerTask;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
@@ -117,6 +133,17 @@ public class NormalUserActivity extends BaseActivity {
                 public void execute(List<ResGamePlayTime> obj) {
                     mSRF.setRefreshing(false);
                     if (obj != null) {
+                        for (ResGamePlayTime item : obj){
+                            try {
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
+                                Calendar today = Calendar.getInstance();
+                                today.setTime(sdf.parse(item.gameTime));
+                                today.add(Calendar.DATE, -1);
+                                item.gameTime = sdf.format(today.getTime());
+                            } catch (ParseException e) {
+                                e.printStackTrace();
+                            }
+                        }
                         mData = obj;
                         mAdapter.notifyDataSetChanged();
                     }

+ 181 - 57
app/src/main/java/com/jyc/threegames/activity/RingActivity.java

@@ -1,6 +1,8 @@
 package com.jyc.threegames.activity;
 
+import android.annotation.SuppressLint;
 import android.app.Dialog;
+import android.app.KeyguardManager;
 import android.app.ProgressDialog;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -13,12 +15,18 @@ import android.media.RingtoneManager;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.PowerManager;
+import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.RadioGroup;
 import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
+import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.jyc.threegames.App;
 import com.jyc.threegames.R;
@@ -28,11 +36,15 @@ import com.jyc.threegames.bean.result.ResGameInfo;
 import com.jyc.threegames.controller.GameController;
 import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
+import com.jyc.threegames.utils.ToastUtil;
+import com.orhanobut.logger.Logger;
 
 import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
+import java.util.Timer;
+import java.util.TimerTask;
 
 import butterknife.BindView;
 import butterknife.OnClick;
@@ -44,6 +56,19 @@ public class RingActivity extends BaseActivity {
     @BindView(R.id.label)
     TextView mTVLabel;
 
+    @BindView(R.id.hint)
+    TextView mTVHint;
+
+    @BindView(R.id.root_ring)
+    ConstraintLayout mCLRootRing;
+    @BindView(R.id.root_delay)
+    ConstraintLayout mCLRootDelay;
+    @BindView(R.id.root_over_time_scale)
+    ConstraintLayout mCLOverTimeScale;
+
+    @BindView(R.id.delay_group)
+    RadioGroup mRGDelay;
+
     private ResGameInfo mGameInfo;
 
     private boolean mGoToGameOrScale = false;
@@ -52,10 +77,14 @@ public class RingActivity extends BaseActivity {
 
     private Ringtone mRingTone;
 
+    private boolean mFirstDelay = true;
+
     @Override
     protected void init(Bundle instance) {
         super.init(instance);
 
+        Logger.i("enter RingActivity");
+
         App.CAN_PLAY_GAME = false;
 
         if (instance == null)
@@ -68,10 +97,25 @@ public class RingActivity extends BaseActivity {
             return;
         }
 
-        mTVLabel.setText(getLabel());
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
+            setTurnScreenOn(true);
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+            keyguardManager.requestDismissKeyguard(this, null);
+        }
 
         maxVolume();
         playRing();
+
+        if (mGameInfo.playGameType == ResGameInfo.GAME_TYPE_SCALE && mGameInfo.delay >= 3){
+            mCLRootRing.setVisibility(View.GONE);
+            mCLOverTimeScale.setVisibility(View.VISIBLE);
+        }else{
+            mTVLabel.setText(getLabel());
+        }
+
+        Logger.i("RingActivity init");
     }
 
     @Override
@@ -101,78 +145,158 @@ public class RingActivity extends BaseActivity {
     }
 
     @Override
-    public void onBackPressed() { }
+    public void onBackPressed() {}
 
-    @OnClick(R.id.now)
+    @OnClick({R.id.now, R.id.do_it_now})
     public void clickNow(){
+        Logger.i("enter game or scale");
         mGoToGameOrScale = true;
         if (mGameInfo.playGameType == ResGameInfo.GAME_TYPE_GAME){
             GameActivity.LAUNCH_GAME(this, mGameInfo);
-            finish();
         } else {
-            Calendar calendar = Calendar.getInstance();
-            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
-            ScaleActivity.LAUNCH(this, mGameInfo.playGameId, simpleDateFormat.format(calendar.getTime()));
-            finish();
+            ScaleActivity.LAUNCH(this, mGameInfo.playGameId, mGameInfo.date);
         }
+        finish();
     }
 
-    @OnClick(R.id.push_back)
-    public void clickPushBack(){
-        String[] items = new String[]{"5分鐘", "10分鐘", "15分鐘", "20分鐘", "25分鐘", "30分鐘"};
-        new AlertDialog.Builder(this,0)
-            .setTitle("請選擇延遲時間")
-            .setItems(items, new DialogInterface.OnClickListener() {
+    @OnClick({R.id.sure, R.id.do_it_later})
+    public void clickSure(View view){
+        int delay = -1;
+        if (view.getId() == R.id.sure) {
+            switch (mRGDelay.getCheckedRadioButtonId()) {
+                case R.id.delay_5:
+                    delay = 5;
+                    break;
+                case R.id.delay_10:
+                    delay = 10;
+                    break;
+                case R.id.delay_15:
+                    delay = 15;
+                    break;
+                case R.id.delay_20:
+                    delay = 20;
+                    break;
+                case R.id.delay_25:
+                    delay = 25;
+                    break;
+                case R.id.delay_30:
+                    delay = 30;
+                    break;
+            }
+        }else
+            delay = 0;
+
+        if (delay == -1){
+            clickNow();
+        }else{
+            if (LoginController.getInstance().isCurrentUserAdmin()){
+                ToastUtil.showToast(RingActivity.this, "延遲成功");
+                finish();
+                return;
+            }
+
+            Dialog loading = new ProgressDialog(RingActivity.this);
+            loading.setTitle("正在延遲");
+            loading.show();
+            new SimpleRequest<>().requestMustDo(RingActivity.this,
+                mGameInfo.playGameType == ResGameInfo.GAME_TYPE_GAME ?
+                GameController.getInstance().delayGame(mGameInfo.playGameId, mGameInfo.gameConfigId, delay, !mFirstDelay) :
+                GameController.getInstance().delayScale(mGameInfo.playGameId, delay),
+                "延遲失敗!請檢查網絡連接狀態", loading, new SimpleRequest.Executor<ControllerMessage<Object>>() {
                 @Override
-                public void onClick(DialogInterface dialogInterface, int i) {
-                    dialogInterface.dismiss();
-
-                    if (LoginController.getInstance().isCurrentUserAdmin()){
-                        Toast.makeText(RingActivity.this, "延遲成功", Toast.LENGTH_LONG).show();
+                public void execute(ControllerMessage<Object> obj) {
+                    loading.dismiss();
+                    if (obj.isSuccess()){
+                        ToastUtil.showToast(RingActivity.this, "延遲成功");
                         finish();
-                        return;
+                    }else if(!TextUtils.isEmpty(obj.getMessage()) && obj.getMessage().equals("1")){
+                        mFirstDelay = false;
+                        mCLRootDelay.setVisibility(View.GONE);
+                        mTVHint.setVisibility(View.VISIBLE);
+                        TimerTask timerTask = new TimerTask() {
+                            @Override
+                            public void run() {
+                                runOnUiThread(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        mTVHint.setVisibility(View.GONE);
+                                        mCLRootDelay.setVisibility(View.VISIBLE);
+                                    }
+                                });
+                            }
+                        };
+                        Timer timer = new Timer();
+                        timer.schedule(timerTask, 5 * 1000);
                     }
-
-                    Dialog loading = new ProgressDialog(RingActivity.this);
-                    loading.setTitle("正在延遲");
-                    loading.show();
-                    new SimpleRequest<>().requestMustDo(RingActivity.this,
-                        mGameInfo.playGameType == ResGameInfo.GAME_TYPE_GAME ?
-                        GameController.getInstance().delayGame(mGameInfo.playGameId, mGameInfo.gameConfigId, getDelayMin(i)) :
-                        GameController.getInstance().delayScale(mGameInfo.playGameId, getDelayMin(i)),
-                        "延遲失敗!請檢查網絡連接狀態", loading, new SimpleRequest.Executor<ControllerMessage<Object>>() {
-                        @Override
-                        public void execute(ControllerMessage<Object> obj) {
-                            if (obj.isSuccess()){
-                                Toast.makeText(RingActivity.this, "延遲成功", Toast.LENGTH_LONG).show();
-                            }else
-                                Toast.makeText(RingActivity.this, obj.getMessage(), Toast.LENGTH_LONG).show();
-                            finish();
-                        }
-                    });
-
                 }
-            }).create().show();
+            });
+        }
     }
 
-    private int getDelayMin(int index){
-        switch (index){
-            case 1:
-                return 10;
-            case 2:
-                return 15;
-            case 3:
-                return 20;
-            case 4:
-                return 25;
-            case 5:
-                return 30;
-            case 0:
-            default:
-                return 5;
-        }
+    @OnClick(R.id.push_back)
+    public void clickPushBack(){
+        Logger.i("choose delay");
+
+        mCLRootRing.setVisibility(View.GONE);
+        mCLRootDelay.setVisibility(View.VISIBLE);
+
+        stopPlay();
+
+//        String[] items = new String[]{"5分鐘", "10分鐘", "15分鐘", "20分鐘", "25分鐘", "30分鐘"};
+//        new AlertDialog.Builder(this,0)
+//            .setTitle("請選擇延遲時間")
+//            .setItems(items, new DialogInterface.OnClickListener() {
+//                @Override
+//                public void onClick(DialogInterface dialogInterface, int i) {
+//                    dialogInterface.dismiss();
+//
+//                    if (LoginController.getInstance().isCurrentUserAdmin()){
+//                        ToastUtil.showToast(RingActivity.this, "延遲成功");
+//                        finish();
+//                        return;
+//                    }
+//
+//                    Dialog loading = new ProgressDialog(RingActivity.this);
+//                    loading.setTitle("正在延遲");
+//                    loading.show();
+//                    new SimpleRequest<>().requestMustDo(RingActivity.this,
+//                        mGameInfo.playGameType == ResGameInfo.GAME_TYPE_GAME ?
+//                        GameController.getInstance().delayGame(mGameInfo.playGameId, mGameInfo.gameConfigId, getDelayMin(i)) :
+//                        GameController.getInstance().delayScale(mGameInfo.playGameId, getDelayMin(i)),
+//                        "延遲失敗!請檢查網絡連接狀態", loading, new SimpleRequest.Executor<ControllerMessage<Object>>() {
+//                        @Override
+//                        public void execute(ControllerMessage<Object> obj) {
+//                            if (obj.isSuccess()){
+//                                ToastUtil.showToast(RingActivity.this, "延遲成功");
+//                            }else
+//                                ToastUtil.showToast(RingActivity.this, obj.getMessage());
+//                            finish();
+//                        }
+//                    });
+//
+//                }
+//            }).create().show();
     }
 
+
+//    private int getDelayMin(int index){
+//        switch (index){
+//            case 1:
+//                return 10;
+//            case 2:
+//                return 15;
+//            case 3:
+//                return 20;
+//            case 4:
+//                return 25;
+//            case 5:
+//                return 30;
+//            case 0:
+//            default:
+//                return 5;
+//        }
+//    }
+
     private void playRing(){
         try {
             Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
@@ -206,7 +330,7 @@ public class RingActivity extends BaseActivity {
     }
 
     private String getLabel(){
-        return mGameInfo.playGameType == ResGameInfo.GAME_TYPE_GAME ? "您需要做遊戲啦" : "您需要做量表啦";
+        return mGameInfo.playGameType == ResGameInfo.GAME_TYPE_GAME ? "您需要做測試啦" : "您需要做量表啦";
     }
 
     public static void LAUNCH(Context context, ResGameInfo gameInfo){

+ 21 - 8
app/src/main/java/com/jyc/threegames/activity/ScaleActivity.java

@@ -22,6 +22,7 @@ import com.jyc.threegames.bean.result.ResGameInfo;
 import com.jyc.threegames.controller.GameController;
 import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
+import com.jyc.threegames.utils.ToastUtil;
 
 import org.greenrobot.eventbus.EventBus;
 
@@ -57,6 +58,8 @@ public class ScaleActivity extends BaseActivity {
     TextView mTVDinner;
     @BindView(R.id.sleep)
     TextView mTVSleep;
+    @BindView(R.id.date)
+    TextView mTVDate;
 
     private long mCurrentDate = System.currentTimeMillis();
 
@@ -80,6 +83,11 @@ public class ScaleActivity extends BaseActivity {
         if (!LoginController.getInstance().isCurrentUserAdmin()){
             new SimpleRequest<>().request(this, GameController.getInstance().enterScale(mPlayGameId));
         }
+
+        if (!TextUtils.isEmpty(mEventDate))
+            mTVDate.setText(mEventDate.split(" ")[0]);
+
+        mNeedToWatch = true;
     }
 
     @Override
@@ -112,6 +120,11 @@ public class ScaleActivity extends BaseActivity {
         App.CAN_PLAY_GAME = true;
     }
 
+    @Override
+    protected String getAlertText() {
+        return "您好,\n閒置超時,\n請繼續操作!";
+    }
+
     @OnClick(R.id.get_up)
     public void clickGetUp(){
         Dialog dialog = getTimeDialog(new TimePickerDialog.OnTimeSetListener() {
@@ -202,36 +215,36 @@ public class ScaleActivity extends BaseActivity {
         mTVSleep.setText("沒做");
     }
 
-    @OnClick(R.id.save)
+    @OnClick(R.id.sure)
     public void save(){
         if (mGetUp.equals("")){
-            Toast.makeText(this, "請選擇下床時間", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "請選擇下床時間");
             return;
         }
 
         if (mContact.equals("")){
-            Toast.makeText(this, "請選擇第一次與人接觸時間", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "請選擇第一次與人接觸時間");
             return;
         }
 
         if (mWork.equals("")){
-            Toast.makeText(this, "請選擇開始工作,上學,家務,義工活動,照顧家庭或小孩的時間", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "請選擇開始工作,上學,家務,義工活動,照顧家庭或小孩的時間");
             return;
         }
 
         if (mDinner.equals("")){
-            Toast.makeText(this, "請選擇吃晚餐的時間", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "請選擇吃晚餐的時間");
             return;
         }
 
         if (mSleep.equals("")){
-            Toast.makeText(this, "請選擇睡覺的時間", Toast.LENGTH_SHORT).show();
+            ToastUtil.showToast(this, "請選擇睡覺的時間");
             return;
         }
 
 
         if (LoginController.getInstance().isCurrentUserAdmin()){
-            Toast.makeText(ScaleActivity.this, "提交量表成功", Toast.LENGTH_LONG).show();
+            ToastUtil.showToast(this, "提交量表成功");
             finish();
             return;
         }
@@ -251,7 +264,7 @@ public class ScaleActivity extends BaseActivity {
                 @Override
                 public void execute(Object obj) {
                     EventBus.getDefault().post(new EventMessage());
-                    Toast.makeText(ScaleActivity.this, "提交量表成功", Toast.LENGTH_LONG).show();
+                    ToastUtil.showToast(ScaleActivity.this, "提交量表成功");
                     finish();
                 }
             });

+ 74 - 1
app/src/main/java/com/jyc/threegames/activity/base/BaseActivity.java

@@ -6,6 +6,9 @@ import android.content.Intent;
 import android.graphics.Color;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
@@ -13,19 +16,26 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.appcompat.widget.Toolbar;
 
 import com.jyc.threegames.R;
+import com.jyc.threegames.activity.AlertActivity;
 import com.jyc.threegames.activity.LoginActivity;
 import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
+import com.jyc.threegames.utils.ToastUtil;
+
+import java.util.Timer;
+import java.util.TimerTask;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
 
 public abstract class BaseActivity extends AppCompatActivity {
+    protected final int WATCH_LONG = 2 * 60 * 1000;
 
     @Nullable
     @BindView(R.id.toolbar)
@@ -35,6 +45,22 @@ public abstract class BaseActivity extends AppCompatActivity {
     @BindView(R.id.title)
     TextView mTVTitle;
 
+    private long mLastTimeClick = 0;
+    protected boolean mNeedToWatch = false;
+
+    private Timer mWatcher;
+
+    private Handler mClickHandler = new Handler(new Handler.Callback() {
+        @Override
+        public boolean handleMessage(@NonNull Message message) {
+            if (System.currentTimeMillis() - mLastTimeClick >= WATCH_LONG){
+                AlertActivity.LAUNCH(BaseActivity.this, getAlertText());
+                stopWatch();
+            }
+            return true;
+        }
+    });
+
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -54,17 +80,64 @@ public abstract class BaseActivity extends AppCompatActivity {
         init(savedInstanceState);
     }
 
+    @Override
+    protected void onResume() {
+        if (mNeedToWatch)
+            startWatch();
+        super.onResume();
+    }
+
+    @Override
+    protected void onDestroy() {
+        stopWatch();
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN)
+            refreshLastTimeClick();
+        return super.dispatchTouchEvent(ev);
+    }
+
     private void initSystemBar() {
         Window window = getWindow();
         window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
     }
 
+    protected void startWatch(){
+        mNeedToWatch = true;
+        refreshLastTimeClick();
+        mWatcher = new Timer();
+        mWatcher.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                mClickHandler.sendEmptyMessage(0);
+            }
+        }, 0, 2 * 1000);
+    }
+
+    private void stopWatch(){
+        if (mWatcher != null){
+            mWatcher.cancel();
+            mWatcher = null;
+        }
+    }
+
+    private void refreshLastTimeClick(){
+        mLastTimeClick = System.currentTimeMillis();
+    }
+
     protected abstract @LayoutRes int getRootLayout();
 
     protected String getPageTitle(){
         return "";
     }
 
+    protected String getAlertText(){
+        return "";
+    }
+
     protected void init(Bundle instance){}
 
     protected void doLogout(){
@@ -87,7 +160,7 @@ public abstract class BaseActivity extends AppCompatActivity {
                         startActivity(new Intent(BaseActivity.this, LoginActivity.class));
                         finish();
                     }else
-                        Toast.makeText(BaseActivity.this, "禁止退出登錄", Toast.LENGTH_LONG).show();
+                        ToastUtil.showToast(BaseActivity.this, "測試週期已開始,不可登出");
                 }
             });
     }

+ 9 - 0
app/src/main/java/com/jyc/threegames/bean/result/ResGameConfig.java

@@ -0,0 +1,9 @@
+package com.jyc.threegames.bean.result;
+
+public class ResGameConfig {
+    public long id;
+    public String startTime;
+    public String endTime;
+    public long uid;
+    public String messageId;
+}

+ 6 - 0
app/src/main/java/com/jyc/threegames/bean/result/ResGameInfo.java

@@ -35,6 +35,8 @@ public class ResGameInfo implements Parcelable {
     public long practiseDuration; //用戶熱身時長
     public int practiseRightNumber;//用户热身正确数字出现次数
     public int practiseOccurrenceNumber;//用戶熱身數字出現次數
+    public String date;
+    public int delay;
 
     public GameInfo getGameInfo(){
         return new GameInfo(this.gameVersion, this.intervalDuration, this.displayDuration, this.correctNumberOccurrenceNumber, this.errorNumberOccurrenceNumber, this.practiseDuration, this.practiseRightNumber, this.practiseOccurrenceNumber);
@@ -61,6 +63,8 @@ public class ResGameInfo implements Parcelable {
         dest.writeLong(this.practiseDuration);
         dest.writeInt(this.practiseRightNumber);
         dest.writeInt(this.practiseOccurrenceNumber);
+        dest.writeString(this.date);
+        dest.writeInt(this.delay);
     }
 
     public ResGameInfo() {
@@ -80,6 +84,8 @@ public class ResGameInfo implements Parcelable {
         this.practiseDuration = in.readLong();
         this.practiseRightNumber = in.readInt();
         this.practiseOccurrenceNumber = in.readInt();
+        this.date = in.readString();
+        this.delay = in.readInt();
     }
 
     public static final Creator<ResGameInfo> CREATOR = new Creator<ResGameInfo>() {

+ 1 - 0
app/src/main/java/com/jyc/threegames/bean/result/ResLogin.java

@@ -5,6 +5,7 @@ import java.util.List;
 public class ResLogin {
     public String token;
     public LoginInfo info;
+    public List<ResGameConfig> gameConfigs;
 
     public boolean isAdmin(){
         return info != null && info.haveRole(LoginInfo.ADMIN);

+ 2 - 2
app/src/main/java/com/jyc/threegames/controller/GameController.java

@@ -94,8 +94,8 @@ public class GameController extends BaseController {
             .map(new SimpleDataHandleFunction<>());
     }
 
-    public Observable<ControllerMessage<Object>> delayGame(long gamePlayTimeId, long gameConfigId, int delayMin){
-        return getGameService().delayGame(gamePlayTimeId, gameConfigId, delayMin, getDeviceId())
+    public Observable<ControllerMessage<Object>> delayGame(long gamePlayTimeId, long gameConfigId, int delayMin, boolean trueDelay){
+        return getGameService().delayGame(gamePlayTimeId, gameConfigId, delayMin, getDeviceId(), trueDelay)
             .map(new SimpleDataHandleFunction<>());
     }
 

+ 54 - 0
app/src/main/java/com/jyc/threegames/controller/LoginController.java

@@ -1,5 +1,6 @@
 package com.jyc.threegames.controller;
 
+import android.content.Intent;
 import android.os.Environment;
 import android.text.TextUtils;
 import android.util.Log;
@@ -9,6 +10,7 @@ import com.google.gson.JsonParser;
 import com.jyc.threegames.App;
 import com.jyc.threegames.bean.ControllerMessage;
 import com.jyc.threegames.bean.request.ReqLogin;
+import com.jyc.threegames.bean.result.ResGameConfig;
 import com.jyc.threegames.bean.result.ResLogin;
 import com.jyc.threegames.bean.result.ResUserConfig;
 import com.jyc.threegames.net.ResData;
@@ -22,8 +24,11 @@ import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.Calendar;
+import java.util.List;
 
 import io.reactivex.Observable;
+import io.reactivex.ObservableSource;
 import io.reactivex.functions.Consumer;
 import io.reactivex.functions.Function;
 
@@ -96,17 +101,44 @@ public class LoginController extends BaseController {
             });
     }
 
+    private List<ResGameConfig> mGameConfigTempData;
+
     public Observable<ControllerMessage<ResLogin>> login(String userName, String passWord){
         return getLoginService().login(userName, passWord)
+            .concatMap(new Function<ResData<ResLogin>, ObservableSource<ResData<ResLogin>>>() {
+                @Override
+                public ObservableSource<ResData<ResLogin>> apply(ResData<ResLogin> data) throws Exception {
+                    if (data.isRequestSuccess() && data.data != null && data.data.info != null && !TextUtils.isEmpty(data.data.token)){
+                        mLoginInfo = data.data;
+                        return getLoginService().getGameConfigs(data.data.info.id).
+                            map(new Function<ResData<List<ResGameConfig>>, ResData<ResLogin>>() {
+                                @Override
+                                public ResData<ResLogin> apply(ResData<List<ResGameConfig>> listData) throws Exception {
+                                    if (listData.isRequestSuccess() && listData.data != null) {
+                                        mGameConfigTempData = listData.data;
+                                    }else {
+                                        data.code = ResData.CODE_ERROR;
+                                        data.message = listData.message;
+                                        data.data = null;
+                                    }
+                                    return data;
+                                }
+                            });
+                    }else
+                        return Observable.just(data);
+                }
+            })
             .doOnNext(new Consumer<ResData<ResLogin>>() {
                 @Override
                 public void accept(ResData<ResLogin> data) throws Exception {
                     if (data.isRequestSuccess() && data.data != null && data.data.info != null && !TextUtils.isEmpty(data.data.token)){
                         mLoginInfo = data.data;
+                        mLoginInfo.gameConfigs = mGameConfigTempData;
                         writeLoginInfoToSDCard();
                     }
                 }
             })
+            .takeLast(1)
             .map(new SimpleDataHandleFunction<ResData<ResLogin>, ControllerMessage<ResLogin>>());
     }
 
@@ -115,6 +147,28 @@ public class LoginController extends BaseController {
         deleteLoginInfoOnSDCard();
     }
 
+    public boolean inTheTestPeriod(){
+        if (this.mLoginInfo == null || this.mLoginInfo.gameConfigs == null || this.mLoginInfo.gameConfigs.size() == 0)
+            return false;
+        for (ResGameConfig item : this.mLoginInfo.gameConfigs){
+            String startTime = item.startTime;
+            Calendar startCalendar = Calendar.getInstance();
+            startCalendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(startTime.split(":")[0]));
+            startCalendar.set(Calendar.MINUTE, Integer.parseInt(startTime.split(":")[1]));
+
+            String endTime = item.endTime;
+            Calendar endCalendar = Calendar.getInstance();
+            endCalendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(endTime.split(":")[0]));
+            endCalendar.set(Calendar.MINUTE, Integer.parseInt(endTime.split(":")[1]));
+
+            Calendar nowCalendar = Calendar.getInstance();
+            if (nowCalendar.getTime().getTime() >= startCalendar.getTime().getTime() && nowCalendar.getTime().getTime() <= endCalendar.getTime().getTime())
+                return true;
+
+        }
+        return false;
+    }
+
     private void deleteLoginInfoOnSDCard(){
         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
             try {

+ 3 - 2
app/src/main/java/com/jyc/threegames/net/SimpleRequest.java

@@ -6,6 +6,7 @@ import android.text.TextUtils;
 import android.widget.Toast;
 
 import com.jyc.threegames.bean.ControllerMessage;
+import com.jyc.threegames.utils.ToastUtil;
 
 import io.reactivex.Observable;
 import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -54,7 +55,7 @@ public class SimpleRequest<T> {
                             success.execute(message.getObject());
                         }else
                             if (!TextUtils.isEmpty(errorMessage))
-                                Toast.makeText(context, TextUtils.isEmpty(message.getMessage()) ? errorMessage : message.getMessage() , Toast.LENGTH_LONG).show();
+                                ToastUtil.showToast(context, TextUtils.isEmpty(message.getMessage()) ? errorMessage : message.getMessage());
                     }
                 }, new Consumer<Throwable>() {
                     @Override
@@ -64,7 +65,7 @@ public class SimpleRequest<T> {
                         if (error != null)
                             error.execute(throwable);
                         else if (!TextUtils.isEmpty(errorMessage))
-                            Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show();
+                            ToastUtil.showToast(context, errorMessage);
 
                     }
                 });

+ 1 - 1
app/src/main/java/com/jyc/threegames/net/api/GameService.java

@@ -64,7 +64,7 @@ public interface GameService {
 
     @FormUrlEncoded
     @POST("push/log/delay/game")
-    Observable<ResData<Object>> delayGame(@Field("gamePlayTimeId") long gamePlayId, @Field("gameConfigId") long gameConfigId, @Field("delayMin") int delayMin, @Field("deviceId") String deviceId);
+    Observable<ResData<Object>> delayGame(@Field("gamePlayTimeId") long gamePlayId, @Field("gameConfigId") long gameConfigId, @Field("delayMin") int delayMin, @Field("deviceId") String deviceId, @Field("trueDelay") boolean trueDelay);
 
 
     @FormUrlEncoded

+ 7 - 0
app/src/main/java/com/jyc/threegames/net/api/LoginService.java

@@ -1,10 +1,13 @@
 package com.jyc.threegames.net.api;
 
 import com.jyc.threegames.bean.request.ReqLogin;
+import com.jyc.threegames.bean.result.ResGameConfig;
 import com.jyc.threegames.bean.result.ResLogin;
 import com.jyc.threegames.bean.result.ResUserConfig;
 import com.jyc.threegames.net.ResData;
 
+import java.util.List;
+
 import io.reactivex.Observable;
 import retrofit2.http.Body;
 import retrofit2.http.Field;
@@ -16,4 +19,8 @@ public interface LoginService {
     @FormUrlEncoded
     @POST("login")
     Observable<ResData<ResLogin>> login(@Field("username") String userName, @Field("password") String passWord);
+
+    @FormUrlEncoded
+    @POST("game/config/list/uid")
+    Observable<ResData<List<ResGameConfig>>> getGameConfigs(@Field("uid") long uid);
 }

+ 3 - 0
app/src/main/java/com/jyc/threegames/net/api/UserConfigService.java

@@ -1,8 +1,11 @@
 package com.jyc.threegames.net.api;
 
+import com.jyc.threegames.bean.result.ResGameConfig;
 import com.jyc.threegames.bean.result.ResUserConfig;
 import com.jyc.threegames.net.ResData;
 
+import java.util.List;
+
 import io.reactivex.Observable;
 import retrofit2.http.Field;
 import retrofit2.http.FormUrlEncoded;

+ 37 - 28
app/src/main/java/com/jyc/threegames/service/GameService.java

@@ -1,5 +1,6 @@
 package com.jyc.threegames.service;
 
+import android.app.Notification;
 import android.app.Service;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -16,44 +17,53 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.jyc.threegames.App;
+import com.jyc.threegames.activity.AlertActivity;
 import com.jyc.threegames.activity.RingActivity;
 import com.jyc.threegames.bean.result.ResGameInfo;
 import com.jyc.threegames.controller.GameController;
 import com.jyc.threegames.controller.LoginController;
 import com.jyc.threegames.net.SimpleRequest;
+import com.jyc.threegames.utils.NotificationUtils;
+import com.jyc.threegames.utils.PhoneUtils;
+import com.orhanobut.logger.Logger;
 
 import java.util.Timer;
 import java.util.TimerTask;
 
+import io.reactivex.Observable;
+import io.reactivex.disposables.Disposable;
+
 public class GameService extends Service {
 
-//    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-//        @Override
-//        public void onReceive(Context context, Intent intent) {
-//            if (App.CAN_PLAY_GAME && LoginController.getInstance().getCurrentLoginInfo() != null && !LoginController.getInstance().isCurrentUserAdmin())
-//                new SimpleRequest<ResGameInfo>().request(context, GameController.getInstance().needPlayGame(), new SimpleRequest.Executor<ResGameInfo>() {
-//                    @Override
-//                    public void execute(ResGameInfo obj) {
-//                        if (App.CAN_PLAY_GAME && obj != null && obj.needDoGame){
-//                            RingActivity.LAUNCH(App.app, obj);
-//                        }
-//                    }
-//                });
-//        }
-//    };
+    private boolean mRequesting = false;
 
     private Handler mHandler = new Handler(new Handler.Callback() {
         @Override
         public boolean handleMessage(@NonNull Message message) {
-            if (App.CAN_PLAY_GAME && LoginController.getInstance().getCurrentLoginInfo() != null && !LoginController.getInstance().isCurrentUserAdmin())
+            if (LoginController.getInstance().inTheTestPeriod() && System.currentTimeMillis() >= (App.LAST_TIME_CHECK_LOW_POWER + App.CHECK_TIME) && PhoneUtils.getBatteryLevel(App.app) <= 20){
+                AlertActivity.LAUNCH(App.app, "你好,\n當前電量低於20%\n請及時充電!");
+                App.LAST_TIME_CHECK_LOW_POWER = System.currentTimeMillis();
+            }else if (LoginController.getInstance().inTheTestPeriod() && System.currentTimeMillis() >= (App.LAST_TIME_CHECK_NO_NET_WORK + App.CHECK_TIME) && !PhoneUtils.isNetworkConnected(App.app)){
+                AlertActivity.LAUNCH(App.app, "你好,\n當前手機已斷網,\n請盡快連接網絡!");
+                App.LAST_TIME_CHECK_NO_NET_WORK = System.currentTimeMillis();
+            }else if (App.CAN_PLAY_GAME && LoginController.getInstance().getCurrentLoginInfo() != null && !LoginController.getInstance().isCurrentUserAdmin() && !mRequesting) {
+                mRequesting = true;
                 new SimpleRequest<ResGameInfo>().request(App.app, GameController.getInstance().needPlayGame(), new SimpleRequest.Executor<ResGameInfo>() {
                     @Override
                     public void execute(ResGameInfo obj) {
                         if (App.CAN_PLAY_GAME && obj != null && obj.needDoGame) {
+                            Logger.i("need play game or fill scale");
                             RingActivity.LAUNCH(App.app, obj);
                         }
+                        mRequesting = false;
+                    }
+                }, new SimpleRequest.Executor<Throwable>() {
+                    @Override
+                    public void execute(Throwable obj) {
+                        mRequesting = false;
                     }
                 });
+            }
 
             return true;
         }
@@ -73,19 +83,16 @@ public class GameService extends Service {
     @Override
     public void onCreate() {
         super.onCreate();
-//        IntentFilter intentFilter = new IntentFilter();
-//        intentFilter.addAction(Intent.ACTION_TIME_TICK);
-//        registerReceiver(mReceiver, intentFilter);
-        PowerManager pm = (PowerManager) this.getSystemService(
-                Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK
-                        | PowerManager.ON_AFTER_RELEASE,
-                "three_game:weak_lock");
+
+        startForeground(2, NotificationUtils.GET_NOTIFICATION(this, "Three Games", "Connected"));
+
+        PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = mPowerManager.newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, "Three_games:weak_lock");
         mWakeLock.acquire();
 
-        WifiManager wMgr = (WifiManager) this.getSystemService(WIFI_SERVICE);
-        mWifiLock = wMgr.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "three_game:wifi_lock");
+        WifiManager mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
+        mWifiLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "three_games:wifi_lock");
         mWifiLock.acquire();
 
         mTimer = new Timer();
@@ -94,19 +101,21 @@ public class GameService extends Service {
             public void run() {
                 mHandler.sendEmptyMessage(0);
             }
-        }, 0, 10 * 1000);
+        }, 0, 20 * 1000);
+
     }
 
     @Override
     public void onDestroy() {
-//        unregisterReceiver(mReceiver);
         if (mTimer != null)
             mTimer.cancel();
+
         if (mWakeLock != null)
             mWakeLock.release();
 
         if (mWifiLock != null)
             mWifiLock.release();
+
         super.onDestroy();
     }
 }

+ 118 - 0
app/src/main/java/com/jyc/threegames/utils/NotificationUtils.java

@@ -0,0 +1,118 @@
+package com.jyc.threegames.utils;
+
+import android.app.AppOpsManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
+
+import androidx.core.app.NotificationCompat;
+
+import com.jyc.threegames.R;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import static android.content.Context.NOTIFICATION_SERVICE;
+
+public class NotificationUtils {
+    public static Notification GET_NOTIFICATION(Context context, String tittle, String body){
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+            NotificationChannel channel =new NotificationChannel("three_game_important",
+            "three_game", NotificationManager.IMPORTANCE_HIGH);
+//            channel.enableLights(true);
+//            channel.setLightColor(Color.RED);
+//            channel.setShowBadge(true);
+            ((NotificationManager)context.getSystemService(NOTIFICATION_SERVICE)).createNotificationChannel(channel);
+        }
+
+        NotificationCompat.Builder build = new NotificationCompat.Builder(context, "three_game_important");
+        build.setContentTitle(tittle);
+        build.setContentText(body);
+        build.setTicker(tittle);
+//        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+//            build.setPriority(NotificationManager.IMPORTANCE_MAX);
+//        else
+//            build.setPriority(Notification.PRIORITY_HIGH);
+//        build.setAutoCancel(true);
+//        build.setWhen(System.currentTimeMillis());
+//        build.setDefaults(Notification.DEFAULT_ALL);
+        build.setSmallIcon(R.mipmap.ic_launcher);
+//        build.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher));
+
+        return build.build();
+    }
+
+    private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
+    private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
+
+    public static boolean IS_NOTIFICATION_ENABLE(Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            ///< 8.0手机以上
+            if (((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).getImportance() == NotificationManager.IMPORTANCE_NONE) {
+                return false;
+            }
+        }
+
+        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        ApplicationInfo appInfo = context.getApplicationInfo();
+        String pkg = context.getApplicationContext().getPackageName();
+        int uid = appInfo.uid;
+
+        Class appOpsClass = null;
+        try {
+            appOpsClass = Class.forName(AppOpsManager.class.getName());
+            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
+                    String.class);
+            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
+
+            int value = (Integer) opPostNotificationValue.get(Integer.class);
+            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    public static void REQUEST_NOTIFY(Context context) {
+        /**
+         * 跳到通知栏设置界面
+         * @param context
+         */
+        Intent localIntent = new Intent();
+        ///< 直接跳转到应用通知设置的代码
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            localIntent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+            localIntent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
+        }
+        else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+                android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            localIntent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
+            localIntent.putExtra("app_package", context.getPackageName());
+            localIntent.putExtra("app_uid", context.getApplicationInfo().uid);
+        } else if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
+            localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+            localIntent.addCategory(Intent.CATEGORY_DEFAULT);
+            localIntent.setData(Uri.parse("package:" + context.getPackageName()));
+        } else {
+            ///< 4.4以下没有从app跳转到应用通知设置页面的Action,可考虑跳转到应用详情页面,
+            localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            if (Build.VERSION.SDK_INT >= 9) {
+                localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
+                localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
+            } else if (Build.VERSION.SDK_INT <= 8) {
+                localIntent.setAction(Intent.ACTION_VIEW);
+                localIntent.setClassName("com.android.settings", "com.android.setting.InstalledAppDetails");
+                localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
+            }
+        }
+        context.startActivity(localIntent);
+    }
+}

+ 29 - 0
app/src/main/java/com/jyc/threegames/utils/PhoneUtils.java

@@ -0,0 +1,29 @@
+package com.jyc.threegames.utils;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.BatteryManager;
+import android.os.Build;
+
+public class PhoneUtils {
+    public static int getBatteryLevel(Context context){
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
+            return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
+        }
+        return 0;
+    }
+
+    public static boolean isNetworkConnected(Context context) {
+        if (context != null) {
+            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
+                    .getSystemService(Context.CONNECTIVITY_SERVICE);
+            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
+            if (mNetworkInfo != null) {
+                return mNetworkInfo.isAvailable();
+            }
+        }
+        return false;
+    }
+}

+ 23 - 0
app/src/main/java/com/jyc/threegames/utils/ToastUtil.java

@@ -0,0 +1,23 @@
+package com.jyc.threegames.utils;
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.jyc.threegames.R;
+
+public class ToastUtil {
+    public static void showToast(Context context, String text){
+        View view= LayoutInflater.from(context).inflate(R.layout.toast, null);
+        TextView tv_msg = view.findViewById(R.id.tvToast);
+        tv_msg.setText(text);
+        Toast toast = new Toast(context);
+        toast.setGravity(Gravity.CENTER, 0, 0);
+        toast.setDuration(Toast.LENGTH_LONG);
+        toast.setView(view);
+        toast.show();
+    }
+}

+ 31 - 0
app/src/main/res/layout/activity_alert.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <TextView
+        android:id="@+id/label"
+        android:textColor="#000"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/sure"
+        app:layout_constraintVertical_chainStyle="packed"
+        android:textSize="25sp"
+        android:gravity="center"
+        android:textStyle="bold" />
+    <Button
+        android:id="@+id/sure"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="確定"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:layout_marginTop="20dp"
+        app:layout_constraintTop_toBottomOf="@id/label"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:background="@android:color/holo_green_light"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 6 - 6
app/src/main/res/layout/activity_game_one.xml

@@ -74,7 +74,7 @@
             android:id="@+id/view_form_question_one"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:textSize="15sp"
+            android:textSize="20sp"
             android:textColor="#CC000000"
             android:textStyle="bold"
             android:text="你覺得你答對了百分之多少?"
@@ -89,7 +89,7 @@
             android:id="@+id/view_form_question_two"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:textSize="15sp"
+            android:textSize="20sp"
             android:textColor="#CC000000"
             android:textStyle="bold"
             android:text="你對以上的判斷有百分之幾的把握?"
@@ -104,12 +104,12 @@
             style="@style/NumberPicker.EditTextStyle"
             app:layout_constraintEnd_toEndOf="parent"
             android:layout_marginEnd="10dp"
-            android:layout_marginTop="30dp"
+            android:layout_marginTop="40dp"
             app:layout_constraintTop_toBottomOf="@+id/view_form_title"
             app:picker_max="100"
             app:picker_min="0"
             android:progress="100"
-            app:picker_stepSize="10"
+            app:picker_stepSize="1"
             app:picker_tracker="exponential"
             app:picker_orientation="vertical"
             android:id="@+id/right"
@@ -120,12 +120,12 @@
             style="@style/NumberPicker.EditTextStyle"
             app:layout_constraintEnd_toEndOf="parent"
             android:layout_marginEnd="10dp"
-            android:layout_marginTop="20dp"
+            android:layout_marginTop="40dp"
             app:layout_constraintTop_toBottomOf="@+id/right"
             app:picker_max="100"
             app:picker_min="0"
             android:progress="100"
-            app:picker_stepSize="10"
+            app:picker_stepSize="1"
             app:picker_tracker="exponential"
             app:picker_orientation="vertical"
             android:id="@+id/grasp"

+ 2 - 0
app/src/main/res/layout/activity_normal_user.xml

@@ -41,6 +41,8 @@
         android:layout_height="wrap_content"
         android:id="@+id/view_list_title"
         android:text="逾期量表"
+        android:textColor="#000"
+        android:textSize="20sp"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toBottomOf="@id/toolbar"/>

+ 189 - 33
app/src/main/res/layout/activity_ring.xml

@@ -1,42 +1,198 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:keepScreenOn="true"
     xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/root_ring"
+        android:visibility="visible"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <TextView
+            android:id="@+id/label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="您需要做遊戲啦"
+            android:textColor="#000"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:textSize="30sp"
+            app:layout_constraintVertical_bias="0.3"/>
+
+        <Button
+            android:id="@+id/push_back"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:text="推遲"
+            android:textColor="#fff"
+            android:background="@android:color/holo_green_light"
+            app:layout_constraintWidth_percent="0.8"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/label"
+            android:textSize="30sp"
+            android:layout_marginTop="60dp"/>
+
+        <Button
+            android:id="@+id/now"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:text="現在就做"
+            android:textColor="#fff"
+            android:background="@android:color/holo_green_light"
+            app:layout_constraintWidth_percent="0.8"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:textSize="30sp"
+            app:layout_constraintTop_toBottomOf="@id/push_back"
+            android:layout_marginTop="30dp"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/root_delay"
+        android:visibility="gone"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:textSize="22sp"
+            android:textColor="#000"
+            android:layout_marginTop="30dp"
+            android:gravity="center"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:id="@+id/delay_title"
+            app:layout_constraintTop_toTopOf="parent"
+            android:textStyle="bold"
+            android:text="請選擇延遲的時間"/>
+        <RadioGroup
+            android:id="@+id/delay_group"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="20dp"
+            app:layout_constraintTop_toBottomOf="@id/delay_title">
+            <RadioButton
+                android:id="@+id/delay_5"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:checked="true"
+                android:textColor="#000"
+                android:text="5分鐘"/>
+            <RadioButton
+                android:id="@+id/delay_10"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:textColor="#000"
+                android:text="10分鐘"/>
+            <RadioButton
+                android:id="@+id/delay_15"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:textColor="#000"
+                android:text="15分鐘"/>
+            <RadioButton
+                android:id="@+id/delay_20"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:textColor="#000"
+                android:text="20分鐘"/>
+            <RadioButton
+                android:id="@+id/delay_25"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:textColor="#000"
+                android:text="25分鐘"/>
+            <RadioButton
+                android:id="@+id/delay_30"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:textColor="#000"
+                android:text="30分鐘"/>
+            <RadioButton
+                android:id="@+id/delay_no"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25sp"
+                android:textColor="#000"
+                android:text="取消延遲,馬上進入"/>
+        </RadioGroup>
+        <Button
+            android:id="@+id/sure"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="確定"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="20dp"
+            app:layout_constraintTop_toBottomOf="@id/delay_group"
+            android:background="@android:color/holo_green_light"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/root_over_time_scale"
+        android:visibility="gone"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <TextView
+            android:id="@+id/scale_title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="50dp"
+            android:layout_marginEnd="50dp"
+            android:text="您需要填寫量表啦\n\n這次填寫量表提示是今日最後一次提示!\n\n如現在不方便填寫,\b請在逾期量表列表中補填量表"
+            android:textColor="#000"
+            android:textStyle="bold"
+            android:layout_marginTop="30dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            android:textSize="27sp" />
+
+        <Button
+            android:id="@+id/do_it_now"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="現在就做"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="20dp"
+            android:textSize="20sp"
+            app:layout_constraintTop_toBottomOf="@id/scale_title"
+            android:background="@android:color/holo_green_light"/>
+
+        <Button
+            android:id="@+id/do_it_later"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="現不方便做"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="20dp"
+            android:textSize="20sp"
+            app:layout_constraintTop_toBottomOf="@id/do_it_now"
+            android:background="@android:color/holo_green_light"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
     <TextView
-        android:id="@+id/label"
+        android:id="@+id/hint"
+        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="您需要做遊戲啦"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        android:textSize="30sp"
-        app:layout_constraintVertical_bias="0.3"/>
-
-    <Button
-        android:id="@+id/push_back"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:text="推遲"
-        app:layout_constraintWidth_percent="0.8"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/label"
-        android:textSize="30sp"
-        android:layout_marginTop="60dp"/>
+        android:layout_gravity="center"
+        android:text="您選擇的延遲時間已超過\n該時間段結束前10分鐘,\n\n該時間段前10分鐘,\n不能進入該時間段的測試"
+        android:background="@drawable/border"
+        android:textSize="25sp"
+        android:textStyle="bold"
+        android:padding="10dp" />
 
-    <Button
-        android:id="@+id/now"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:text="現在就做"
-        app:layout_constraintWidth_percent="0.8"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        android:textSize="30sp"
-        app:layout_constraintTop_toBottomOf="@id/push_back"
-        android:layout_marginTop="30dp"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
+</FrameLayout>

+ 40 - 11
app/src/main/res/layout/activity_scale.xml

@@ -23,25 +23,43 @@
             android:layout_gravity="center"
             android:textSize="20sp"
             android:textStyle="bold"/>
-
-        <TextView
-            android:id="@+id/save"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="end"
-            android:textSize="14sp"
-            android:text="保存"
-            android:layout_marginEnd="10dp"
-            android:textStyle="bold"/>
     </androidx.appcompat.widget.Toolbar>
 
+
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/toolbar"
+        android:layout_gravity="center"
+        android:textSize="20sp"
+        android:textColor="#000"
+        android:textStyle="bold"/>
+
+    <TextView
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:textSize="22sp"
+        android:textColor="#000"
+        android:layout_marginTop="10dp"
+        android:layout_marginStart="40dp"
+        android:layout_marginEnd="40dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:id="@+id/view_form_title_desc"
+        app:layout_constraintTop_toBottomOf="@id/date"
+        android:textStyle="bold"
+        android:text="請在以下每個項目內選擇開始的時間,如果你沒有進行該項活動,請選擇“沒做”"/>
+
     <ScrollView
         android:layout_width="0dp"
         android:layout_height="0dp"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/toolbar">
+        app:layout_constraintTop_toBottomOf="@id/view_form_title_desc">
         <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
@@ -204,6 +222,17 @@
                 app:layout_constraintTop_toTopOf="@id/view_title_sleep"
                 app:layout_constraintBottom_toBottomOf="@id/sleep"/>
 
+            <Button
+                android:id="@+id/sure"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="確定"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_marginTop="20dp"
+                app:layout_constraintTop_toBottomOf="@id/sleep"
+                android:background="@android:color/holo_green_light"/>
+
         </androidx.constraintlayout.widget.ConstraintLayout>
     </ScrollView>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 21 - 0
app/src/main/res/layout/toast.xml

@@ -0,0 +1,21 @@
+<?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">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:orientation="horizontal"
+        android:background="@android:color/darker_gray"
+        android:gravity="center"
+        android:padding="20dp"
+        android:layout_height="match_parent">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:id="@+id/tvToast"
+            android:text="Toast"
+            android:textSize="35sp"
+            android:textColor="#fff"
+            android:layout_height="wrap_content"/>
+    </LinearLayout>
+</LinearLayout>

BIN
app/src/main/res/raw/test.mp3