Commit a74cd439fe43426688169e98263f014650214854

Authored by 杨帅
1 parent 85acdb87

1 优化电源白名单与GPS权限在安卓6.0以下的判断逻辑

2 修改赛事详情页各项权限被用户拒绝后的处理逻辑
3 用户赛事详情页及路径工具详情页增加二级标题显示
4 修改用户赛事详情页以及路径工具中的赛事详情页为网页图文展示方式
5 实现卡路里相关数据计算
6 优化起点终点相同时,点击开始会提示结束弹框的问题
7 修复当字体调到最大时,赛事结束页UI显示异常问题
8 修复部分机型在赛事结束页中相关提示标签遮挡问题
9 修复在无网络切换到有网时,赛事详情页小概率消失问题
Showing 54 changed files with 1959 additions and 162 deletions
app/src/main/java/com/example/modulepedometer/MainActivity.java
... ... @@ -2,6 +2,7 @@ package com.example.modulepedometer;
2 2  
3 3 import android.content.Intent;
4 4 import android.os.Bundle;
  5 +import android.support.v4.content.ContextCompat;
5 6 import android.support.v7.app.AppCompatActivity;
6 7 import android.text.TextUtils;
7 8 import android.view.View;
... ... @@ -13,11 +14,13 @@ import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
13 14 import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
14 15 import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
15 16 import com.cnlive.libs.base.util.AlertUtil;
  17 +import com.cnlive.moudle.calorie.service.CalorieService;
16 18 import com.cnlive.moudle.collectionTrace.ui.activity.CollRunRaceDetailActivity;
17 19 import com.cnlive.moudle.collectionTrace.ui.activity.CollRunningFinishActivity;
18 20 import com.cnlive.moudle.collectionTrace.ui.activity.RaceListActivity;
19 21 import com.cnlive.moudle.collectionTrace.ui.activity.RaceNameListActivity;
20 22 import com.cnlive.moudle.pedometer.model.Constant;
  23 +import com.cnlive.moudle.pedometer.service.KeepLiveService;
21 24 import com.cnlive.moudle.pedometer.ui.activity.MyRecordActivity;
22 25 import com.cnlive.moudle.pedometer.ui.activity.RunLineActivity;
23 26 import com.cnlive.moudle.pedometer.ui.activity.SelfRecordActivity;
... ... @@ -54,6 +57,13 @@ public class MainActivity extends AppCompatActivity {
54 57 }
55 58 });
56 59  
  60 + findViewById(R.id.tool3).setOnClickListener(new View.OnClickListener() {
  61 + @Override
  62 + public void onClick(View v) {
  63 + Intent intent = new Intent(MainActivity.this, CalorieService.class);
  64 + ContextCompat.startForegroundService(MainActivity.this, intent); }
  65 + });
  66 +
57 67 // MyMapUtil.getGeoCoderResult(new LatLng(39.934805, 116.308686), new MyMapUtil.GeoCodeResult() {
58 68 // @Override
59 69 // public void success(String address) {
... ...
app/src/main/res/layout/activity_main.xml
... ... @@ -27,4 +27,11 @@
27 27 android:layout_height="wrap_content"
28 28 android:layout_margin="10dp"
29 29 android:text="我的记录" />
  30 +
  31 + <Button
  32 + android:id="@+id/tool3"
  33 + android:layout_width="match_parent"
  34 + android:layout_height="wrap_content"
  35 + android:layout_margin="10dp"
  36 + android:text="卡路里" />
30 37 </LinearLayout>
31 38 \ No newline at end of file
... ...
build.gradle
... ... @@ -44,8 +44,8 @@ task clean(type: Delete) {
44 44  
45 45 ext {
46 46 def versionMajor = 1
47   - def versionMinor = 0
48   - def versionPatch = 0
  47 + def versionMinor = 6
  48 + def versionPatch = 1
49 49 def versionBuild = 0
50 50 // module依赖库公共版本号
51 51 versionCode = versionMajor * 1000 + versionMinor * 100 + versionPatch * 10 + versionBuild
... ... @@ -106,4 +106,6 @@ ext {
106 106 //视频库
107 107 libVideoQiniu = '1.0.6'
108 108 libMediaPicker = '1.5.1'
  109 + //loading动画
  110 + avi='2.1.3'
109 111 }
... ...
moudle_pedometer/build.gradle
... ... @@ -111,7 +111,7 @@ dependencies {
111 111  
112 112 implementation project(':library_baidumap')
113 113 //加载动画
114   - implementation 'com.wang.avi:library:2.1.3'
  114 + implementation "com.wang.avi:library:$rootProject.avi"
115 115 implementation "com.cnlive.libs:video_qiniu:$rootProject.libVideoQiniu"
116 116 //七牛上传
117 117 implementation "com.qiniu:qiniu-android-sdk:$rootProject.qiniuAndroidSdk"
... ...
moudle_pedometer/src/main/AndroidManifest.xml
... ... @@ -253,6 +253,14 @@
253 253 android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
254 254 android:launchMode="singleTask"
255 255 android:screenOrientation="portrait" />
  256 + <!--************************************************卡路里**********************************************-->
  257 +
  258 + <service
  259 + android:name="com.cnlive.moudle.calorie.service.CalorieService"
  260 + android:enabled="true"
  261 + android:exported="true"
  262 + android:priority="1000"
  263 + android:process=":alive" />
256 264 </application>
257 265  
258 266 </manifest>
259 267 \ No newline at end of file
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/calorie/service/CalorieService.java 0 → 100644
  1 +package com.cnlive.moudle.calorie.service;
  2 +
  3 +import android.annotation.SuppressLint;
  4 +import android.app.Notification;
  5 +import android.app.NotificationChannel;
  6 +import android.app.NotificationManager;
  7 +import android.app.PendingIntent;
  8 +import android.app.Service;
  9 +import android.content.BroadcastReceiver;
  10 +import android.content.ComponentName;
  11 +import android.content.Context;
  12 +import android.content.Intent;
  13 +import android.content.IntentFilter;
  14 +import android.hardware.Sensor;
  15 +import android.hardware.SensorEvent;
  16 +import android.hardware.SensorEventListener;
  17 +import android.hardware.SensorManager;
  18 +import android.os.Binder;
  19 +import android.os.Build;
  20 +import android.os.CountDownTimer;
  21 +import android.os.Handler;
  22 +import android.os.IBinder;
  23 +import android.support.v4.app.NotificationCompat;
  24 +import android.text.TextUtils;
  25 +import android.util.Log;
  26 +import android.widget.RemoteViews;
  27 +
  28 +import com.baidu.trace.LBSTraceClient;
  29 +import com.baidu.trace.Trace;
  30 +import com.baidu.trace.api.track.LatestPoint;
  31 +import com.baidu.trace.api.track.LatestPointResponse;
  32 +import com.baidu.trace.api.track.OnTrackListener;
  33 +import com.baidu.trace.model.LocationMode;
  34 +import com.baidu.trace.model.OnTraceListener;
  35 +import com.baidu.trace.model.PushMessage;
  36 +import com.baidu.trace.model.StatusCodes;
  37 +import com.cnlive.moudle.calorie.utils.CalorieUtil;
  38 +import com.cnlive.moudle.collectionTrace.commonInfo.CollCommonInfo;
  39 +import com.cnlive.moudle.collectionTrace.service.CollKeepLiveService;
  40 +import com.cnlive.moudle.collectionTrace.utils.CollStepUtil;
  41 +import com.cnlive.moudle.pedometer.commonInfo.CommonInfo;
  42 +import com.cnlive.moudle.pedometer.model.Constant;
  43 +import com.cnlive.moudle.pedometer.model.MessageEvent;
  44 +import com.cnlive.moudle.pedometer.model.step.StepCount;
  45 +import com.cnlive.moudle.pedometer.model.step.StepValuePassListener;
  46 +import com.cnlive.moudle.pedometer.sql.db.DbCore;
  47 +import com.cnlive.moudle.pedometer.sql.entity.CalorieEntity;
  48 +import com.cnlive.moudle.pedometer.sql.entity.CollUserStepEntity;
  49 +import com.cnlive.moudle.pedometer.utils.ServiceUtils;
  50 +import com.example.moudle_pedometer.R;
  51 +
  52 +import org.greenrobot.eventbus.EventBus;
  53 +import org.greenrobot.eventbus.Subscribe;
  54 +import org.greenrobot.eventbus.ThreadMode;
  55 +
  56 +import java.text.SimpleDateFormat;
  57 +import java.util.Date;
  58 +
  59 +/**
  60 + * 计算卡路里
  61 + *
  62 + * @author ShinnyYang
  63 + */
  64 +public class CalorieService extends Service implements SensorEventListener {
  65 +
  66 + private String TAG = "CalorieService";
  67 + /**
  68 + * 通知栏相关
  69 + */
  70 + private String CHANNEL_ONE_ID = "com.cnlive.calorie";
  71 + private String CHANNEL_ONE_NAME = "calorie";
  72 + private NotificationManager mNM;
  73 + private Notification notification = null;
  74 + private RemoteViews remoteViews;
  75 + /**
  76 + * 默认为30秒进行一次存储
  77 + */
  78 + private static int duration = 30 * 1000;
  79 + /**
  80 + * 当前的日期
  81 + */
  82 + private static String CURRENT_DATE = "";
  83 + /**
  84 + * 传感器管理对象
  85 + */
  86 + private SensorManager sensorManager;
  87 + /**
  88 + * 广播接受者
  89 + */
  90 + private BroadcastReceiver mBatInfoReceiver;
  91 + /**
  92 + * 保存记步计时器
  93 + */
  94 + private static TimeCount time;
  95 + /**
  96 + * 当前所走的步数
  97 + */
  98 + private int CURRENT_STEP = 0;
  99 + /**
  100 + * 计步传感器类型 Sensor.TYPE_STEP_COUNTER或者Sensor.TYPE_STEP_DETECTOR
  101 + */
  102 + private static int stepSensorType = -1;
  103 + /**
  104 + * 每次第一次启动记步服务时是否从系统中获取了已有的步数记录
  105 + */
  106 + private boolean hasRecord = false;
  107 + /**
  108 + * 系统中获取到的已有的步数
  109 + */
  110 + private int hasStepCount = 0;
  111 + /**
  112 + * 上一次的步数
  113 + */
  114 + private int previousStepCount = 0;
  115 + /**
  116 + * 加速度传感器中获取的步数
  117 + */
  118 + private StepCount mStepCount;
  119 + /**
  120 + * IBinder对象,向Activity传递数据的桥梁
  121 + */
  122 + private CalorieService.StepBinder stepBinder = new CalorieService.StepBinder();
  123 + private String userId;
  124 + private final int NOTIFICATION_ID = 106;
  125 + private boolean isStartForeground = false;
  126 +
  127 +
  128 + @Override
  129 + public void onCreate() {
  130 + super.onCreate();
  131 + init();
  132 +// initBroadcastReceiver();
  133 +// if (!ServiceUtils.isServiceRunning(getApplicationContext(), "com.cnlive.moudle.pedometer.service.CollKeepLiveService")) {
  134 +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  135 +// startForegroundService(new Intent(getApplicationContext(), CollKeepLiveService.class));
  136 +// } else {
  137 +// startService(new Intent(getApplicationContext(), CollKeepLiveService.class));
  138 +// }
  139 +// }
  140 + showStartForegroundNotification();
  141 + }
  142 +
  143 + private static int retryIndex = 0;
  144 +
  145 + private void initTrace() {
  146 + Log.e(TAG, "initTrace: ");
  147 +
  148 +
  149 + }
  150 +
  151 +
  152 + @SuppressLint("WrongConstant")
  153 + @Override
  154 + public int onStartCommand(Intent intent, int flags, int startId) {
  155 +
  156 + if (!EventBus.getDefault().isRegistered(this)) {
  157 + EventBus.getDefault().register(this);
  158 + }
  159 + userId = CommonInfo.getUserId(getApplicationContext());
  160 + if (userId != null && !TextUtils.isEmpty(userId)) {
  161 + //初始化数据库
  162 + initTodayData(userId);
  163 + initTrace();
  164 + //显示计步通知
  165 + showStartForegroundNotification();
  166 + new Thread(new Runnable() {
  167 + @Override
  168 + public void run() {
  169 + startStepDetector();
  170 + }
  171 + }).start();
  172 + startTimeCount();
  173 + } else {
  174 + EventBus.getDefault().post(new MessageEvent(Constant.START_TRACE_GATHER_FAIL, ""));
  175 + }
  176 +
  177 + flags = START_STICKY;
  178 + return super.onStartCommand(intent, flags, startId);
  179 + }
  180 +
  181 + private void init() {
  182 + if (null == mNM) {
  183 + mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  184 + }
  185 + }
  186 +
  187 +
  188 + private void showStartForegroundNotification() {
  189 + if (null == remoteViews) {
  190 + remoteViews = new RemoteViews(getPackageName(), R.layout.custom_step_notification);
  191 + }
  192 + NotificationChannel channel = null;
  193 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  194 + channel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME,
  195 + NotificationManager.IMPORTANCE_HIGH);
  196 + channel.enableLights(false);
  197 + channel.setSound(null, null);
  198 + channel.enableVibration(false);
  199 + channel.setVibrationPattern(new long[]{0});
  200 + channel.setSound(null, null);
  201 + mNM.createNotificationChannel(channel);
  202 + }
  203 +
  204 +
  205 +// Intent notificationIntent = new Intent(this, CollRunningMapActivity.class);
  206 + notification = new NotificationCompat.Builder(this, CHANNEL_ONE_ID)
  207 +// .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, 0))
  208 + .setSmallIcon(R.mipmap.ic_launcher)
  209 + .setCustomContentView(remoteViews)
  210 + .setContentTitle(getResources().getString(R.string.app_name))
  211 + .setContentText(getResources().getString(R.string.step_service_tip))
  212 + .setCategory(Notification.CATEGORY_SERVICE)
  213 + .setSound(null)
  214 + .setWhen(System.currentTimeMillis())
  215 + .build();
  216 + //设置步数
  217 + remoteViews.setTextViewText(R.id.tv_step_count, CURRENT_STEP + "");
  218 + remoteViews.setTextViewText(R.id.tv_calorie, CalorieUtil.getCalorie(CURRENT_STEP) + "");
  219 + //设置卡路里
  220 + startForeground(NOTIFICATION_ID, notification);
  221 + isStartForeground = true;
  222 +
  223 + }
  224 +
  225 + @Override
  226 + public IBinder onBind(Intent intent) {
  227 +
  228 +// return stepBinder;
  229 + return null;
  230 + }
  231 +
  232 +
  233 + @Override
  234 + public void onDestroy() {
  235 + super.onDestroy();
  236 + if (isStartForeground) {
  237 + //取消前台进程
  238 + stopForeground(true);
  239 + }
  240 + if (mBatInfoReceiver != null) {
  241 + unregisterReceiver(mBatInfoReceiver);
  242 + }
  243 + if (EventBus.getDefault().isRegistered(this)) {
  244 + EventBus.getDefault().unregister(this);
  245 + }
  246 + hasStepCount = 0;
  247 + hasRecord = false;
  248 + CURRENT_STEP = 0;
  249 + previousStepCount = 0;
  250 + if (sensorManager != null) {
  251 + sensorManager.unregisterListener(CalorieService.this);
  252 + sensorManager = null;
  253 + }
  254 + stepSensorType = -1;
  255 + time = null;
  256 + }
  257 +
  258 + //接收事件
  259 + @Subscribe(threadMode = ThreadMode.BACKGROUND)
  260 + public void Event(MessageEvent messageEvent) {
  261 +// //暂停计步
  262 +// if (messageEvent.getMessageType() == Constant.SERVICE_STEP_COUNT_PAUSE) {
  263 +// pauseFlag = true;
  264 +// }
  265 +// //继续计步
  266 +// else if (messageEvent.getMessageType() == Constant.SERVICE_STEP_COUNT_CONTINUE) {
  267 +// pauseFlag = false;
  268 +// }
  269 +
  270 + //更新锁屏步数
  271 + if (messageEvent.getMessageType() == Constant.COLL_SERVICE_STEP_COUNT_ONRESUME) {
  272 + updateNotification();
  273 + }
  274 +
  275 + }
  276 +
  277 + /**
  278 + * 发送重启广播
  279 + */
  280 + private void sendRestartBroadCast() {
  281 + Intent intent = new Intent(" com.cnlive.moudle.pedometer.receivers.MyReceiver");
  282 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  283 + intent.setComponent(new ComponentName(getPackageName(), " com.cnlive.moudle.pedometer.receivers.MyReceiver"));//高版本Android发送广播需要加这句
  284 + }
  285 + sendBroadcast(intent);
  286 + }
  287 +
  288 +
  289 + @Override
  290 + public void onAccuracyChanged(Sensor sensor, int i) {
  291 +
  292 + }
  293 +
  294 + /**
  295 + * @获取默认的pendingIntent,为了防止2.3及以下版本报错
  296 + * @flags属性: 在顶部常驻:Notification.FLAG_ONGOING_EVENT
  297 + * 点击去除: Notification.FLAG_AUTO_CANCEL
  298 + */
  299 + public PendingIntent getDefalutIntent(int flags) {
  300 + PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, new Intent(), flags);
  301 + return pendingIntent;
  302 + }
  303 +
  304 + /**
  305 + * 获取当天日期
  306 + *
  307 + * @return
  308 + */
  309 + private String getTodayDate() {
  310 + Date date = new Date(System.currentTimeMillis());
  311 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  312 + return sdf.format(date);
  313 + }
  314 +
  315 + /**
  316 + * 初始化当天的步数
  317 + */
  318 + private void initTodayData(String userId) {
  319 + CURRENT_DATE = getTodayDate();
  320 + if (userId == null || CURRENT_DATE == null) {
  321 + return;
  322 + }
  323 + //获取当天的数据,用于展示 CURRENT_DATE
  324 + CalorieEntity calorieEntity = CalorieUtil.getUserCalorieData(getApplicationContext(), userId, getTodayDate());
  325 + if (null == calorieEntity) {
  326 + CURRENT_STEP = 0;
  327 + } else {
  328 + if (calorieEntity.getStep() != null && !TextUtils.isEmpty(calorieEntity.getStep())) {
  329 + CURRENT_STEP = Integer.parseInt(calorieEntity.getStep());
  330 + }
  331 + }
  332 +// Log.e(TAG, "initTodayData: 初始化当前步数" + CURRENT_STEP);
  333 + if (mStepCount != null) {
  334 + mStepCount.setSteps(CURRENT_STEP);
  335 + }
  336 + updateNotification();
  337 + }
  338 +
  339 + private void updateNotification() {
  340 + save();
  341 + showStartForegroundNotification();
  342 +// Log.e(TAG, "updateNotification: 当前步数:" + CURRENT_STEP);
  343 + EventBus.getDefault().post(new MessageEvent(Constant.COLL_SERVICE_STEP_COUNT_UPDATE, CURRENT_STEP));
  344 +// remoteViews = new RemoteViews(getPackageName(), R.layout.custom_step_notification);
  345 +// NotificationChannel channel = null;
  346 +// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
  347 +// channel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME,
  348 +// NotificationManager.IMPORTANCE_HIGH);
  349 +// channel.enableLights(false);
  350 +// channel.setSound(null, null);
  351 +// channel.enableVibration(false);
  352 +// channel.setVibrationPattern(new long[]{0});
  353 +// channel.setSound(null, null);
  354 +// mNM.createNotificationChannel(channel);
  355 +// }
  356 +// Intent notificationIntent = new Intent(this, CollPedometerMainActivity.class);
  357 +// notification = new NotificationCompat.Builder(this, CHANNEL_ONE_ID)
  358 +// .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, 0))
  359 +// .setSmallIcon(R.mipmap.ic_launcher)
  360 +// .setCustomContentView(remoteViews)
  361 +// .setSound(null)
  362 +// .setCategory(Notification.CATEGORY_SERVICE)
  363 +// .setWhen(System.currentTimeMillis())
  364 +// .build();
  365 +// remoteViews.setTextViewText(R.id.tv_step_count, CURRENT_STEP + "");
  366 +// remoteViews.setChronometer(R.id.ch, aa, null, true);
  367 +//
  368 +// mNM.notify(1, notification);
  369 + }
  370 +
  371 +
  372 +// private void updateNotification(long i) {
  373 +// remoteViews = new RemoteViews(getPackageName(), R.layout.custom_step_notification);
  374 +// NotificationChannel channel = null;
  375 +// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
  376 +// channel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME,
  377 +// NotificationManager.IMPORTANCE_HIGH);
  378 +// channel.enableLights(false);
  379 +// channel.setSound(null, null);
  380 +//// channel.setLightColor(getColor(R.color.colorPrimary));
  381 +// channel.enableVibration(false);
  382 +// channel.setVibrationPattern(new long[]{0});
  383 +// channel.setSound(null, null);
  384 +// mNM.createNotificationChannel(channel);
  385 +// }
  386 +//
  387 +// Intent notificationIntent = new Intent(this, CollPedometerMainActivity.class);
  388 +// notification = new NotificationCompat.Builder(this, CHANNEL_ONE_ID)
  389 +// .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, 0))
  390 +// .setSmallIcon(R.mipmap.ic_launcher)
  391 +//// .setContentText("前台服务正在运行")
  392 +//// .setContentTitle("标题")
  393 +// .setCustomContentView(remoteViews)
  394 +// .setSound(null)
  395 +// .setWhen(System.currentTimeMillis())
  396 +// .build();
  397 +// remoteViews.setTextViewText(R.id.tv_time, getFormatHMS(i));
  398 +// remoteViews.setTextViewText(R.id.tv_step_count, CURRENT_STEP + "");
  399 +// mNM.notify(1, notification);
  400 +// }
  401 +
  402 + /**
  403 + * 注册广播
  404 + */
  405 + private void initBroadcastReceiver() {
  406 + final IntentFilter filter = new IntentFilter();
  407 + // 屏幕灭屏广播
  408 + filter.addAction(Intent.ACTION_SCREEN_OFF);
  409 + //关机广播
  410 + filter.addAction(Intent.ACTION_SHUTDOWN);
  411 + // 屏幕亮屏广播
  412 + filter.addAction(Intent.ACTION_SCREEN_ON);
  413 + // 屏幕解锁广播
  414 +// filter.addAction(Intent.ACTION_USER_PRESENT);
  415 + // 当长按电源键弹出“关机”对话或者锁屏时系统会发出这个广播
  416 + // example:有时候会用到系统对话框,权限可能很高,会覆盖在锁屏界面或者“关机”对话框之上,
  417 + // 所以监听这个广播,当收到时就隐藏自己的对话,如点击pad右下角部分弹出的对话框
  418 + filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
  419 + //监听日期变化
  420 + filter.addAction(Intent.ACTION_DATE_CHANGED);
  421 + filter.addAction(Intent.ACTION_TIME_CHANGED);
  422 + filter.addAction(Intent.ACTION_TIME_TICK);
  423 + filter.addAction("close.CollStepService");
  424 + mBatInfoReceiver = new BroadcastReceiver() {
  425 + @Override
  426 + public void onReceive(final Context context, final Intent intent) {
  427 + String action = intent.getAction();
  428 + if (Intent.ACTION_SCREEN_ON.equals(action)) {
  429 + startStepDetector();
  430 + Log.d(TAG, "screen on");
  431 + } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
  432 + startStepDetector();
  433 + Log.d(TAG, "screen off");
  434 + //改为60秒一存储
  435 + duration = 60000;
  436 + } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
  437 + Log.d(TAG, "screen unlock");
  438 + save();
  439 + //改为30秒一存储
  440 + duration = 30000;
  441 + } else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
  442 + Log.i(TAG, " receive Intent.ACTION_CLOSE_SYSTEM_DIALOGS");
  443 + //保存一次
  444 + save();
  445 + } else if (Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
  446 + Log.i(TAG, " receive ACTION_SHUTDOWN");
  447 + save();
  448 + } else if (Intent.ACTION_DATE_CHANGED.equals(action)) {//日期变化步数重置为0
  449 +// Logger.d("重置步数" + StepDcretor.CURRENT_STEP);
  450 + save();
  451 + isNewDay();
  452 + } else if (Intent.ACTION_TIME_CHANGED.equals(action)) {
  453 + //时间变化步数重置为0
  454 +// isCall();
  455 + save();
  456 + isNewDay();
  457 + } else if (Intent.ACTION_TIME_TICK.equals(action)) {//日期变化步数重置为0
  458 +// isCall();
  459 +// Logger.d("重置步数" + StepDcretor.CURRENT_STEP);
  460 + save();
  461 + isNewDay();
  462 + } else if ("close.CollStepService".equals(action)) {
  463 + Log.e("关闭StepService", "关闭");
  464 + onDestroy();
  465 + stopSelf();
  466 + }
  467 + }
  468 + };
  469 + registerReceiver(mBatInfoReceiver, filter);
  470 + }
  471 +
  472 + /**
  473 + * 获取当前步数
  474 + *
  475 + * @return
  476 + */
  477 + public int getStepCount() {
  478 + return CURRENT_STEP;
  479 + }
  480 +
  481 + /**
  482 + * 监听晚上0点变化初始化数据
  483 + */
  484 + private void isNewDay() {
  485 + String time = "00:00";
  486 + CalorieEntity calorieEntity = new CalorieEntity();
  487 + calorieEntity.setUuid(CalorieUtil.getUUID());
  488 + calorieEntity.setUserId(userId);
  489 + calorieEntity.setCurrentDate(getTodayDate());
  490 + CalorieUtil.insertData(getApplicationContext(), calorieEntity);
  491 + if (time.equals(new SimpleDateFormat("HH:mm").format(new Date())) || !CURRENT_DATE.equals(getTodayDate())) {
  492 + initTodayData(userId);
  493 + }
  494 + }
  495 +
  496 +// /**
  497 +// * 监听时间变化提醒用户锻炼
  498 +// */
  499 +// private void isCall() {
  500 +// String time = this.getSharedPreferences("share_date", Context.MODE_MULTI_PROCESS).getString("achieveTime", "21:00");
  501 +// String plan = this.getSharedPreferences("share_date", Context.MODE_MULTI_PROCESS).getString("planWalk_QTY", "7000");
  502 +// String remind = this.getSharedPreferences("share_date", Context.MODE_MULTI_PROCESS).getString("remind", "1");
  503 +// Logger.d("time=" + time + "\n" +
  504 +// "new SimpleDateFormat(\"HH: mm\").format(new Date()))=" + new SimpleDateFormat("HH:mm").format(new Date()));
  505 +// if (("1".equals(remind)) &&
  506 +// (CURRENT_STEP < Integer.parseInt(plan)) &&
  507 +// (time.equals(new SimpleDateFormat("HH:mm").format(new Date())))
  508 +// ) {
  509 +// remindNotify();
  510 +// }
  511 +//
  512 +// }
  513 + /**
  514 + * 提醒锻炼通知栏
  515 + */
  516 +// private void remindNotify() {
  517 +//
  518 +// //设置点击跳转
  519 +// Intent hangIntent = new Intent(this, MainActivity.class);
  520 +// PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, hangIntent, PendingIntent.FLAG_CANCEL_CURRENT);
  521 +//
  522 +// String plan = this.getSharedPreferences("share_date", Context.MODE_MULTI_PROCESS).getString("planWalk_QTY", "7000");
  523 +// NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
  524 +// mBuilder.setContentTitle("今日步数" + CURRENT_STEP + " 步")
  525 +// .setContentText("距离目标还差" + (Integer.valueOf(plan) - CURRENT_STEP) + "步,加油!")
  526 +// .setContentIntent(hangPendingIntent)
  527 +// .setTicker(getResources().getString(R.string.app_name) + "提醒您开始锻炼了")//通知首次出现在通知栏,带上升动画效果的
  528 +// .setWhen(System.currentTimeMillis())//通知产生的时间,会在通知信息里显示
  529 +// .setPriority(Notification.PRIORITY_DEFAULT)//设置该通知优先级
  530 +// .setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
  531 +// .setOngoing(false)//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
  532 +// .setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:
  533 +// //Notification.DEFAULT_ALL Notification.DEFAULT_SOUND 添加声音 // requires VIBRATE permission
  534 +// .setSmallIcon(R.mipmap.logo);
  535 +// NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
  536 +// mNotificationManager.notify(notify_remind_id, mBuilder.build());
  537 +// }
  538 +
  539 + /**
  540 + * 获取传感器实例
  541 + */
  542 + private void startStepDetector() {
  543 + if (sensorManager != null) {
  544 + sensorManager = null;
  545 + }
  546 + // 获取传感器管理器的实例
  547 + sensorManager = (SensorManager) this
  548 + .getSystemService(SENSOR_SERVICE);
  549 + //android4.4以后可以使用计步传感器
  550 + int VERSION_CODES = Build.VERSION.SDK_INT;
  551 + if (VERSION_CODES >= 19) {
  552 + sensorManager.unregisterListener(CalorieService.this);
  553 + //注册传感器,传感器监听器的注册导致传感器电源又重新开启
  554 + addCountStepListener();
  555 + } else {
  556 + addBasePedometerListener();
  557 + }
  558 + }
  559 +
  560 + /**
  561 + * 停止传感器
  562 + */
  563 + private void stopStepDetector() {
  564 + if (sensorManager != null) {
  565 + sensorManager = null;
  566 + }
  567 + // 获取传感器管理器的实例
  568 + sensorManager = (SensorManager) this
  569 + .getSystemService(SENSOR_SERVICE);
  570 + //android4.4以后可以使用计步传感器
  571 + sensorManager.unregisterListener(CalorieService.this);
  572 + }
  573 +
  574 + /**
  575 + * 添加传感器监听
  576 + * 1. TYPE_STEP_COUNTER API的解释说返回从开机被激活后统计的步数,当重启手机后该数据归零,
  577 + * 该传感器是一个硬件传感器所以它是低功耗的。
  578 + * 为了能持续的计步,请不要反注册事件,就算手机处于休眠状态它依然会计步。
  579 + * 当激活的时候依然会上报步数。该sensor适合在长时间的计步需求。
  580 + * <p>
  581 + * 2.TYPE_STEP_DETECTOR翻译过来就是走路检测,
  582 + * API文档也确实是这样说的,该sensor只用来监监测走步,每次返回数字1.0。
  583 + * 如果需要长事件的计步请使用TYPE_STEP_COUNTER。
  584 + */
  585 + private void addCountStepListener() {
  586 + Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
  587 + Sensor detectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
  588 + if (countSensor != null) {
  589 + stepSensorType = Sensor.TYPE_STEP_COUNTER;
  590 + Log.v(TAG, "Sensor.TYPE_STEP_COUNTER");
  591 + sensorManager.registerListener(CalorieService.this, countSensor, SensorManager.SENSOR_DELAY_NORMAL);
  592 + } else if (detectorSensor != null) {
  593 + stepSensorType = Sensor.TYPE_STEP_DETECTOR;
  594 + Log.v(TAG, "Sensor.TYPE_STEP_DETECTOR");
  595 + sensorManager.registerListener(CalorieService.this, detectorSensor, SensorManager.SENSOR_DELAY_NORMAL);
  596 + } else {
  597 + Log.v(TAG, "Count sensor not available!");
  598 + addBasePedometerListener();
  599 + }
  600 + }
  601 +
  602 + /**
  603 + * 通过加速度传感器来记步
  604 + */
  605 + private void addBasePedometerListener() {
  606 + mStepCount = new StepCount();
  607 + mStepCount.setSteps(CURRENT_STEP);
  608 + // 获得传感器的类型,这里获得的类型是加速度传感器
  609 + // 此方法用来注册,只有注册过才会生效,参数:SensorEventListener的实例,Sensor的实例,更新速率
  610 + Sensor sensor = sensorManager
  611 + .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  612 + boolean isAvailable = sensorManager.registerListener(mStepCount.getStepDetector(), sensor,
  613 + SensorManager.SENSOR_DELAY_UI);
  614 + mStepCount.initListener(new StepValuePassListener() {
  615 + @Override
  616 + public void stepChanged(int steps) {
  617 + CURRENT_STEP = steps;
  618 + updateNotification();
  619 + }
  620 + });
  621 + if (isAvailable) {
  622 + Log.e(TAG, "加速度传感器可以使用");
  623 + } else {
  624 + Log.e(TAG, "加速度传感器无法使用");
  625 + }
  626 + }
  627 +
  628 + /**
  629 + * 传感器监听回调
  630 + * 记步的关键代码
  631 + * 1. TYPE_STEP_COUNTER API的解释说返回从开机被激活后统计的步数,当重启手机后该数据归零,
  632 + * 该传感器是一个硬件传感器所以它是低功耗的。
  633 + * 为了能持续的计步,请不要反注册事件,就算手机处于休眠状态它依然会计步。
  634 + * 当激活的时候依然会上报步数。该sensor适合在长时间的计步需求。
  635 + * <p>
  636 + * 2.TYPE_STEP_DETECTOR翻译过来就是走路检测,
  637 + * API文档也确实是这样说的,该sensor只用来监监测走步,每次返回数字1.0。
  638 + * 如果需要长事件的计步请使用TYPE_STEP_COUNTER。
  639 + *
  640 + * @param event
  641 + */
  642 +
  643 + @Override
  644 + public void onSensorChanged(SensorEvent event) {
  645 + //没有暂停
  646 + if (stepSensorType == Sensor.TYPE_STEP_COUNTER) {
  647 + //获取当前传感器返回的临时步数
  648 + int tempStep = (int) event.values[0];
  649 +// Log.e(TAG, "onSensorChanged: 第一次,tempStep:" + tempStep + "lastStep:" + lastStep + ",previousStepCount" + previousStepCount + ",CURRENT_STEP" + CURRENT_STEP);
  650 + //首次如果没有获取手机系统中已有的步数则获取一次系统中APP还未开始记步的步数
  651 + if (!hasRecord) {
  652 + hasRecord = true;
  653 + hasStepCount = tempStep;
  654 + previousStepCount = 0;
  655 + } else {
  656 + //获取APP打开到现在的总步数=本次系统回调的总步数-APP打开之前已有的步数
  657 +// Log.e(TAG, "tempStep: " + tempStep + ",hasStepCount:" + hasStepCount);
  658 + int thisStepCount = tempStep - hasStepCount;
  659 +// Log.e(TAG, "onSensorChanged: thisStepCount" + thisStepCount);
  660 + //本次有效步数=(APP打开后所记录的总步数-上一次APP打开后所记录的总步数)
  661 + int thisStep = thisStepCount - previousStepCount;
  662 + //记录最后一次APP打开到现在的总步数
  663 + previousStepCount = thisStepCount;
  664 +// Log.e(TAG, "onSensorChanged: CURRENT_STEP" + CURRENT_STEP);
  665 + if (CURRENT_STEP < 0) {
  666 + CURRENT_STEP = -CURRENT_STEP;
  667 + }
  668 + //总步数=现有的步数+本次有效步数
  669 + CURRENT_STEP += (thisStep);
  670 + }
  671 + } else if (stepSensorType == Sensor.TYPE_STEP_DETECTOR) {
  672 + if (event.values[0] == 1.0) {
  673 + CURRENT_STEP++;
  674 + }
  675 + }
  676 + //如果没有暂停就更新计步器
  677 + updateNotification();
  678 +
  679 + }
  680 +
  681 + /**
  682 + * 保存记步数据
  683 + */
  684 + private void save() {
  685 + int tempStep = CURRENT_STEP;
  686 + CalorieEntity calorieEntity = CalorieUtil.getUserCalorieData(getApplicationContext(), userId, getTodayDate());
  687 + if (null == calorieEntity) {
  688 + calorieEntity = new CalorieEntity();
  689 + calorieEntity.setUserId(userId);
  690 + calorieEntity.setStep(tempStep + "");
  691 + CalorieUtil.insertData(getApplicationContext(), calorieEntity);
  692 + } else {
  693 + calorieEntity.setStep(tempStep + "");
  694 + CalorieUtil.updateData(getApplicationContext(), calorieEntity);
  695 + }
  696 + }
  697 +
  698 +
  699 + /**
  700 + * 保存记步数据
  701 + */
  702 + class TimeCount extends CountDownTimer {
  703 + public TimeCount(long millisInFuture, long countDownInterval) {
  704 + super(millisInFuture, countDownInterval);
  705 + }
  706 +
  707 + @Override
  708 + public void onFinish() {
  709 + // 如果计时器正常结束,则开始计步
  710 + if (null != time) {
  711 + time.cancel();
  712 + save();
  713 + startTimeCount();
  714 + }
  715 + }
  716 +
  717 + @Override
  718 + public void onTick(long millisUntilFinished) {
  719 +
  720 + }
  721 +
  722 + }
  723 +
  724 + /**
  725 + * 根据行走步数,计算大概行走具体
  726 + * 单位:公里
  727 + * 1步的距离大概是60厘米。
  728 + * 1万多步,距离大概就是600000厘米,即6000米(6公里)
  729 + *
  730 + * @param step
  731 + * @return
  732 + */
  733 + private double getWalkDistance(long step) {
  734 + double result = step * 60.0 / 100.0 / 1000.0;
  735 + return result;
  736 + }
  737 +
  738 + /**
  739 + * 开始保存记步数据
  740 + */
  741 + private void startTimeCount() {
  742 + if (time == null) {
  743 + time = new TimeCount(duration, 1000);
  744 + }
  745 + time.start();
  746 + }
  747 +
  748 + /**
  749 + * 向Activity传递数据的纽带
  750 + */
  751 + public class StepBinder extends Binder {
  752 +
  753 + /**
  754 + * 获取当前service对象
  755 + *
  756 + * @return CollStepService
  757 + */
  758 + public CalorieService getService() {
  759 + return CalorieService.this;
  760 + }
  761 + }
  762 +
  763 + /**
  764 + * 根据毫秒返回时分秒
  765 + *
  766 + * @param time
  767 + * @return
  768 + */
  769 + public String getFormatHMS(long time) {
  770 + time = time / 1000;//总秒数
  771 + int s = (int) (time % 60);//秒
  772 + int m = (int) (time / 60) % 60;//分
  773 + int h = (int) (time / 3600) % 60;//小时
  774 + return String.format("%02d:%02d:%02d", h, m, s);
  775 + }
  776 +
  777 +
  778 +}
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/calorie/utils/CalorieUtil.java 0 → 100644
  1 +package com.cnlive.moudle.calorie.utils;
  2 +
  3 +import android.content.Context;
  4 +import android.text.TextUtils;
  5 +import android.util.Log;
  6 +
  7 +import com.cnlive.moudle.pedometer.sql.dao.CalorieEntityDao;
  8 +import com.cnlive.moudle.pedometer.sql.dao.UserStepEntityDao;
  9 +import com.cnlive.moudle.pedometer.sql.db.DbCore;
  10 +import com.cnlive.moudle.pedometer.sql.entity.CalorieEntity;
  11 +import com.cnlive.moudle.pedometer.sql.entity.UserStepEntity;
  12 +
  13 +import java.text.SimpleDateFormat;
  14 +import java.util.Date;
  15 +import java.util.List;
  16 +import java.util.UUID;
  17 +
  18 +/**
  19 + * 卡路里相关
  20 + *
  21 + * @author ShinnyYang
  22 + */
  23 +public class CalorieUtil {
  24 + private static final String TAG = "CalorieUtil";
  25 + private static final String dbName = "Step.db";
  26 +
  27 + public static String getUUID() {
  28 + return UUID.randomUUID().toString().replace("-", "");
  29 + }
  30 +
  31 + public synchronized static void updateData(Context context, CalorieEntity calorieEntity) {
  32 + try {
  33 + if (null != calorieEntity) {
  34 + DbCore.init(context, dbName);
  35 + DbCore.getDaoSession().getCalorieEntityDao().update(calorieEntity);
  36 + }
  37 + } catch (Exception e) {
  38 + Log.e(TAG, "initDataBase: " + e.toString());
  39 + }
  40 +
  41 + }
  42 +
  43 + public synchronized static void insertData(Context context, CalorieEntity calorieEntity) {
  44 + try {
  45 + if (null != calorieEntity) {
  46 + DbCore.init(context, dbName);
  47 + DbCore.getDaoSession().getCalorieEntityDao().insert(calorieEntity);
  48 + }
  49 + } catch (Exception e) {
  50 + Log.e(TAG, "initDataBase: " + e.toString());
  51 + }
  52 +
  53 + }
  54 +
  55 + public synchronized static void initDataBase(Context context, String uid, String currentDate) {
  56 + try {
  57 + if (null == getUserCalorieData(context, uid, currentDate)) {
  58 + DbCore.init(context, dbName);
  59 + CalorieEntity calorieEntity = new CalorieEntity();
  60 + calorieEntity.setUuid(getUUID());
  61 + calorieEntity.setUserId(uid);
  62 + calorieEntity.setCurrentDate(getTodayDate());
  63 + DbCore.getDaoSession().getCalorieEntityDao().insert(calorieEntity);
  64 + }
  65 + } catch (Exception e) {
  66 + Log.e(TAG, "initDataBase: " + e.toString());
  67 + }
  68 +
  69 + }
  70 +
  71 + /**
  72 + * 获取用户数据
  73 + *
  74 + * @param context
  75 + * @param uid
  76 + * @return
  77 + */
  78 + public synchronized static CalorieEntity getUserCalorieData(Context context, String uid, String currentDate) {
  79 + try {
  80 + if (!TextUtils.isEmpty(uid)) {
  81 + DbCore.init(context, dbName);
  82 + List<CalorieEntity> list = DbCore.getDaoSession().getCalorieEntityDao().queryBuilder().where(CalorieEntityDao.Properties.UserId.eq(uid), CalorieEntityDao.Properties.CurrentDate.eq(currentDate)).list();
  83 + if (list != null && list.size() > 0) {
  84 + return list.get(0);
  85 + } else {
  86 + return null;
  87 + }
  88 + } else {
  89 + return null;
  90 + }
  91 + } catch (Exception e) {
  92 + Log.e(TAG, "getUserCalorieData: " + e.toString());
  93 + return null;
  94 + }
  95 +
  96 + }
  97 +
  98 + /**
  99 + * 获取当天日期
  100 + *
  101 + * @return
  102 + */
  103 + public static String getTodayDate() {
  104 + Date date = new Date(System.currentTimeMillis());
  105 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  106 + return sdf.format(date);
  107 + }
  108 +
  109 + /**
  110 + * 根据行走步数,计算大概行走具体
  111 + * 单位:公里
  112 + * 1步的距离大概是60厘米。
  113 + * 1万多步,距离大概就是600000厘米,即6000米(6公里)
  114 + *
  115 + * @param step
  116 + * @return
  117 + */
  118 + public static double getWalkDistanceKM(double step) {
  119 + double result = step * 60.0 / 100.0 / 1000.0;
  120 + result = Double.parseDouble(String.format("%1.2f", result));
  121 + return result;
  122 + }
  123 +
  124 + public static double getCalorie(double step) {
  125 +// 体重(kg)* 距离(km)* 运动系数(k)
  126 +// 健走:k=0.8214
  127 +//
  128 +//跑步:k=1.036
  129 +//
  130 +//自行车:k=0.6142
  131 +//
  132 +//轮滑、溜冰:k=0.518
  133 +//
  134 +//室外滑雪:k=0.888
  135 + double result =60 * getWalkDistanceKM(step) * 1.036;
  136 + result = Double.parseDouble(String.format("%1.2f", result));
  137 + return result;
  138 + }
  139 +}
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/collectionTrace/frame/view/CollRunRaceDetailFragmentView.java
... ... @@ -7,10 +7,14 @@ import android.hardware.Sensor;
7 7 import android.hardware.SensorEvent;
8 8 import android.hardware.SensorEventListener;
9 9 import android.hardware.SensorManager;
  10 +import android.os.Build;
10 11 import android.text.TextUtils;
11 12 import android.util.Log;
12 13 import android.view.View;
  14 +import android.view.ViewGroup;
13 15 import android.view.ViewTreeObserver;
  16 +import android.webkit.WebSettings;
  17 +import android.webkit.WebView;
14 18 import android.widget.Toast;
15 19  
16 20 import com.baidu.location.BDAbstractLocationListener;
... ... @@ -54,6 +58,7 @@ import com.cnlive.moudle.pedometer.utils.BitmapUtil;
54 58 import com.cnlive.moudle.pedometer.utils.MyMapUtil;
55 59 import com.cnlive.moudle.pedometer.utils.ScreenUtil;
56 60 import com.cnlive.moudle.pedometer.utils.TimeUtil;
  61 +import com.cnlive.moudle.pedometer.utils.WebViewUtil;
57 62 import com.cnlive.strike.application.GlideApp;
58 63 import com.example.moudle_pedometer.R;
59 64 import com.hannesdorfmann.mosby3.mvp.MvpView;
... ... @@ -98,6 +103,7 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
98 103 private float initZoom = 0;
99 104 private final float INIT_MAP_OVERLOOK = -40f;//地图倾斜角度
100 105 private final float DEFAULT_MAP_AUTO_ZOOM = -0.8f;//根据点位,自动缩放的比例
  106 + public WebView webView;
101 107  
102 108 public CollRunRaceDetailFragmentView(CollRunRaceDetailFragment fragment) {
103 109 this.fragment = fragment;
... ... @@ -107,6 +113,30 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
107 113 return fragment == null ? null : fragment.getActivity();
108 114 }
109 115  
  116 + public void initWebView(String html) {
  117 + if (null == webView) {
  118 + webView = new WebView(getContext());
  119 + WebSettings webSettings = webView.getSettings();
  120 + if (Build.VERSION.SDK_INT >= 21) {
  121 + webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
  122 + }
  123 + // 设置支持javascript脚本
  124 + webSettings.setJavaScriptEnabled(true);
  125 + // 设置此属性,可任意比例缩放
  126 + webSettings.setUseWideViewPort(true);
  127 + // 设置不出现缩放工具
  128 + webSettings.setBuiltInZoomControls(false);
  129 + // 设置不可以缩放
  130 + webSettings.setSupportZoom(false);
  131 + webSettings.setDisplayZoomControls(false);
  132 + //自适应屏幕
  133 + webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
  134 + // 自适应 屏幕大小界面
  135 + webSettings.setLoadWithOverviewMode(true);
  136 + }
  137 + WebViewUtil.setPtoHtmlData(fragment.getActivity(), html, webView, Constant.WEBVIEW_FONT_SIZE);
  138 + fragment.binding.includeStreetIntroduce.llWebview.addView(webView);
  139 + }
110 140  
111 141 public void initView(RunRaceDetailInfo runRaceDetailInfo, String uid) {
112 142 queryResultPoints = new ArrayList<>();
... ... @@ -116,6 +146,13 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
116 146 if (null == mClient) {
117 147 mClient = new LBSTraceClient(getContext());
118 148 }
  149 + if (null != runRaceDetailInfo) {
  150 + if (null != runRaceDetailInfo.getNewDescription() && !TextUtils.isEmpty(runRaceDetailInfo.getNewDescription())) {
  151 + initWebView(runRaceDetailInfo.getNewDescription());
  152 + } else if (null != runRaceDetailInfo.getDescription() && !TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
  153 + initWebView(runRaceDetailInfo.getDescription());
  154 + }
  155 + }
119 156 CollCommonInfo.setUserId(getContext(), uid);
120 157 this.runRaceDetailInfo = runRaceDetailInfo;
121 158 //显示地图
... ... @@ -175,31 +212,50 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
175 212 if (!TextUtils.isEmpty(runRaceDetailInfo.getTitle())) {
176 213 fragment.binding.includeStreet.tvRaceTitle.setText(runRaceDetailInfo.getTitle());
177 214 }
178   -
  215 + //设置二级标题
  216 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  217 + fragment.binding.includeStreet.tvSecondTitle.setVisibility(View.VISIBLE);
  218 + fragment.binding.includeStreet.tvSecondTitle.setText(runRaceDetailInfo.getE_subtitle());
  219 + }
179 220 //判断是否显示绑定轨迹按钮
180 221 if (runRaceDetailInfo.isTrackButton()) {
181 222 //显示
182 223 fragment.binding.rlScrollViewAddTrace.setVisibility(View.VISIBLE);
183 224 fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140));
184 225 // //根据标题行数,自动调整卡片大小
185   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
186   - @Override
187   - public boolean onPreDraw() {
188   - int line = fragment.binding.includeStreet.tvRaceTitle.getLineCount();
189   - int height = fragment.binding.includeStreet.tvRaceTitle.getHeight();
190   - if (line > 1) {
191   - int avgHeight = height / line;//平局高度
192   - fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140) + avgHeight * (line - 1));
193   -
194   - }
195   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
196   - return false;
197   - }
198   - });
  226 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
  227 +// @Override
  228 +// public boolean onPreDraw() {
  229 +// int line = fragment.binding.includeStreet.tvRaceTitle.getLineCount();
  230 +// int height = fragment.binding.includeStreet.tvRaceTitle.getHeight();
  231 +// if (line > 1) {
  232 +// int avgHeight = height / line;//平局高度
  233 +// fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140) + avgHeight * (line - 1));
  234 +//
  235 +// }
  236 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
  237 +// return false;
  238 +// }
  239 +// });
  240 + //显示底部滑动卡片
  241 + fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  242 + fragment.binding.scrollView.scrollTo(0, 0);
  243 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  244 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 170));
  245 + } else {
  246 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140));
  247 + }
199 248 } else {
200 249 //不显示
201 250 fragment.binding.rlScrollViewAddTrace.setVisibility(View.GONE);
202   - fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 100));
  251 + //显示底部滑动卡片
  252 + fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  253 + fragment.binding.scrollView.scrollTo(0, 0);
  254 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  255 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 130));
  256 + } else {
  257 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 100));
  258 + }
203 259 // //根据标题行数,自动调整卡片大小
204 260 fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
205 261 @Override
... ... @@ -290,9 +346,9 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
290 346  
291 347 }
292 348 //设置路线介绍
293   - if (!TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
294   - fragment.binding.includeStreetIntroduce.tvStreetIntroduce.setText(runRaceDetailInfo.getDescription());
295   - }
  349 +// if (!TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
  350 +// fragment.binding.includeStreetIntroduce.tvStreetIntroduce.setText(runRaceDetailInfo.getDescription());
  351 +// }
296 352  
297 353 //添加轨迹按钮点击事件
298 354 fragment.binding.rlScrollViewAddTrace.setOnClickListener(new View.OnClickListener() {
... ... @@ -630,6 +686,9 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
630 686 if (mMapView != null) {
631 687 mMapView.onResume();
632 688 }
  689 + if (null != webView) {
  690 + webView.onResume();
  691 + }
633 692 }
634 693  
635 694 public void onPause() {
... ... @@ -639,6 +698,9 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
639 698 if (mMapView != null) {
640 699 mMapView.onPause();
641 700 }
  701 + if (null != webView) {
  702 + webView.onPause();
  703 + }
642 704 }
643 705  
644 706 public void onDestroy() {
... ... @@ -652,6 +714,15 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
652 714 if (mLocClient != null) {
653 715 mLocClient.stop();
654 716 }
  717 + try {
  718 + if (null != webView) {
  719 + if (webView.getParent() != null) {
  720 + ((ViewGroup) webView.getParent()).removeView(webView);
  721 + }
  722 + webView.destroy();
  723 + }
  724 + } catch (Exception e) {
  725 + }
655 726 }
656 727  
657 728 /**
... ... @@ -669,7 +740,7 @@ public class CollRunRaceDetailFragmentView implements MvpView, SensorEventListen
669 740 if (isFirstLoc) {
670 741 isFirstLoc = false;
671 742 if (location.getRadius() > Constant.LOCA_ACCURACY) {
672   - Toast.makeText(getContext(), "当前定位误差为:" + (int)location.getRadius() + "米,请您移动至空旷地带!", Toast.LENGTH_SHORT).show();
  743 + Toast.makeText(getContext(), "当前定位误差为:" + (int) location.getRadius() + "米,请您移动至空旷地带!", Toast.LENGTH_SHORT).show();
673 744 }
674 745 } else {
675 746 //过滤定位精度
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/collectionTrace/ui/adapter/RunListAdapter.java
... ... @@ -44,6 +44,13 @@ public class RunListAdapter extends RecyclerView.Adapter&lt;RunListAdapter.MyViewHo
44 44 @Override
45 45 public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
46 46 myViewHolder.line_name.setText(list.get(i).getTitle());
  47 + if (!TextUtils.isEmpty(list.get(i).getE_subtitle())) {
  48 + myViewHolder.tv_second_title.setVisibility(View.VISIBLE);
  49 + myViewHolder.tv_second_title.setText(list.get(i).getE_subtitle());
  50 + } else {
  51 + myViewHolder.tv_second_title.setVisibility(View.GONE);
  52 +
  53 + }
47 54 myViewHolder.activity_time.setText(TimeUtil.getStampToTime(list.get(i).getStart_time(), "yyyy.MM.dd") + "——" + TimeUtil.getStampToTime(list.get(i).getEnd_time(), "yyyy.MM.dd"));
48 55 if (!TextUtils.isEmpty(list.get(i).getMileage())) {
49 56 myViewHolder.line_address.setText(list.get(i).getAddress() + "\t\t全长" + list.get(i).getMileage() + "公里");
... ... @@ -84,6 +91,7 @@ public class RunListAdapter extends RecyclerView.Adapter&lt;RunListAdapter.MyViewHo
84 91 TextView line_address;
85 92 TextView add_path;
86 93 TextView path_list;
  94 + TextView tv_second_title;
87 95 RelativeLayout item_ly;
88 96  
89 97 public MyViewHolder(@NonNull View itemView) {
... ... @@ -94,6 +102,8 @@ public class RunListAdapter extends RecyclerView.Adapter&lt;RunListAdapter.MyViewHo
94 102 add_path = itemView.findViewById(R.id.add_path);
95 103 path_list = itemView.findViewById(R.id.path_list);
96 104 item_ly = itemView.findViewById(R.id.item_ly);
  105 + tv_second_title = itemView.findViewById(R.id.tv_second_title);
  106 +
97 107 }
98 108 }
99 109  
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/collectionTrace/ui/fragment/CollRunRaceDetailFragment.java
... ... @@ -7,6 +7,7 @@ import android.os.Bundle;
7 7 import android.support.annotation.Nullable;
8 8 import android.util.Log;
9 9 import android.view.View;
  10 +import android.view.ViewGroup;
10 11 import android.widget.Button;
11 12  
12 13 import com.cnlive.libs.base.ui.QMUIFragment;
... ... @@ -197,6 +198,18 @@ public class CollRunRaceDetailFragment extends QMUIFragment&lt;CollRunRaceDetailFra
197 198 if (messageEvent.getMessageType() == Constant.UPDATA_COLL_BIND_TRACE_LIST) {
198 199 if (getMvpView() != null) {
199 200 getMvpView().resetMap();
  201 + if (null != getMvpView()) {
  202 + try {
  203 + if (null != getMvpView().webView) {
  204 + if (getMvpView().webView.getParent() != null) {
  205 + ((ViewGroup) getMvpView().webView.getParent()).removeView(getMvpView().webView);
  206 + }
  207 + getMvpView().webView.destroy();
  208 + getMvpView().webView = null;
  209 + }
  210 + } catch (Exception e) {
  211 + }
  212 + }
200 213 getPresenter().getRunRaceDetailInfo(getActivity(), CollCommonInfo.getStreetId(getActivity()), CommonInfo.getUserId(getActivity()), "1");
201 214 }
202 215 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/frame/view/OnGoingFragmentView.java
... ... @@ -4,10 +4,14 @@ import android.app.Activity;
4 4 import android.content.Context;
5 5 import android.graphics.Bitmap;
6 6 import android.graphics.BitmapFactory;
  7 +import android.os.Build;
7 8 import android.text.TextUtils;
8 9 import android.util.Log;
9 10 import android.view.View;
  11 +import android.view.ViewGroup;
10 12 import android.view.ViewTreeObserver;
  13 +import android.webkit.WebSettings;
  14 +import android.webkit.WebView;
11 15 import android.widget.LinearLayout;
12 16  
13 17 import com.alibaba.android.arouter.launcher.ARouter;
... ... @@ -41,6 +45,7 @@ import com.cnlive.moudle.pedometer.utils.QMUITipDialogUtil;
41 45 import com.cnlive.moudle.pedometer.utils.ScreenUtil;
42 46 import com.cnlive.moudle.pedometer.utils.StepUtil;
43 47 import com.cnlive.moudle.pedometer.utils.TimeUtil;
  48 +import com.cnlive.moudle.pedometer.utils.WebViewUtil;
44 49 import com.cnlive.strike.application.GlideApp;
45 50 import com.example.moudle_pedometer.R;
46 51 import com.hannesdorfmann.mosby3.mvp.MvpView;
... ... @@ -56,6 +61,7 @@ public class OnGoingFragmentView implements MvpView {
56 61 private UiSettings mUiSettings;
57 62 public RunRaceDetailInfo runRaceDetailInfo;
58 63 private LBSTraceClient mClient = null;
  64 + private WebView webView;
59 65  
60 66 public OnGoingFragmentView(OnGoingFragment fragment) {
61 67 this.fragment = fragment;
... ... @@ -65,12 +71,44 @@ public class OnGoingFragmentView implements MvpView {
65 71 return fragment == null ? null : fragment.getActivity();
66 72 }
67 73  
  74 + public void initWebView(String html) {
  75 + if (null == webView) {
  76 + webView = new WebView(getContext());
  77 + WebSettings webSettings = webView.getSettings();
  78 + if (Build.VERSION.SDK_INT >= 21) {
  79 + webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
  80 + }
  81 + // 设置支持javascript脚本
  82 + webSettings.setJavaScriptEnabled(true);
  83 + // 设置此属性,可任意比例缩放
  84 + webSettings.setUseWideViewPort(true);
  85 + // 设置不出现缩放工具
  86 + webSettings.setBuiltInZoomControls(false);
  87 + // 设置不可以缩放
  88 + webSettings.setSupportZoom(false);
  89 + webSettings.setDisplayZoomControls(false);
  90 + //自适应屏幕
  91 + webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
  92 + // 自适应 屏幕大小界面
  93 + webSettings.setLoadWithOverviewMode(true);
  94 + }
  95 + WebViewUtil.setPtoHtmlData(fragment.getActivity(), html, webView, Constant.WEBVIEW_FONT_SIZE);
  96 + fragment.binding.includeStreetIntroduce.llWebview.addView(webView);
  97 + }
  98 +
68 99 public void initView(RunRaceDetailInfo runRaceDetailInfo) {
69 100  
70 101 if (fragment.getActivity() == null) {
71 102 return;
72 103 }
73 104 this.runRaceDetailInfo = runRaceDetailInfo;
  105 + if (null != runRaceDetailInfo) {
  106 + if (null != runRaceDetailInfo.getNewDescription() && !TextUtils.isEmpty(runRaceDetailInfo.getNewDescription())) {
  107 + initWebView(runRaceDetailInfo.getNewDescription());
  108 + } else if (null != runRaceDetailInfo.getDescription() && !TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
  109 + initWebView(runRaceDetailInfo.getDescription());
  110 + }
  111 + }
74 112 //轨迹开始时间
75 113 long startTime = 0;
76 114 //轨迹结束时间
... ... @@ -212,33 +250,45 @@ public class OnGoingFragmentView implements MvpView {
212 250 //设置围栏ID
213 251 CommonInfo.setFenceId(getContext(), Integer.parseInt(runRaceDetailInfo.getFenceId()));
214 252 }
215   - fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140));
  253 + //显示底部滑动卡片
  254 + fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  255 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  256 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 169));
  257 + } else {
  258 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140));
  259 + }
216 260 //设置标题
217 261 if (!TextUtils.isEmpty(runRaceDetailInfo.getTitle())) {
218 262 fragment.binding.includeStreet.tvRaceTitle.setText(runRaceDetailInfo.getTitle());
219 263 //根据标题行数,自动调整卡片大小
220   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
221   - @Override
222   - public boolean onPreDraw() {
223   - int line = fragment.binding.includeStreet.tvRaceTitle.getLineCount();
224   - int height = fragment.binding.includeStreet.tvRaceTitle.getHeight();
225   - if (line > 1) {
226   - int avgHeight = height / line;//平局高度
227   - fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140) + avgHeight * (line - 1));
228   -
229   - }
230   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
231   - return false;
232   - }
233   - });
  264 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
  265 +// @Override
  266 +// public boolean onPreDraw() {
  267 +// int line = fragment.binding.includeStreet.tvRaceTitle.getLineCount();
  268 +// int height = fragment.binding.includeStreet.tvRaceTitle.getHeight();
  269 +// if (line > 1) {
  270 +// int avgHeight = height / line;//平局高度
  271 +// fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 140) + avgHeight * (line - 1));
  272 +//
  273 +// }
  274 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
  275 +// return false;
  276 +// }
  277 +// });
234 278 // fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  279 +
  280 + }
  281 + //设置二级标题
  282 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  283 + fragment.binding.includeStreet.tvSecondTitle.setVisibility(View.VISIBLE);
  284 + fragment.binding.includeStreet.tvSecondTitle.setText(runRaceDetailInfo.getE_subtitle());
235 285 }
236 286 //设置活动地点
237 287 if (!TextUtils.isEmpty(runRaceDetailInfo.getAddress())) {
238 288 fragment.binding.includeStreet.tvAddress.setText(runRaceDetailInfo.getAddress());
239 289 //设置活动距离
240 290 if (!TextUtils.isEmpty(runRaceDetailInfo.getMileage())) {
241   - fragment.binding.includeStreet.tvAddress.append("\t\t" + runRaceDetailInfo.getMileage()+"公里");
  291 + fragment.binding.includeStreet.tvAddress.append("\t\t" + runRaceDetailInfo.getMileage() + "公里");
242 292 }
243 293 }
244 294  
... ... @@ -330,9 +380,9 @@ public class OnGoingFragmentView implements MvpView {
330 380  
331 381 }
332 382 //设置路线描述
333   - if (!TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
334   - fragment.binding.includeStreetIntroduce.tvStreetIntroduce.setText(runRaceDetailInfo.getDescription());
335   - }
  383 +// if (!TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
  384 +// fragment.binding.includeStreetIntroduce.tvStreetIntroduce.setText(runRaceDetailInfo.getDescription());
  385 +// }
336 386 //设置路线介绍的图片
337 387 if (!TextUtils.isEmpty(runRaceDetailInfo.getRoadmap())) {
338 388 //设置路线图
... ... @@ -444,4 +494,43 @@ public class OnGoingFragmentView implements MvpView {
444 494 fragment.binding.emptyLayout.show(false, titleText, detailText, getContext().getString(R.string.retry), R.drawable.wufalianjie, listener);
445 495 }
446 496  
  497 + public void onResume() {
  498 + if (getContext() == null) {
  499 + return;
  500 + }
  501 + if (mMapView != null) {
  502 + mMapView.onResume();
  503 + }
  504 + if (null != webView) {
  505 + webView.onResume();
  506 + }
  507 +
  508 + }
  509 +
  510 + public void onPause() {
  511 + if (mMapView != null) {
  512 + mMapView.onPause();
  513 + }
  514 + if (null != webView) {
  515 + webView.onPause();
  516 + }
  517 + }
  518 +
  519 + public void onDestroy() {
  520 + if (mMapView != null) {
  521 + mMapView.onDestroy();
  522 + mMapView = null;
  523 + }
  524 + try {
  525 + if (null != webView) {
  526 + if (webView.getParent() != null) {
  527 + ((ViewGroup) webView.getParent()).removeView(webView);
  528 + }
  529 + webView.destroy();
  530 + webView = null;
  531 + }
  532 + } catch (Exception e) {
  533 + }
  534 + }
  535 +
447 536 }
448 537 \ No newline at end of file
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/frame/view/RunMainFragmentView.java
... ... @@ -796,12 +796,14 @@ public class RunMainFragmentView implements MvpView {
796 796 if (!TextUtils.isEmpty(userStepEntity.getEndLatLng())) {
797 797 endLatLng = GsonUtil.GsonToBean(userStepEntity.getEndLatLng(), LatLng.class);
798 798 }
799   - if (null == userStepEntity.getStepCount() || TextUtils.isEmpty(userStepEntity.getStepCount())) {
  799 + }
  800 + }
  801 + if (null != userStepEntity) {
  802 + if (null == userStepEntity.getStepCount() || TextUtils.isEmpty(userStepEntity.getStepCount())) {
  803 + return;
  804 + } else {
  805 + if (Integer.parseInt(userStepEntity.getStepCount()) <= 100) {
800 806 return;
801   - } else {
802   - if (Integer.parseInt(userStepEntity.getStepCount()) <= 100) {
803   - return;
804   - }
805 807 }
806 808 }
807 809 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/frame/view/RunRaceDetailFragmentView.java
... ... @@ -8,12 +8,18 @@ import android.hardware.Sensor;
8 8 import android.hardware.SensorEvent;
9 9 import android.hardware.SensorEventListener;
10 10 import android.hardware.SensorManager;
  11 +import android.os.Build;
11 12 import android.os.SystemClock;
12 13 import android.support.v4.content.ContextCompat;
13 14 import android.text.TextUtils;
14 15 import android.util.Log;
15 16 import android.view.View;
  17 +import android.view.ViewGroup;
16 18 import android.view.ViewTreeObserver;
  19 +import android.webkit.JavascriptInterface;
  20 +import android.webkit.WebSettings;
  21 +import android.webkit.WebView;
  22 +import android.webkit.WebViewClient;
17 23 import android.widget.LinearLayout;
18 24 import android.widget.Toast;
19 25  
... ... @@ -63,6 +69,7 @@ import com.cnlive.moudle.pedometer.utils.ScreenUtil;
63 69 import com.cnlive.moudle.pedometer.utils.ServiceUtils;
64 70 import com.cnlive.moudle.pedometer.utils.StepUtil;
65 71 import com.cnlive.moudle.pedometer.utils.TimeUtil;
  72 +import com.cnlive.moudle.pedometer.utils.WebViewUtil;
66 73 import com.cnlive.strike.application.GlideApp;
67 74 import com.example.moudle_pedometer.R;
68 75 import com.hannesdorfmann.mosby3.mvp.MvpView;
... ... @@ -121,7 +128,8 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
121 128 private final String BTN_START_RACE = "5";//立即开始
122 129 private final String BTN_END_RACE = "6";//赛事已结束
123 130 private final String BTN_CONTINUE_RACE = "7";//继续运动
124   -
  131 + public WebView webView;
  132 + private boolean isLoadWeb = false;
125 133  
126 134 public RunRaceDetailFragmentView(RunRaceDetailFragment fragment) {
127 135 this.fragment = fragment;
... ... @@ -131,11 +139,42 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
131 139 return fragment == null ? null : fragment.getActivity();
132 140 }
133 141  
  142 + public void initWebView(String html) {
  143 + if (null == webView) {
  144 + webView = new WebView(getContext());
  145 + WebSettings webSettings = webView.getSettings();
  146 + if (Build.VERSION.SDK_INT >= 21) {
  147 + webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
  148 + }
  149 + // 设置支持javascript脚本
  150 + webSettings.setJavaScriptEnabled(true);
  151 + // 设置此属性,可任意比例缩放
  152 + webSettings.setUseWideViewPort(true);
  153 + // 设置不出现缩放工具
  154 + webSettings.setBuiltInZoomControls(false);
  155 + // 设置不可以缩放
  156 + webSettings.setSupportZoom(false);
  157 + webSettings.setDisplayZoomControls(false);
  158 + //自适应屏幕
  159 + webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
  160 + // 自适应 屏幕大小界面
  161 + webSettings.setLoadWithOverviewMode(true);
  162 + }
  163 + WebViewUtil.setPtoHtmlData(fragment.getActivity(), html, webView, Constant.WEBVIEW_FONT_SIZE);
  164 + fragment.binding.includeStreetIntroduce.llWebview.addView(webView);
  165 + }
134 166  
135 167 public void initView(RunRaceDetailInfo runRaceDetailInfo) {
136 168 if (fragment.getActivity() == null) {
137 169 return;
138 170 }
  171 + if (null != runRaceDetailInfo) {
  172 + if (null != runRaceDetailInfo.getNewDescription() && !TextUtils.isEmpty(runRaceDetailInfo.getNewDescription())) {
  173 + initWebView(runRaceDetailInfo.getNewDescription());
  174 + } else if (null != runRaceDetailInfo.getDescription() && !TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
  175 + initWebView(runRaceDetailInfo.getDescription());
  176 + }
  177 + }
139 178 queryResultPoints = new ArrayList<>();
140 179 this.runRaceDetailInfo = runRaceDetailInfo;
141 180 //轨迹开始时间
... ... @@ -173,12 +212,11 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
173 212  
174 213 //显示地图
175 214 fragment.binding.mapView.setVisibility(View.VISIBLE);
176   - //显示底部滑动卡片
177   -// fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
178 215 //隐藏空视图
179 216 fragment.binding.emptyLayout.setVisibility(View.GONE);
180 217 //显示立即报名按钮
181 218 // fragment.binding.includeStreet.rlStartBtn.setVisibility(View.VISIBLE);
  219 +
182 220 //设置底部卡片第一次可滑动的位置
183 221 fragment.binding.slidingLayout.setAnchorPoint(0.6f);
184 222 LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
... ... @@ -188,6 +226,7 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
188 226 fragment.binding.slidingLayout.addPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
189 227 @Override
190 228 public void onPanelSlide(View panel, float slideOffset) {
  229 + Log.e(TAG, "onPanelSlide: ");
191 230 //设置顶层卡片特效
192 231 if (slideOffset > 0.7) {
193 232 double alpha = (255 / (1 - 0.6)) * (slideOffset - 0.6);
... ... @@ -233,6 +272,8 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
233 272  
234 273 @Override
235 274 public void onPanelStateChanged(View panel, SlidingUpPanelLayout.PanelState previousState, SlidingUpPanelLayout.PanelState newState) {
  275 + Log.e(TAG, "onPanelStateChanged: ");
  276 +
236 277 if (newState == SlidingUpPanelLayout.PanelState.EXPANDED) {
237 278 fragment.binding.includeStreet.ivSlideIcon.setVisibility(View.INVISIBLE);
238 279 }
... ... @@ -324,31 +365,46 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
324 365 //设置标题
325 366 if (!TextUtils.isEmpty(runRaceDetailInfo.getTitle())) {
326 367 fragment.binding.includeStreet.tvRaceTitle.setText(runRaceDetailInfo.getTitle());
327   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
328   - @Override
329   - public boolean onPreDraw() {
330   - Log.e(TAG, "initView: " + fragment.binding.includeStreet.tvRaceTitle.getLineCount());
331   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
332   - return false;
333   - }
334   - });
335   - fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 181));
336   - //根据标题行数,自动调整卡片大小
337   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
338   - @Override
339   - public boolean onPreDraw() {
340   - int line = fragment.binding.includeStreet.tvRaceTitle.getLineCount();
341   - int height = fragment.binding.includeStreet.tvRaceTitle.getHeight();
342   - if (line > 1) {
343   - int avgHeight = height / line;//平局高度
344   - fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 181) + avgHeight * (line - 1));
  368 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
  369 +// @Override
  370 +// public boolean onPreDraw() {
  371 +// Log.e(TAG, "initView: " + fragment.binding.includeStreet.tvRaceTitle.getLineCount());
  372 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
  373 +// return false;
  374 +// }
  375 +// });
  376 + //显示底部滑动卡片
  377 + fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  378 + fragment.binding.scrollView.scrollTo(0, 0);
  379 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  380 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 210));
  381 + } else {
  382 + fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 181));
  383 + }
  384 +// //根据标题行数,自动调整卡片大小
  385 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
  386 +// @Override
  387 +// public boolean onPreDraw() {
  388 +// int line = fragment.binding.includeStreet.tvRaceTitle.getLineCount();
  389 +// int height = fragment.binding.includeStreet.tvRaceTitle.getHeight();
  390 +// if (line > 1) {
  391 +// int avgHeight = height / line;//平局高度
  392 +// fragment.binding.slidingLayout.setPanelHeight(ScreenUtil.dip2px(getContext(), 181) + avgHeight * (line - 1));
  393 +// }
  394 +// fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
  395 +// //显示底部滑动卡片
  396 +// fragment.binding.slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  397 +// fragment.binding.scrollView.scrollTo(0,0);
  398 +// return false;
  399 +// }
  400 +// });
345 401  
346   - }
347   - fragment.binding.includeStreet.tvRaceTitle.getViewTreeObserver().removeOnPreDrawListener(this);
348   - return false;
349   - }
350   - });
  402 + }
351 403  
  404 + //设置二级标题
  405 + if (!TextUtils.isEmpty(runRaceDetailInfo.getE_subtitle())) {
  406 + fragment.binding.includeStreet.tvSecondTitle.setVisibility(View.VISIBLE);
  407 + fragment.binding.includeStreet.tvSecondTitle.setText(runRaceDetailInfo.getE_subtitle());
352 408 }
353 409 //设置活动地点
354 410 if (!TextUtils.isEmpty(runRaceDetailInfo.getAddress())) {
... ... @@ -455,9 +511,9 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
455 511  
456 512 }
457 513 //设置路线描述
458   - if (!TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
459   - fragment.binding.includeStreetIntroduce.tvStreetIntroduce.setText(runRaceDetailInfo.getDescription());
460   - }
  514 +// if (!TextUtils.isEmpty(runRaceDetailInfo.getDescription())) {
  515 +// fragment.binding.includeStreetIntroduce.tvStreetIntroduce.setText(runRaceDetailInfo.getDescription());
  516 +// }
461 517 //设置路线介绍的图片
462 518 if (!TextUtils.isEmpty(runRaceDetailInfo.getRoadmap())) {
463 519 //设置路线图
... ... @@ -641,6 +697,11 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
641 697 } else if (BTN_END_RACE.equals(fragment.binding.rlScrollViewStartBtn.getTag())) {
642 698 return;
643 699 }
  700 +
  701 +// if (fragment.binding.slidingLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
  702 +// fragment.binding.scrollView.scrollTo(0, 0);
  703 +// }
  704 +
644 705 }
645 706 });
646 707 //查看全部成绩点击事件
... ... @@ -1077,6 +1138,9 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
1077 1138 if (mMapView != null) {
1078 1139 mMapView.onResume();
1079 1140 }
  1141 + if (null != webView) {
  1142 + webView.onResume();
  1143 + }
1080 1144 //todo 防止停止后,再次开始,无法获取到赛道的轨迹
1081 1145 if (runRaceDetailInfo != null) {
1082 1146 if (runRaceDetailInfo.getFenceId() != null && !TextUtils.isEmpty(runRaceDetailInfo.getFenceId())) {
... ... @@ -1184,6 +1248,9 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
1184 1248 if (mMapView != null) {
1185 1249 mMapView.onPause();
1186 1250 }
  1251 + if (null != webView) {
  1252 + webView.onPause();
  1253 + }
1187 1254 }
1188 1255  
1189 1256 public void onDestroy() {
... ... @@ -1194,6 +1261,16 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
1194 1261 if (mLocClient != null) {
1195 1262 mLocClient.stop();
1196 1263 }
  1264 + try {
  1265 + if (null != webView) {
  1266 + if (webView.getParent() != null) {
  1267 + ((ViewGroup) webView.getParent()).removeView(webView);
  1268 + }
  1269 + webView.destroy();
  1270 + webView = null;
  1271 + }
  1272 + } catch (Exception e) {
  1273 + }
1197 1274 }
1198 1275  
1199 1276 /**
... ... @@ -1388,4 +1465,32 @@ public class RunRaceDetailFragmentView implements MvpView, SensorEventListener {
1388 1465 // }
1389 1466 }
1390 1467  
  1468 +// private class MyWebViewClient extends WebViewClient {
  1469 +// @Override
  1470 +// public void onPageFinished(WebView view, String url) {
  1471 +// super.onPageFinished(view, url);
  1472 +// int w = View.MeasureSpec.makeMeasureSpec(0,
  1473 +// View.MeasureSpec.UNSPECIFIED);
  1474 +// int h = View.MeasureSpec.makeMeasureSpec(0,
  1475 +// View.MeasureSpec.UNSPECIFIED);
  1476 +// // 重新测量
  1477 +// view.measure(w, h);
  1478 +//
  1479 +// String js = "javascript:(function(){" +
  1480 +// "var images = document.getElementsByTagName(\"img\");" +
  1481 +// "var imageUrls = new Array(); " +
  1482 +// "for(var i=0; i<images.length; i++) {" +
  1483 +// " imageUrls[i] = images[i].src; " +
  1484 +// " images[i].pos = i; " +
  1485 +// " images[i].onclick = function(){" +
  1486 +// " window.injectedObject.openImage(this.src, this.pos);" +
  1487 +// " }" +
  1488 +// "}" +
  1489 +// "window.injectedObject.setImageUrls(imageUrls); " +
  1490 +// "})()";
  1491 +//
  1492 +// webView.loadUrl(js);
  1493 +// }
  1494 +// }
  1495 +
1391 1496 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/frame/view/RunningMapFragmentView.java
... ... @@ -383,16 +383,19 @@ public class RunningMapFragmentView implements MvpView, SensorEventListener {
383 383 if (!TextUtils.isEmpty(userStepEntity.getEndLatLng())) {
384 384 endLatLng = GsonUtil.GsonToBean(userStepEntity.getEndLatLng(), LatLng.class);
385 385 }
386   - if (null == userStepEntity.getStepCount() || TextUtils.isEmpty(userStepEntity.getStepCount())) {
  386 +
  387 + }
  388 + }
  389 +
  390 + if (null != userStepEntity) {
  391 + if (null == userStepEntity.getStepCount() || TextUtils.isEmpty(userStepEntity.getStepCount())) {
  392 + return;
  393 + } else {
  394 + if (Integer.parseInt(userStepEntity.getStepCount()) <= 100) {
387 395 return;
388   - } else {
389   - if (Integer.parseInt(userStepEntity.getStepCount()) <= 100) {
390   - return;
391   - }
392 396 }
393 397 }
394 398 }
395   -
396 399 //开始比较
397 400 if (null != endLatLng) {
398 401 LatLng current = new LatLng(location.getLatitude(), location.getLongitude());
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/model/Constant.java
... ... @@ -44,4 +44,5 @@ public class Constant {
44 44 public static final int FENCE_DENOISE = 20;//围栏去噪精度
45 45 public static final int TAKE_POINT_MAX_SIZE = 100;//最大打点数量
46 46 public static final int COLL_GEORESULT_RADIUS = 20;//打点逆地理半径
  47 + public static final int WEBVIEW_FONT_SIZE = 40;//webview显示的网页文字大小
47 48 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/net/bean/MyRecordInfo.java
... ... @@ -102,6 +102,15 @@ public class MyRecordInfo {
102 102 private String title;
103 103 private String day;
104 104 private List<String> faceUrl;
  105 + private String e_subtitle;
  106 +
  107 + public String getE_subtitle() {
  108 + return e_subtitle;
  109 + }
  110 +
  111 + public void setE_subtitle(String e_subtitle) {
  112 + this.e_subtitle = e_subtitle;
  113 + }
105 114  
106 115 public String getAddress() {
107 116 return address;
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/net/bean/RunLineInfo.java
... ... @@ -103,6 +103,15 @@ public class RunLineInfo {
103 103 private String title;
104 104 private String mileage;
105 105 private List<String> faceUrl;
  106 + private String e_subtitle;
  107 +
  108 + public String getE_subtitle() {
  109 + return e_subtitle;
  110 + }
  111 +
  112 + public void setE_subtitle(String e_subtitle) {
  113 + this.e_subtitle = e_subtitle;
  114 + }
106 115  
107 116 public String getAddress() {
108 117 return address;
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/net/bean/RunRaceDetailInfo.java
... ... @@ -92,6 +92,24 @@ public class RunRaceDetailInfo implements Serializable {
92 92 private boolean endState;//活动是否结束(true 结束 false 未结束 )
93 93 private String collStartLatLng;//运营打的点
94 94 private String collStartLntLngName;//运营打点名称
  95 + private String e_subtitle;
  96 + private String newDescription;
  97 +
  98 + public String getE_subtitle() {
  99 + return e_subtitle;
  100 + }
  101 +
  102 + public void setE_subtitle(String e_subtitle) {
  103 + this.e_subtitle = e_subtitle;
  104 + }
  105 +
  106 + public String getNewDescription() {
  107 + return newDescription;
  108 + }
  109 +
  110 + public void setNewDescription(String newDescription) {
  111 + this.newDescription = newDescription;
  112 + }
95 113  
96 114 public String getEventState() {
97 115 return eventState;
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/service/StepService.java
... ... @@ -1288,16 +1288,18 @@ public class StepService extends Service implements SensorEventListener {
1288 1288 if (!TextUtils.isEmpty(userStepEntity.getEndLatLng())) {
1289 1289 endLatLng = GsonUtil.GsonToBean(userStepEntity.getEndLatLng(), LatLng.class);
1290 1290 }
1291   - if (null == userStepEntity.getStepCount() || TextUtils.isEmpty(userStepEntity.getStepCount())) {
  1291 +
  1292 + }
  1293 + }
  1294 + if (null != userStepEntity) {
  1295 + if (null == userStepEntity.getStepCount() || TextUtils.isEmpty(userStepEntity.getStepCount())) {
  1296 + return;
  1297 + } else {
  1298 + if (Integer.parseInt(userStepEntity.getStepCount()) <= 100) {
1292 1299 return;
1293   - } else {
1294   - if (Integer.parseInt(userStepEntity.getStepCount()) <= 100) {
1295   - return;
1296   - }
1297 1300 }
1298 1301 }
1299 1302 }
1300   -
1301 1303 //开始比较数据
1302 1304 if (null != endLatLng) {
1303 1305 LatLng current = new LatLng(location.getLatitude(), location.getLongitude());
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/sql/dao/DaoMaster.java
... ... @@ -21,6 +21,7 @@ public class DaoMaster extends AbstractDaoMaster {
21 21  
22 22 /** Creates underlying database table using DAOs. */
23 23 public static void createAllTables(Database db, boolean ifNotExists) {
  24 + CalorieEntityDao.createTable(db, ifNotExists);
24 25 CollFailedEntityDao.createTable(db, ifNotExists);
25 26 CollUserStepEntityDao.createTable(db, ifNotExists);
26 27 FailedEntityDao.createTable(db, ifNotExists);
... ... @@ -29,6 +30,7 @@ public class DaoMaster extends AbstractDaoMaster {
29 30  
30 31 /** Drops underlying database table using DAOs. */
31 32 public static void dropAllTables(Database db, boolean ifExists) {
  33 + CalorieEntityDao.dropTable(db, ifExists);
32 34 CollFailedEntityDao.dropTable(db, ifExists);
33 35 CollUserStepEntityDao.dropTable(db, ifExists);
34 36 FailedEntityDao.dropTable(db, ifExists);
... ... @@ -51,6 +53,7 @@ public class DaoMaster extends AbstractDaoMaster {
51 53  
52 54 public DaoMaster(Database db) {
53 55 super(db, SCHEMA_VERSION);
  56 + registerDaoClass(CalorieEntityDao.class);
54 57 registerDaoClass(CollFailedEntityDao.class);
55 58 registerDaoClass(CollUserStepEntityDao.class);
56 59 registerDaoClass(FailedEntityDao.class);
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/sql/dao/DaoSession.java
... ... @@ -8,11 +8,13 @@ import org.greenrobot.greendao.database.Database;
8 8 import org.greenrobot.greendao.identityscope.IdentityScopeType;
9 9 import org.greenrobot.greendao.internal.DaoConfig;
10 10  
  11 +import com.cnlive.moudle.pedometer.sql.entity.CalorieEntity;
11 12 import com.cnlive.moudle.pedometer.sql.entity.CollFailedEntity;
12 13 import com.cnlive.moudle.pedometer.sql.entity.CollUserStepEntity;
13 14 import com.cnlive.moudle.pedometer.sql.entity.FailedEntity;
14 15 import com.cnlive.moudle.pedometer.sql.entity.UserStepEntity;
15 16  
  17 +import com.cnlive.moudle.pedometer.sql.dao.CalorieEntityDao;
16 18 import com.cnlive.moudle.pedometer.sql.dao.CollFailedEntityDao;
17 19 import com.cnlive.moudle.pedometer.sql.dao.CollUserStepEntityDao;
18 20 import com.cnlive.moudle.pedometer.sql.dao.FailedEntityDao;
... ... @@ -27,11 +29,13 @@ import com.cnlive.moudle.pedometer.sql.dao.UserStepEntityDao;
27 29 */
28 30 public class DaoSession extends AbstractDaoSession {
29 31  
  32 + private final DaoConfig calorieEntityDaoConfig;
30 33 private final DaoConfig collFailedEntityDaoConfig;
31 34 private final DaoConfig collUserStepEntityDaoConfig;
32 35 private final DaoConfig failedEntityDaoConfig;
33 36 private final DaoConfig userStepEntityDaoConfig;
34 37  
  38 + private final CalorieEntityDao calorieEntityDao;
35 39 private final CollFailedEntityDao collFailedEntityDao;
36 40 private final CollUserStepEntityDao collUserStepEntityDao;
37 41 private final FailedEntityDao failedEntityDao;
... ... @@ -41,6 +45,9 @@ public class DaoSession extends AbstractDaoSession {
41 45 daoConfigMap) {
42 46 super(db);
43 47  
  48 + calorieEntityDaoConfig = daoConfigMap.get(CalorieEntityDao.class).clone();
  49 + calorieEntityDaoConfig.initIdentityScope(type);
  50 +
44 51 collFailedEntityDaoConfig = daoConfigMap.get(CollFailedEntityDao.class).clone();
45 52 collFailedEntityDaoConfig.initIdentityScope(type);
46 53  
... ... @@ -53,11 +60,13 @@ public class DaoSession extends AbstractDaoSession {
53 60 userStepEntityDaoConfig = daoConfigMap.get(UserStepEntityDao.class).clone();
54 61 userStepEntityDaoConfig.initIdentityScope(type);
55 62  
  63 + calorieEntityDao = new CalorieEntityDao(calorieEntityDaoConfig, this);
56 64 collFailedEntityDao = new CollFailedEntityDao(collFailedEntityDaoConfig, this);
57 65 collUserStepEntityDao = new CollUserStepEntityDao(collUserStepEntityDaoConfig, this);
58 66 failedEntityDao = new FailedEntityDao(failedEntityDaoConfig, this);
59 67 userStepEntityDao = new UserStepEntityDao(userStepEntityDaoConfig, this);
60 68  
  69 + registerDao(CalorieEntity.class, calorieEntityDao);
61 70 registerDao(CollFailedEntity.class, collFailedEntityDao);
62 71 registerDao(CollUserStepEntity.class, collUserStepEntityDao);
63 72 registerDao(FailedEntity.class, failedEntityDao);
... ... @@ -65,12 +74,17 @@ public class DaoSession extends AbstractDaoSession {
65 74 }
66 75  
67 76 public void clear() {
  77 + calorieEntityDaoConfig.clearIdentityScope();
68 78 collFailedEntityDaoConfig.clearIdentityScope();
69 79 collUserStepEntityDaoConfig.clearIdentityScope();
70 80 failedEntityDaoConfig.clearIdentityScope();
71 81 userStepEntityDaoConfig.clearIdentityScope();
72 82 }
73 83  
  84 + public CalorieEntityDao getCalorieEntityDao() {
  85 + return calorieEntityDao;
  86 + }
  87 +
74 88 public CollFailedEntityDao getCollFailedEntityDao() {
75 89 return collFailedEntityDao;
76 90 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/sql/entity/CalorieEntity.java 0 → 100644
  1 +package com.cnlive.moudle.pedometer.sql.entity;
  2 +
  3 +import org.greenrobot.greendao.annotation.Entity;
  4 +import org.greenrobot.greendao.annotation.Id;
  5 +import org.greenrobot.greendao.annotation.Generated;
  6 +
  7 +@Entity
  8 +public class CalorieEntity {
  9 + @Id
  10 + private String uuid;
  11 + private String userId;
  12 + private String currentDate;
  13 + private String step;
  14 + private String calorie;
  15 + @Generated(hash = 2026883887)
  16 + public CalorieEntity(String uuid, String userId, String currentDate,
  17 + String step, String calorie) {
  18 + this.uuid = uuid;
  19 + this.userId = userId;
  20 + this.currentDate = currentDate;
  21 + this.step = step;
  22 + this.calorie = calorie;
  23 + }
  24 + @Generated(hash = 1460309768)
  25 + public CalorieEntity() {
  26 + }
  27 + public String getUuid() {
  28 + return this.uuid;
  29 + }
  30 + public void setUuid(String uuid) {
  31 + this.uuid = uuid;
  32 + }
  33 + public String getUserId() {
  34 + return this.userId;
  35 + }
  36 + public void setUserId(String userId) {
  37 + this.userId = userId;
  38 + }
  39 + public String getCurrentDate() {
  40 + return this.currentDate;
  41 + }
  42 + public void setCurrentDate(String currentDate) {
  43 + this.currentDate = currentDate;
  44 + }
  45 + public String getStep() {
  46 + return this.step;
  47 + }
  48 + public void setStep(String step) {
  49 + this.step = step;
  50 + }
  51 + public String getCalorie() {
  52 + return this.calorie;
  53 + }
  54 + public void setCalorie(String calorie) {
  55 + this.calorie = calorie;
  56 + }
  57 +}
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/activity/RunRaceDetailActivity.java
... ... @@ -56,6 +56,9 @@ public class RunRaceDetailActivity extends QMUIFragmentActivity {
56 56 private String eventId;//赛道id
57 57 private int permissionRequestCount = 0;//权限请求次数
58 58 private SelectDialog selectDialog;
  59 + private boolean isFirstRequestNotification = true;//是否第一次检查通知权限
  60 + private boolean isFirstRequestGPS = true;//是否第一次检查GPS
  61 + private boolean isFirstRequestIgnore = true;//是否第一次设置电池优化白名单
59 62  
60 63 public static void startActivity(Activity activity, String eventId, String userId, String userIcon, String userName, String userPhone) {
61 64 Intent intent = new Intent(activity, RunRaceDetailActivity.class);
... ... @@ -131,26 +134,80 @@ public class RunRaceDetailActivity extends QMUIFragmentActivity {
131 134 CommonInfo.setStreetId(this, eventId);
132 135 Log.e("设置全局eventId", "onResume: " + eventId);
133 136 }
  137 + //链式检查各项权限
  138 + checkNotification();
  139 +
  140 +
  141 + }
  142 +
  143 + private void checkNotification() {
134 144 boolean isOpen = NotificationUtil.isOpenNotification(this);
135   - if (isOpen) {
136   - //判断GPS是否开启
137   - if (!MyMapUtil.isOPenGps(getApplicationContext())) {
138   - Toast.makeText(getApplicationContext(), getString(R.string.open_gps_tip), Toast.LENGTH_LONG).show();
  145 + //请求通知权限
  146 + if (isFirstRequestNotification) {
  147 + isFirstRequestNotification = false;
  148 + if (!isOpen) {
  149 + NotificationUtil.goToSettingNo(this);
  150 + } else {
  151 + //请求GPS权限
  152 + checkGPS();
  153 + }
  154 +
  155 + } else {
  156 + if (!isOpen) {
  157 + finish();
  158 + } else {
  159 + //请求GPS权限
  160 + checkGPS();
  161 + }
  162 + }
  163 + }
  164 +
  165 + /**
  166 + * 检查GPS
  167 + */
  168 + private void checkGPS() {
  169 + boolean isOpenGps = MyMapUtil.isOPenGps(getApplicationContext());
  170 + if (isFirstRequestGPS) {
  171 + isFirstRequestGPS = false;
  172 + if (!isOpenGps) {
139 173 //开启GPS
140 174 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
141 175 startActivityForResult(intent, 10);
  176 + Toast.makeText(getApplicationContext(), getString(R.string.open_gps_tip), Toast.LENGTH_LONG).show();
142 177 } else {
143   - boolean isSetBattery = CheckUtil.isIgnoringBatteryOptimizationss(RunRaceDetailActivity.this);
144   - if (!isSetBattery) {
145   - CheckUtil.toSetIgnore(this);
146   - } else {
147   - getPermissionsWithTip();
148   - }
  178 + checkIgnore();
  179 + }
  180 +
  181 + } else {
  182 + if (!isOpenGps) {
  183 + finish();
  184 + } else {
  185 + checkIgnore();
149 186 }
150   - }else {
151   - NotificationUtil.goToSettingNo(this);
152 187 }
  188 + }
153 189  
  190 + /**
  191 + * 检查白名单
  192 + */
  193 + private void checkIgnore() {
  194 + boolean isSetBattery = CheckUtil.isIgnoringBatteryOptimizationss(RunRaceDetailActivity.this);
  195 + if (isFirstRequestIgnore) {
  196 + isFirstRequestIgnore = false;
  197 + if (!isSetBattery) {
  198 + CheckUtil.toSetIgnore(this);
  199 + } else {
  200 + //检查权限
  201 + getPermissionsWithTip();
  202 + }
  203 + } else {
  204 + if (!isSetBattery) {
  205 + finish();
  206 + } else {
  207 + //检查权限
  208 + getPermissionsWithTip();
  209 + }
  210 + }
154 211 }
155 212  
156 213 /**
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/adapter/MyRecordAdapter.java
... ... @@ -40,7 +40,7 @@ public class MyRecordAdapter extends RecyclerView.Adapter&lt;MyRecordAdapter.MyView
40 40 this.clickListener = clickListener;
41 41 }
42 42  
43   - public MyRecordAdapter(List<MyRecordInfo.ListBean> list,String state,Activity context) {
  43 + public MyRecordAdapter(List<MyRecordInfo.ListBean> list, String state, Activity context) {
44 44 this.list = list;
45 45 this.state = state;
46 46 this.context = context;
... ... @@ -58,15 +58,20 @@ public class MyRecordAdapter extends RecyclerView.Adapter&lt;MyRecordAdapter.MyView
58 58 myViewHolder.my_record_ry.setVisibility(View.VISIBLE);
59 59 myViewHolder.has_report.setVisibility(View.GONE);
60 60 myViewHolder.my_record.setOnClickListener(v -> startAc(list.get(i)));
61   - myViewHolder.check_raking.setOnClickListener(v -> toRaking(list.get(i).getId()+""));
  61 + myViewHolder.check_raking.setOnClickListener(v -> toRaking(list.get(i).getId() + ""));
62 62  
63 63 if (clickListener != null) {
64 64 myViewHolder.item_ly.setOnClickListener(v -> clickListener.onClickListener(list.get(i), i));
65 65 }
66   -
  66 + if (!TextUtils.isEmpty(list.get(i).getE_subtitle())) {
  67 + myViewHolder.tv_second_title.setVisibility(View.VISIBLE);
  68 + myViewHolder.tv_second_title.setText(list.get(i).getE_subtitle());
  69 + } else {
  70 + myViewHolder.tv_second_title.setVisibility(View.GONE);
  71 + }
67 72 myViewHolder.line_name.setText(list.get(i).getTitle());
68 73 myViewHolder.activity_time.setText(TimeUtil.getStampToTime(list.get(i).getStart_time(), "yyyy.MM.dd") + "——" + TimeUtil.getStampToTime(list.get(i).getEnd_time(), "yyyy.MM.dd"));
69   - if (!TextUtils.isEmpty(list.get(i).getMileage())) {
  74 + if (!TextUtils.isEmpty(list.get(i).getMileage())) {
70 75 myViewHolder.line_address.setText(list.get(i).getAddress() + "\t\t全长" + list.get(i).getMileage() + "公里");
71 76 } else {
72 77 myViewHolder.line_address.setText(list.get(i).getAddress());
... ... @@ -83,41 +88,48 @@ public class MyRecordAdapter extends RecyclerView.Adapter&lt;MyRecordAdapter.MyView
83 88 } else {
84 89 myViewHolder.join_person.setVisibility(View.GONE);
85 90 }
86   - if(state.equals("0")){
  91 + if (!TextUtils.isEmpty(list.get(i).getE_subtitle())) {
  92 + myViewHolder.tv_second_title.setVisibility(View.VISIBLE);
  93 + myViewHolder.tv_second_title.setText(list.get(i).getE_subtitle());
  94 + } else {
  95 + myViewHolder.tv_second_title.setVisibility(View.GONE);
  96 +
  97 + }
  98 + if (state.equals("0")) {
87 99 myViewHolder.day_num.setVisibility(View.VISIBLE);
88 100 myViewHolder.after_finish.setVisibility(View.GONE);
89 101 myViewHolder.day_num.setText(list.get(i).getDay());
90   - if(list.get(i).getDay().contains("开始")){
  102 + if (list.get(i).getDay().contains("开始")) {
91 103 myViewHolder.my_record.setVisibility(View.GONE);
92 104 myViewHolder.check_raking.setVisibility(View.GONE);
93   - }else {
  105 + } else {
94 106 myViewHolder.my_record.setVisibility(View.VISIBLE);
95 107 myViewHolder.check_raking.setVisibility(View.VISIBLE);
96 108 }
97   - }else {
  109 + } else {
98 110 myViewHolder.day_num.setVisibility(View.GONE);
99 111 myViewHolder.after_finish.setVisibility(View.VISIBLE);
100 112 myViewHolder.after_finish.setText("已结束");
101 113 }
102 114 }
103 115  
104   - private void startAc(MyRecordInfo.ListBean listBean){
105   - CommonInfo.setStreetId(context,listBean.getId()+"");
106   - RaceRecordActivity.newInstance(context,listBean.getTitle());
  116 + private void startAc(MyRecordInfo.ListBean listBean) {
  117 + CommonInfo.setStreetId(context, listBean.getId() + "");
  118 + RaceRecordActivity.newInstance(context, listBean.getTitle());
107 119 }
108 120  
109   - private void toRaking(String eventId){
110   - String baseWebUrl,title;
111   - if(state.equals("0")){
  121 + private void toRaking(String eventId) {
  122 + String baseWebUrl, title;
  123 + if (state.equals("0")) {
112 124 title = "排行榜";
113 125 baseWebUrl = AppConfig.isDebug() ? "http://wjjh5test.cnlive.com/cnSportList.html" : "http://wjjh5.cnlive.com/cnSportList.html";
114   - }else {
  126 + } else {
115 127 title = "总排行榜";
116 128 baseWebUrl = AppConfig.isDebug() ? "http://wjjh5test.cnlive.com/cnSportListOver.html" : "http://wjjh5.cnlive.com/cnSportListOver.html";
117 129 }
118 130 ARouter.getInstance().build("/web/WebViewColorActivity")
119   - .withString("url", baseWebUrl +"?sid="+CommonInfo.getUserId(context)+"&eventId="+eventId)
120   - .withString("title",title)
  131 + .withString("url", baseWebUrl + "?sid=" + CommonInfo.getUserId(context) + "&eventId=" + eventId)
  132 + .withString("title", title)
121 133 .navigation(context);
122 134 }
123 135  
... ... @@ -140,6 +152,7 @@ public class MyRecordAdapter extends RecyclerView.Adapter&lt;MyRecordAdapter.MyView
140 152 TextView people_part;
141 153 TextView day_num;
142 154 TextView after_finish;
  155 + TextView tv_second_title;
143 156  
144 157 public MyViewHolder(@NonNull View itemView) {
145 158 super(itemView);
... ... @@ -155,6 +168,7 @@ public class MyRecordAdapter extends RecyclerView.Adapter&lt;MyRecordAdapter.MyView
155 168 people_part = itemView.findViewById(R.id.people_part);
156 169 day_num = itemView.findViewById(R.id.day_num);
157 170 after_finish = itemView.findViewById(R.id.after_finish);
  171 + tv_second_title = itemView.findViewById(R.id.tv_second_title);
158 172 }
159 173 }
160 174  
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/adapter/RunLineAdapter.java
... ... @@ -58,7 +58,12 @@ public class RunLineAdapter extends RecyclerView.Adapter&lt;RunLineAdapter.MyViewHo
58 58 if (clickListener != null) {
59 59 myViewHolder.item_ly.setOnClickListener(v -> clickListener.onClickListener(list.get(i), i));
60 60 }
61   -
  61 + if (!TextUtils.isEmpty(list.get(i).getE_subtitle())) {
  62 + myViewHolder.tv_second_title.setVisibility(View.VISIBLE);
  63 + myViewHolder.tv_second_title.setText(list.get(i).getE_subtitle());
  64 + } else {
  65 + myViewHolder.tv_second_title.setVisibility(View.GONE);
  66 + }
62 67 myViewHolder.line_name.setText(list.get(i).getTitle());
63 68 myViewHolder.activity_time.setText(TimeUtil.getStampToTime(list.get(i).getStart_time(), "yyyy.MM.dd") + "——" + TimeUtil.getStampToTime(list.get(i).getEnd_time(), "yyyy.MM.dd"));
64 69 if (!TextUtils.isEmpty(list.get(i).getMileage())) {
... ... @@ -97,6 +102,7 @@ public class RunLineAdapter extends RecyclerView.Adapter&lt;RunLineAdapter.MyViewHo
97 102 TextView activity_time;
98 103 TextView line_address;
99 104 TextView people_part;
  105 + TextView tv_second_title;
100 106  
101 107 public MyViewHolder(@NonNull View itemView) {
102 108 super(itemView);
... ... @@ -109,6 +115,7 @@ public class RunLineAdapter extends RecyclerView.Adapter&lt;RunLineAdapter.MyViewHo
109 115 activity_time = itemView.findViewById(R.id.activity_time);
110 116 line_address = itemView.findViewById(R.id.line_address);
111 117 people_part = itemView.findViewById(R.id.people_part);
  118 + tv_second_title = itemView.findViewById(R.id.tv_second_title);
112 119 }
113 120 }
114 121  
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/fragment/OnGoingFragment.java
... ... @@ -48,9 +48,9 @@ public class OnGoingFragment extends QMUIFragment&lt;OnGoingFragmentView, OnGoingFr
48 48 if (getMvpView() != null) {
49 49 getMvpView().initMap();
50 50 }
51   - if (null!=getArguments()){
52   - eventId=getArguments().getString("eventId");
53   - if (!TextUtils.isEmpty(eventId)){
  51 + if (null != getArguments()) {
  52 + eventId = getArguments().getString("eventId");
  53 + if (!TextUtils.isEmpty(eventId)) {
54 54 if (getPresenter() != null) {
55 55 if (!TextUtils.isEmpty(CommonInfo.getStreetId(getActivity()))) {
56 56 getPresenter().getRunRaceDetailInfo(getActivity(), eventId, CommonInfo.getUserId(getActivity()), "0");
... ... @@ -60,4 +60,28 @@ public class OnGoingFragment extends QMUIFragment&lt;OnGoingFragmentView, OnGoingFr
60 60 }
61 61  
62 62 }
  63 +
  64 + @Override
  65 + public void onResume() {
  66 + super.onResume();
  67 + if (null != getMvpView()) {
  68 + getMvpView().onResume();
  69 + }
  70 + }
  71 +
  72 + @Override
  73 + public void onPause() {
  74 + super.onPause();
  75 + if (null != getMvpView()) {
  76 + getMvpView().onPause();
  77 + }
  78 + }
  79 +
  80 + @Override
  81 + public void onDestroy() {
  82 + super.onDestroy();
  83 + if (null != getMvpView()) {
  84 + getMvpView().onDestroy();
  85 + }
  86 + }
63 87 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/fragment/RunMainFragment.java
... ... @@ -197,7 +197,7 @@ public class RunMainFragment extends QMUIFragment&lt;RunMainFragmentView, RunMainFr
197 197 mVibrator.vibrate(new long[]{Constant.VIBRATOR_DELAY_TIME, Constant.VIBRATOR_RUN_TIME, Constant.VIBRATOR_DELAY_TIME, Constant.VIBRATOR_RUN_TIME}, Constant.VIBRATOR_REPEAT_TIME);
198 198 }
199 199 if (tipDialog != null) {
200   - tipDialog.setTipMsg("您已偏离路径轨迹\n请您时回归路径!");
  200 + tipDialog.setTipMsg("您已偏离路径轨迹\n请您时回归路径!");
201 201 tipDialog.show();
202 202 }
203 203 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/fragment/RunRaceDetailFragment.java
... ... @@ -7,6 +7,7 @@ import android.support.annotation.Nullable;
7 7 import android.text.TextUtils;
8 8 import android.util.Log;
9 9 import android.view.View;
  10 +import android.view.ViewGroup;
10 11  
11 12 import com.cnlive.libs.base.ui.QMUIFragment;
12 13 import com.cnlive.libs.base.util.StatusBarUtil2;
... ... @@ -209,6 +210,18 @@ public class RunRaceDetailFragment extends QMUIFragment&lt;RunRaceDetailFragmentVie
209 210 }
210 211 if (getMvpView() != null && null != getPresenter()) {
211 212 if (!TextUtils.isEmpty(CommonInfo.getStreetId(getActivity()))) {
  213 + if (null != getMvpView()) {
  214 + try {
  215 + if (null != getMvpView().webView) {
  216 + if (getMvpView().webView.getParent() != null) {
  217 + ((ViewGroup) getMvpView().webView.getParent()).removeView(getMvpView().webView);
  218 + }
  219 + getMvpView().webView.destroy();
  220 + getMvpView().webView = null;
  221 + }
  222 + } catch (Exception e) {
  223 + }
  224 + }
212 225 getPresenter().getRunRaceDetailInfo(getActivity(), CommonInfo.getStreetId(getActivity()), CommonInfo.getUserId(getActivity()), "0");
213 226 }
214 227 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/ui/fragment/RunningMapFragment.java
... ... @@ -200,7 +200,7 @@ public class RunningMapFragment extends QMUIFragment&lt;RunningMapFragmentView, Run
200 200 mVibrator.vibrate(new long[]{Constant.VIBRATOR_DELAY_TIME, Constant.VIBRATOR_RUN_TIME, Constant.VIBRATOR_DELAY_TIME, Constant.VIBRATOR_RUN_TIME}, Constant.VIBRATOR_REPEAT_TIME);
201 201 }
202 202 if (tipDialog != null) {
203   - tipDialog.setTipMsg("您已偏离路径轨迹\n请您时回归路径!");
  203 + tipDialog.setTipMsg("您已偏离路径轨迹\n请您时回归路径!");
204 204 tipDialog.show();
205 205 }
206 206 }
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/utils/CheckUtil.java
... ... @@ -10,6 +10,7 @@ import android.provider.Settings;
10 10 import android.widget.Toast;
11 11  
12 12 import com.cnlive.libs.base.util.AlertUtil;
  13 +import com.example.moudle_pedometer.R;
13 14  
14 15 import static android.content.Context.POWER_SERVICE;
15 16  
... ... @@ -29,11 +30,12 @@ public class CheckUtil {
29 30 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
30 31 boolean hasIgnored = powerManager.isIgnoringBatteryOptimizations(context.getPackageName());
31 32 return hasIgnored;
  33 + } else {
  34 + return true;
32 35 }
33 36 } else {
34 37 return true;
35 38 }
36   - return false;
37 39 } catch (Exception e) {
38 40 return true;
39 41 }
... ... @@ -46,7 +48,7 @@ public class CheckUtil {
46 48 PackageManager pm = context.getPackageManager();
47 49 if (intent.resolveActivity(pm) != null) {
48 50 context.startActivity(intent);
49   - AlertUtil.showDeftToast(context, "请选择允许加入电池优化白名单,否则将会影响您的正常使用!");
  51 + Toast.makeText(context, "为保证功能正常使用,请选择允许加入电池优化白名单!", Toast.LENGTH_LONG).show();
50 52  
51 53 }
52 54 } catch (Exception e) {
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/utils/MyMapUtil.java
... ... @@ -594,20 +594,25 @@ public class MyMapUtil {
594 594 */
595 595 public static final boolean isOPenGps(final Context context) {
596 596 try {
597   - LocationManager locationManager
598   - = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
599   - // 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快)
600   - boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
601   - // 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位)
602   - boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
603   - if (gps) {
  597 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
  598 + LocationManager locationManager
  599 + = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
  600 + // 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快)
  601 + boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
  602 + // 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位)
  603 + boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
  604 + if (gps) {
  605 + return true;
  606 + } else {
  607 + return false;
  608 + }
  609 + } else {
604 610 return true;
605 611 }
606 612 } catch (Exception e) {
607 613 //异常就返回true
608 614 return true;
609 615 }
610   - return false;
611 616 }
612 617  
613 618 /**
... ... @@ -837,6 +842,10 @@ public class MyMapUtil {
837 842 polylineOptions = new PolylineOptions().width(10)
838 843 .color(context.getResources().getColor(lineColor)).points(points);
839 844 }
  845 + if (polylineOptions != null) {
  846 + resultOverlays.add(baiduMap.addOverlay(polylineOptions));
  847 +
  848 + }
840 849 if (endCircleOptions != null) {
841 850 resultOverlays.add(baiduMap.addOverlay(endCircleOptions));
842 851 }
... ... @@ -850,10 +859,7 @@ public class MyMapUtil {
850 859 if (endOptions != null) {
851 860 resultOverlays.add(baiduMap.addOverlay(endOptions));
852 861 }
853   - if (polylineOptions != null) {
854   - resultOverlays.add(baiduMap.addOverlay(polylineOptions));
855 862  
856   - }
857 863 if (resultOverlays != null) {
858 864 return resultOverlays;
859 865 } else {
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/utils/NotificationUtil.java
... ... @@ -17,14 +17,22 @@ public class NotificationUtil {
17 17 private static NotificationManagerCompat notificationManagerCompat;
18 18  
19 19 public static boolean isOpenNotification(Activity activity) {
20   - //监测通知权限是否打开
21   - notificationManagerCompat = NotificationManagerCompat.from(activity);
22   - isOpen = notificationManagerCompat.areNotificationsEnabled();
23   - return isOpen;
  20 + try {
  21 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
  22 + //监测通知权限是否打开
  23 + notificationManagerCompat = NotificationManagerCompat.from(activity);
  24 + isOpen = notificationManagerCompat.areNotificationsEnabled();
  25 + return isOpen;
  26 + } else {
  27 + return true;
  28 + }
  29 + } catch (Exception e) {
  30 + return true;
  31 + }
  32 +
24 33 }
25 34  
26 35 public static void goToSettingNo(Activity activity) {
27   - Toast.makeText(activity, "您尚未开启通知权限,无法进行计步", Toast.LENGTH_LONG).show();
28 36 Intent intent1 = new Intent();
29 37 try {
30 38 // 根据isOpened结果,判断是否需要提醒用户跳转AppInfo页面,去打开App通知权限
... ... @@ -47,6 +55,8 @@ public class NotificationUtil {
47 55 // // intent.setAction("com.android.settings/.SubSettings");
48 56 // }
49 57 activity.startActivity(intent1);
  58 + Toast.makeText(activity, "为保证功能正常使用,请开启通知!", Toast.LENGTH_LONG).show();
  59 +
50 60 } catch (Exception e) {
51 61 //其他低版本或者异常情况,走该节点。进入APP设置界面
52 62 intent1.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/utils/WebPreviewShowImg.java 0 → 100644
  1 +package com.cnlive.moudle.pedometer.utils;
  2 +
  3 +/**
  4 + * 作者: 吴奎庆
  5 + * <p>
  6 + * 时间: 2019/1/30
  7 + * <p>
  8 + * 简介:
  9 + */
  10 +public class WebPreviewShowImg {
  11 + public String getImgPath() {
  12 + return imgPath;
  13 + }
  14 +
  15 + public void setImgPath(String imgPath) {
  16 + this.imgPath = imgPath;
  17 + }
  18 +
  19 + public String getPreviewPath() {
  20 + return previewPath;
  21 + }
  22 +
  23 + public void setPreviewPath(String previewPath) {
  24 + this.previewPath = previewPath;
  25 + }
  26 +
  27 + private String imgPath;
  28 + private String previewPath;
  29 +}
... ...
moudle_pedometer/src/main/java/com/cnlive/moudle/pedometer/utils/WebViewUtil.java 0 → 100644
  1 +package com.cnlive.moudle.pedometer.utils;
  2 +
  3 +import android.app.Activity;
  4 +import android.text.TextUtils;
  5 +import android.util.Log;
  6 +import android.view.View;
  7 +import android.webkit.JavascriptInterface;
  8 +import android.webkit.WebView;
  9 +import android.webkit.WebViewClient;
  10 +
  11 +import com.alibaba.android.arouter.launcher.ARouter;
  12 +import com.cnlive.moudle.pedometer.frame.view.RunRaceDetailFragmentView;
  13 +import com.google.gson.Gson;
  14 +
  15 +import java.util.ArrayList;
  16 +
  17 +/**
  18 + * WebView中直接将p标签转为html代码
  19 + *
  20 + * @author ShinnyYang
  21 + */
  22 +public class WebViewUtil {
  23 + private static WebEleClickListener webEleListener;
  24 + private static Activity context;
  25 +
  26 + /**
  27 + * 将<p>标签转为html同时有回调
  28 + *
  29 + * @param pData
  30 + * @param webView
  31 + * @param webEleClickListener
  32 + */
  33 + public static void setPtoHtmlData(String pData, WebView webView, WebEleClickListener webEleClickListener) {
  34 + if (null != webView) {
  35 + webEleListener = webEleClickListener;
  36 + String html = "<html><head><meta charset=\"UTF-8\"><style type=\"text/css\">html,body{padding:0px;margin:0px;font-size:40px} img{background-size:contain|cover;width:100%;height: auto;} p{margin:0px;font-size:40px}</style></head><body>" + pData + "</body></html>";
  37 + // 设置支持javascript脚本
  38 + webView.getSettings().setJavaScriptEnabled(true);
  39 + webView.addJavascriptInterface(new JsObject(), "injectedObject");
  40 + webView.setWebViewClient(new WebViewClient() {
  41 + @Override
  42 + public void onPageFinished(WebView view, String url) {
  43 + super.onPageFinished(view, url);
  44 + String js = "javascript:(function(){" +
  45 + "var images = document.getElementsByTagName(\"img\");" +
  46 + "var imageUrls = new Array(); " +
  47 + "for(var i=0; i<images.length; i++) {" +
  48 + " imageUrls[i] = images[i].src; " +
  49 + " images[i].pos = i; " +
  50 + " images[i].onclick = function(){" +
  51 + " window.injectedObject.openImage(this.src, this.pos);" +
  52 + " }" +
  53 + "}" +
  54 + "window.injectedObject.setImageUrls(imageUrls); " +
  55 + "})()";
  56 + webView.loadUrl(js);
  57 + }
  58 + });
  59 + webView.loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
  60 + }
  61 + }
  62 +
  63 + /**
  64 + * 将<p>标签转为html没有回调,直接跳转
  65 + *
  66 + * @param activity
  67 + * @param pData
  68 + * @param webView
  69 + */
  70 + public static void setPtoHtmlData(Activity activity, String pData, WebView webView) {
  71 + if (null != webView) {
  72 + context = activity;
  73 + String html = "<html><head><meta charset=\"UTF-8\"><style type=\"text/css\">html,body{padding:0px;margin:0px;font-size:40px} img{background-size:contain|cover;width:100%;height: auto;} p{margin:0px;font-size:40px}</style></head><body>" + pData + "</body></html>";
  74 + // 设置支持javascript脚本
  75 + webView.getSettings().setJavaScriptEnabled(true);
  76 + webView.addJavascriptInterface(new JsObject(), "injectedObject");
  77 + webView.setWebViewClient(new WebViewClient() {
  78 + @Override
  79 + public void onPageFinished(WebView view, String url) {
  80 + super.onPageFinished(view, url);
  81 + String js = "javascript:(function(){" +
  82 + "var images = document.getElementsByTagName(\"img\");" +
  83 + "var imageUrls = new Array(); " +
  84 + "for(var i=0; i<images.length; i++) {" +
  85 + " imageUrls[i] = images[i].src; " +
  86 + " images[i].pos = i; " +
  87 + " images[i].onclick = function(){" +
  88 + " window.injectedObject.openImage(this.src, this.pos);" +
  89 + " }" +
  90 + "}" +
  91 + "window.injectedObject.setImageUrls(imageUrls); " +
  92 + "})()";
  93 + webView.loadUrl(js);
  94 + }
  95 + });
  96 + webView.loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
  97 + }
  98 + }
  99 +
  100 + /**
  101 + * 将<p>标签转为html没有回调,直接跳转,可指定文字大小
  102 + *
  103 + * @param activity
  104 + * @param pData
  105 + * @param webView
  106 + * @param fontSize 字体大小
  107 + */
  108 + public static void setPtoHtmlData(Activity activity, String pData, WebView webView, int fontSize) {
  109 + if (null != webView) {
  110 + context = activity;
  111 +
  112 + String html = "<html><head><meta charset=\"UTF-8\"><style type=\"text/css\">html,body{padding:0px;margin:0px;font-size:" + fontSize + "px} img{background-size:contain|cover;width:100%;height: auto;} p{margin:0px;font-size:" + fontSize + "px}</style></head><body>" + pData + "</body></html>";
  113 + // 设置支持javascript脚本
  114 + webView.getSettings().setJavaScriptEnabled(true);
  115 + webView.addJavascriptInterface(new JsObject(), "injectedObject");
  116 + webView.setWebViewClient(new WebViewClient() {
  117 + @Override
  118 + public void onPageFinished(WebView view, String url) {
  119 + super.onPageFinished(view, url);
  120 + int w = View.MeasureSpec.makeMeasureSpec(0,
  121 + View.MeasureSpec.UNSPECIFIED);
  122 + int h = View.MeasureSpec.makeMeasureSpec(0,
  123 + View.MeasureSpec.UNSPECIFIED);
  124 + // 重新测量
  125 + view.measure(w, h);
  126 + String js = "javascript:(function(){" +
  127 + "var images = document.getElementsByTagName(\"img\");" +
  128 + "var imageUrls = new Array(); " +
  129 + "for(var i=0; i<images.length; i++) {" +
  130 + " imageUrls[i] = images[i].src; " +
  131 + " images[i].pos = i; " +
  132 + " images[i].onclick = function(){" +
  133 + " window.injectedObject.openImage(this.src, this.pos);" +
  134 + " }" +
  135 + "}" +
  136 + "window.injectedObject.setImageUrls(imageUrls); " +
  137 + "})()";
  138 + webView.loadUrl(js);
  139 + }
  140 +
  141 + });
  142 + webView.loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
  143 + }
  144 + }
  145 +
  146 + public interface WebEleClickListener {
  147 + void onImageClick(String src, int pos, String[] mImageUrls);
  148 + }
  149 +
  150 +
  151 + private static class JsObject {
  152 +
  153 + private String[] mImageUrls;
  154 +
  155 + @JavascriptInterface
  156 + public void setImageUrls(String[] imageUrls) {
  157 + this.mImageUrls = imageUrls;
  158 + }
  159 +
  160 + @JavascriptInterface
  161 + public void openImage(String src, int pos) {
  162 + if (null != webEleListener) {
  163 + webEleListener.onImageClick(src, pos, this.mImageUrls);
  164 + }
  165 + if (null != context) {
  166 + if (null != src && !TextUtils.isEmpty(src) && null != mImageUrls) {
  167 + ArrayList<String> imgs = new ArrayList<>();
  168 + for (String imageUrl : mImageUrls) {
  169 + imgs.add(imageUrl);
  170 + }
  171 + if (null != imgs && imgs.size() > 0) {
  172 + previewImg(context, src, imgs);
  173 + }
  174 + }
  175 + }
  176 + }
  177 + }
  178 +
  179 + /**
  180 + * 跳转到图片预览页面
  181 + *
  182 + * @param activity
  183 + * @param showImg
  184 + * @param imgs
  185 + */
  186 + public static void previewImg(Activity activity, String showImg, ArrayList<String> imgs) {
  187 + Gson gson = new Gson();
  188 + WebPreviewShowImg imagePreviewShowInfo = new WebPreviewShowImg();
  189 + imagePreviewShowInfo.setPreviewPath("");
  190 + imagePreviewShowInfo.setImgPath(showImg);
  191 + String ss = gson.toJson(imagePreviewShowInfo);
  192 + ArrayList<String> list = new ArrayList<>();
  193 + if (imgs != null) {
  194 + for (int i = 0; i < imgs.size(); i++) {
  195 + WebPreviewShowImg info = new WebPreviewShowImg();
  196 + info.setImgPath(imgs.get(i));
  197 + info.setPreviewPath("");
  198 + Gson gsonInfo = new Gson();
  199 + String ins = gsonInfo.toJson(info);
  200 + list.add(ins);
  201 + }
  202 + }
  203 + ARouter.getInstance().build("/preview/PreviewImageViewActivity")
  204 + .withString("type", "htmlImg")
  205 + .withTransition(android.R.anim.fade_in, android.R.anim.fade_out)
  206 + .withString("collectionType", "moment")
  207 + .withString("previewUrl", ss)
  208 + .withStringArrayList("preImgList", list)
  209 + .withBoolean("isFriend", false)
  210 + .withBoolean("isHide", false)
  211 + .withBoolean("isLife", false)
  212 + .withBoolean("isCollection", false)
  213 + .navigation(activity);
  214 + }
  215 +}
... ...
moudle_pedometer/src/main/res/drawable-hdpi/icon_end.png 0 → 100644

2.54 KB

moudle_pedometer/src/main/res/drawable-hdpi/icon_end.webp deleted 100644 → 0
No preview for this file type
moudle_pedometer/src/main/res/drawable-hdpi/icon_start.png 0 → 100644

3.18 KB

moudle_pedometer/src/main/res/drawable-hdpi/icon_start.webp deleted 100644 → 0
No preview for this file type
moudle_pedometer/src/main/res/drawable-xhdpi/icon_end.png 0 → 100644

3.06 KB

moudle_pedometer/src/main/res/drawable-xhdpi/icon_end.webp deleted 100644 → 0
No preview for this file type
moudle_pedometer/src/main/res/drawable-xhdpi/icon_start.png 0 → 100644

3.7 KB

moudle_pedometer/src/main/res/drawable-xhdpi/icon_start.webp deleted 100644 → 0
No preview for this file type
moudle_pedometer/src/main/res/drawable-xxhdpi/icon_end.png 0 → 100644

5.89 KB

moudle_pedometer/src/main/res/drawable-xxhdpi/icon_end.webp deleted 100644 → 0
No preview for this file type
moudle_pedometer/src/main/res/drawable-xxhdpi/icon_start.png 0 → 100644

7.26 KB

moudle_pedometer/src/main/res/drawable-xxhdpi/icon_start.webp deleted 100644 → 0
No preview for this file type
moudle_pedometer/src/main/res/layout/custom_step_notification.xml
... ... @@ -64,16 +64,33 @@
64 64 android:layout_width="match_parent"
65 65 android:layout_height="wrap_content"
66 66 android:paddingLeft="10dp"
67   - android:text="用时"
  67 + android:text="卡路里"
68 68 android:textColor="#707070"
69 69 android:textSize="14sp" />
70 70  
71   - <Chronometer
72   - android:id="@+id/ch"
  71 + <LinearLayout
73 72 android:layout_width="match_parent"
74 73 android:layout_height="wrap_content"
75   - android:textColor="#707070"
76   - android:textSize="20sp" />
  74 + android:gravity="bottom">
  75 +
  76 + <TextView
  77 + android:id="@+id/tv_calorie"
  78 + android:layout_width="wrap_content"
  79 + android:layout_height="wrap_content"
  80 + android:layout_gravity="left"
  81 + android:layout_marginLeft="5dp"
  82 + android:text="0"
  83 + android:textColor="#707070"
  84 + android:textSize="20sp" />
  85 +
  86 + <TextView
  87 + android:layout_width="wrap_content"
  88 + android:layout_height="wrap_content"
  89 + android:layout_marginLeft="10dp"
  90 + android:text="千卡"
  91 + android:textColor="#707070"
  92 + android:textSize="14sp" />
  93 + </LinearLayout>
77 94 </LinearLayout>
78 95  
79 96 <LinearLayout
... ...
moudle_pedometer/src/main/res/layout/fragment_run_race_detail.xml
... ... @@ -11,7 +11,7 @@
11 11 android:layout_width="match_parent"
12 12 android:layout_height="match_parent"
13 13 android:gravity="bottom"
14   - sothree:umanoDragView="@+id/dragView"
  14 + sothree:umanoDragView="@+id/scrollView"
15 15 sothree:umanoFadeColor="@color/black_20"
16 16 sothree:umanoOverlay="true"
17 17 sothree:umanoParallaxOffset="400dp"
... ...
moudle_pedometer/src/main/res/layout/item_my_record.xml
... ... @@ -19,11 +19,23 @@
19 19 android:id="@+id/line_name"
20 20 android:layout_width="wrap_content"
21 21 android:layout_height="wrap_content"
22   - android:textColor="#333333"
23   - android:singleLine="true"
24 22 android:layout_marginRight="25dp"
  23 + android:singleLine="true"
  24 + android:textColor="#333333"
25 25 android:textSize="18sp" />
26 26  
  27 + <TextView
  28 + android:id="@+id/tv_second_title"
  29 + android:layout_width="wrap_content"
  30 + android:layout_height="wrap_content"
  31 + android:layout_marginLeft="1dp"
  32 + android:layout_marginTop="3dp"
  33 + android:layout_marginRight="25dp"
  34 + android:singleLine="true"
  35 + android:textColor="@color/text_gray"
  36 + android:textSize="15sp"
  37 + android:visibility="gone" />
  38 +
27 39 <LinearLayout
28 40 android:layout_width="match_parent"
29 41 android:layout_height="wrap_content"
... ...
moudle_pedometer/src/main/res/layout/item_record.xml
... ... @@ -19,6 +19,18 @@
19 19 android:singleLine="true"
20 20 android:textColor="#333333"
21 21 android:textSize="18sp" />
  22 + <!--二级标题-->
  23 + <TextView
  24 + android:id="@+id/tv_second_title"
  25 + android:layout_width="wrap_content"
  26 + android:layout_height="wrap_content"
  27 + android:layout_marginLeft="1dp"
  28 + android:layout_marginTop="5dp"
  29 + android:maxLines="1"
  30 + android:text="--"
  31 + android:visibility="gone"
  32 + android:textColor="@color/text_gray"
  33 + android:textSize="15sp" />
22 34  
23 35 <LinearLayout
24 36 android:layout_width="match_parent"
... ... @@ -38,8 +50,8 @@
38 50 android:id="@+id/activity_time"
39 51 android:layout_width="wrap_content"
40 52 android:layout_height="wrap_content"
41   - android:singleLine="true"
42 53 android:layout_marginLeft="10dp"
  54 + android:singleLine="true"
43 55 android:textColor="#999999"
44 56 android:textSize="12sp" />
45 57 </LinearLayout>
... ... @@ -63,8 +75,8 @@
63 75 android:layout_width="wrap_content"
64 76 android:layout_height="wrap_content"
65 77 android:layout_marginLeft="10dp"
66   - android:textColor="#999999"
67 78 android:singleLine="true"
  79 + android:textColor="#999999"
68 80 android:textSize="12sp" />
69 81 </LinearLayout>
70 82  
... ... @@ -92,6 +104,7 @@
92 104 android:layout_width="wrap_content"
93 105 android:layout_height="wrap_content"
94 106 android:layout_marginRight="10dp"
  107 + android:layout_marginBottom="5dp"
95 108 android:layout_toLeftOf="@id/path_list"
96 109 android:background="@drawable/green_raduis_bg"
97 110 android:paddingLeft="12dp"
... ... @@ -100,7 +113,6 @@
100 113 android:paddingBottom="7dp"
101 114 android:text="添加轨迹"
102 115 android:textColor="#36C28D"
103   - android:layout_marginBottom="5dp"
104 116 android:textSize="12sp" />
105 117  
106 118 </RelativeLayout>
... ...
moudle_pedometer/src/main/res/layout/layout_collect_run_detail_street.xml
... ... @@ -42,6 +42,17 @@
42 42 android:textColor="@color/text_black"
43 43 android:textSize="18sp"
44 44 android:textStyle="bold" />
  45 + <!--二级标题-->
  46 + <TextView
  47 + android:id="@+id/tv_second_title"
  48 + android:layout_width="wrap_content"
  49 + android:layout_height="wrap_content"
  50 + android:layout_marginLeft="11dp"
  51 + android:layout_marginTop="5dp"
  52 + android:text="--"
  53 + android:textColor="@color/text_gray"
  54 + android:textSize="15sp"
  55 + android:visibility="gone" />
45 56 <!--活动地点-->
46 57 <LinearLayout
47 58 android:layout_width="match_parent"
... ...
moudle_pedometer/src/main/res/layout/layout_run_detail_street.xml
... ... @@ -45,6 +45,17 @@
45 45 android:textColor="@color/text_black"
46 46 android:textSize="18sp"
47 47 android:textStyle="bold" />
  48 + <!--二级标题-->
  49 + <TextView
  50 + android:id="@+id/tv_second_title"
  51 + android:layout_width="wrap_content"
  52 + android:layout_height="wrap_content"
  53 + android:layout_marginLeft="11dp"
  54 + android:layout_marginTop="5dp"
  55 + android:text="--"
  56 + android:textColor="@color/text_gray"
  57 + android:textSize="15sp"
  58 + android:visibility="gone" />
48 59 <!--活动地点-->
49 60 <LinearLayout
50 61 android:layout_width="match_parent"
... ... @@ -446,8 +457,8 @@
446 457 android:id="@+id/five_join_person"
447 458 android:layout_width="180dp"
448 459 android:layout_height="40dp"
449   - android:gravity="right"
450 460 android:layout_marginRight="10dp"
  461 + android:gravity="right"
451 462 FivePersonIconView:showRightFlag="true" />
452 463  
453 464  
... ...
moudle_pedometer/src/main/res/layout/layout_run_detail_street_introduce.xml
... ... @@ -18,16 +18,23 @@
18 18 android:textSize="18sp"
19 19 android:textStyle="bold" />
20 20  
21   - <TextView
22   - android:id="@+id/tv_street_introduce"
23   - android:layout_width="wrap_content"
  21 + <!--<TextView-->
  22 + <!--android:id="@+id/tv_street_introduce"-->
  23 + <!--android:layout_width="wrap_content"-->
  24 + <!--android:layout_height="wrap_content"-->
  25 + <!--android:layout_marginTop="10dp"-->
  26 + <!--android:layout_marginRight="10dp"-->
  27 + <!--android:text="&#45;&#45;"-->
  28 + <!--android:textColor="@color/text_black"-->
  29 + <!--android:textSize="15sp" />-->
  30 +
  31 + <LinearLayout
  32 + android:id="@+id/ll_webview"
  33 + android:layout_width="match_parent"
24 34 android:layout_height="wrap_content"
25 35 android:layout_marginTop="10dp"
26   - android:layout_marginRight="10dp"
27   - android:text="--"
28   - android:textColor="@color/text_black"
29   - android:textSize="15sp" />
30   -
  36 + android:descendantFocusability="blocksDescendants"
  37 + android:orientation="vertical"></LinearLayout>
31 38 <!--地图-->
32 39 <TextView
33 40 android:layout_width="wrap_content"
... ...
moudle_pedometer/src/main/res/values/strings.xml
... ... @@ -68,7 +68,7 @@
68 68 <string name="loc_gps_accuracy_mid">GPS信号质量中等</string>
69 69 <string name="loc_gps_accuracy_good">GPS信号质量好</string>
70 70 <string name="layout_street_active_type">活动类型</string>
71   - <string name="open_gps_tip">请开启GPS,将其设置为高精度模式!</string>
  71 + <string name="open_gps_tip">为确保定位准确性,请开启GPS,将其设置为高精度模式!</string>
72 72 <!---->
73 73 <!--网络请求-->
74 74 <string name="retry">重试</string>
... ...