feat: 线型手动拍摄增加照片检查功能

This commit is contained in:
xiaoyan 2023-04-06 17:08:26 +08:00
parent ae2f4705d9
commit 6a5b6a5f19
29 changed files with 558 additions and 318 deletions

View File

@ -18,7 +18,7 @@ android {
minSdkVersion 24
targetSdkVersion 30
versionCode 50
versionName "8.230328-开发版"
versionName "8.230406-测试版"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
@ -80,9 +80,9 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.android.material:material:1.6.0'
implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'

View File

@ -1,6 +1,7 @@
package com.navinfo.outdoor.activity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -14,6 +15,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@ -31,10 +33,12 @@ import androidx.annotation.RequiresApi;
import com.elvishew.xlog.XLog;
import com.github.lazylibrary.util.FileUtils;
import com.google.gson.Gson;
import com.kongzue.dialog.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialog.util.BaseDialog;
import com.kongzue.dialog.util.DialogSettings;
import com.kongzue.dialog.v3.MessageDialog;
import com.lzy.okgo.model.HttpParams;
import com.navinfo.ocr.OCRManager;
import com.navinfo.ocr.model.OcrViewResultModel;
import com.navinfo.outdoor.R;
@ -42,7 +46,12 @@ import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.api.UserApplication;
import com.navinfo.outdoor.base.BaseActivity;
import com.navinfo.outdoor.bean.LocationRecorder;
import com.navinfo.outdoor.bean.TaskNameBean;
import com.navinfo.outdoor.http.Callback;
import com.navinfo.outdoor.http.HttpInterface;
import com.navinfo.outdoor.http.OkGoBuilder;
import com.navinfo.outdoor.util.BitmapUtil;
import com.navinfo.outdoor.util.FlushTokenUtil;
import com.navinfo.outdoor.util.GPSUtils;
import com.navinfo.outdoor.util.Geohash;
import com.navinfo.outdoor.util.GeometryTools;
@ -147,7 +156,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
// private Timer timer;
// private TimerTask timerTask;
private Disposable disposable; // RxJava循环拍照的控制对象
private FlowableEmitter<PictureResult> pictureEmitter; // RxJava控制照片生成
private FlowableEmitter<Map<String, Object>> pictureEmitter; // RxJava控制照片生成
private SystemTTS systemTTS;
private StringBuilder picturesBuilder;
private LatLng startLatLine, endLatLine;
@ -168,6 +177,8 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
private TextView tvDegrees;
private PicturesSpeedCheck speedCheck;
private PictureCheckHelper pictureCheckHelper; // 照片辅助检查帮助类
private Gson gson;
private int emitterPictureIndex, dealPictureIndex; // 发送的照片Index和已处理的照片Index用来判断照片处理是否完成
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
@ -209,7 +220,8 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
}
});
speedCheck = new PicturesSpeedCheck();
pictureCheckHelper = new PictureCheckHelper();
pictureCheckHelper = new PictureCheckHelper(PicturesActivity.this);
gson = new Gson();
}
@Override
@ -330,7 +342,6 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
picturesBuilder.append(TimestampUtil.time()).append(",").append("capturePicture 点击了拍摄 ,");
}
startTakePhoto(radioPicture);
startTakePhoto(radioPicture);
} else {
if (radioPicture != 1) {
capturePicture.setText("开始采集");
@ -398,26 +409,31 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
}
});
Flowable<PictureResult> pictureResultFlowable = Flowable.create(new FlowableOnSubscribe<PictureResult>() {
Flowable<Map<String, Object>> pictureResultFlowable = Flowable.create(new FlowableOnSubscribe<Map<String, Object>>() {
@Override
public void subscribe(FlowableEmitter<PictureResult> emitter) throws Exception {
public void subscribe(FlowableEmitter<Map<String, Object>> emitter) throws Exception {
pictureEmitter = emitter;
}
}, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io());
Flowable<Integer> integerFlowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) {
for (int i = videoIndex; ; i++) { // 标记当前是第几个图片记录Index
emitter.onNext(i);
}
}
}, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io());
Flowable.zip(pictureResultFlowable, integerFlowable, new BiFunction<PictureResult, Integer, Map>(){
// Flowable<Integer> integerFlowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
// @Override
// public void subscribe(FlowableEmitter<Integer> emitter) {
// for (int i = videoIndex; ; i++) { // 标记当前是第几个图片记录Index
// emitter.onNext(i);
// emitterPictureIndex = i;
// Log.d("int", "发送:"+i);
// }
// }
// }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io());
pictureResultFlowable.subscribeOn(Schedulers.io()) // 指定上游为IO线程
.observeOn(Schedulers.io())
.doOnNext(new Consumer<Map<String, Object>>() {
@Override
public Map<String, Object> apply(PictureResult pictureResult, Integer fileIndex) throws Exception { // 将图片转为File文件
public void accept(Map<String, Object> map) throws Exception {
int fileIndex = (int) map.get("index");
PictureResult pictureResult = (PictureResult) map.get("picture");
// 图片和paper.txt处理
File currentFile = new File(paperFile.getParentFile().getAbsolutePath() + "/" + fileIndex + ".webp");
CameraUtils.writeToFile(pictureResult.getData(), currentFile); // 生成照片文件
@ -437,13 +453,8 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
recorder.setRssi(GPSUtils.getInstance(PicturesActivity.this).getSateliteCount());
recorder.setSatelliteCount(GPSUtils.getInstance(PicturesActivity.this).getSateliteCount());
FileUtils.writeFile(paperFile.getAbsolutePath(), recorder.toString(formatter, fileIndex), true);
Map<String, Object> map = new HashMap<>();
map.put("index", fileIndex);
map.put("picture", pictureResult);
return map;
}
})
.subscribeOn(Schedulers.io()) // 指定上游为IO线程
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(new Consumer<Map>() {
@Override
@ -455,55 +466,21 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
}
})
.observeOn(Schedulers.computation())// 开始进行图片辅助判定
.subscribe(new FlowableSubscriber<Map>() {
.subscribe(new FlowableSubscriber<Map<String, Object>>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Integer.MAX_VALUE);
}
@Override
public void onNext(Map map) {
int index = Integer.parseInt(map.get("index").toString());
PictureResult pictureResult = (PictureResult) map.get("picture");
// 如果当前拍照是POI拍照模式才需要做ocr识别以及附近POI查询
if (type == 3) {
// 开始ocr文字识别
List<OcrViewResultModel> ocrViewResultModels = OCRManager.Companion.getInstance().ocr(BitmapUtil.getBitmapFromBytes(pictureResult.getData()));
if (ocrViewResultModels!=null&&!ocrViewResultModels.isEmpty()) {
pictureCheckHelper.addocrCheck(true);
// 该照片存在文字信息获取占比最大的文字为后续POI判定做准备
OcrViewResultModel maxOcrViewResult = ocrViewResultModels.stream()
.max(new Comparator<OcrViewResultModel>() {
@Override
public int compare(OcrViewResultModel t0, OcrViewResultModel t1) {
int t0Value = Math.abs(t0.getBounds().get(2).x-t0.getBounds().get(0).x)
* Math.abs(t0.getBounds().get(2).y-t0.getBounds().get(0).y);
int t1Value = Math.abs(t1.getBounds().get(2).x-t1.getBounds().get(0).x)
* Math.abs(t1.getBounds().get(2).y-t1.getBounds().get(0).y);
if (t0Value>t1Value) {
return 1;
} else if (t0Value<t1Value){
return -1;
}
return 0;
}
})
.get();
// 周边搜索判定周边POI是否存在
if (pictureCheckHelper.getCheckResult().getNearestChecked()<3) {
// 发送请求查询周边POI是否存在
}
} else {
pictureCheckHelper.addocrCheck(false);
}
}
public void onNext(Map<String, Object> map) {
pictureCheckHelper.savePictureCheckResult((Activity) PicturesActivity.this, new Gson(), type, map,
checkFile, sensorOritationLifecycle.getYDegree(), currentSpeed, false);
// 获取当前手机姿态判定该照片手机姿态是否合格
float yDegree = sensorOritationLifecycle.getYDegree();
if (yDegree>-90-45&&yDegree<-90+45) {
}
// 记录当前完成多少个图片的处理
int index = Integer.parseInt(map.get("index").toString());
dealPictureIndex = index;
}
@Override
@ -550,7 +527,11 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
}
if (pictureEmitter!=null) {
pictureEmitter.onNext(result);
Map<String, Object> map = new HashMap();
emitterPictureIndex = videoIndex;
map.put("index", videoIndex++);
map.put("picture", result);
pictureEmitter.onNext(map);
}
} else {
isBack = false;
@ -1089,26 +1070,24 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
}
private boolean isSpeedLimitTips = false;
private boolean hasSpeakSpeedLimit = false; // 是否已经播报过速度提醒
private double currentSpeed = 0f;
private void initSpeed() {
if (!systemTTS.isSpeaking()) {
isSpeedLimitTips = false;
}
if (isSpeedLimitTips == true || LocationLifeCycle.getInstance().getMainLocation() == null) {
if (/*isSpeedLimitTips == true || */LocationLifeCycle.getInstance().getMainLocation() == null) {
return;
}
float speed = LocationLifeCycle.getInstance().getMainLocation().getSpeed();///
if (speed != 0) {
float a = (speed * 3600 / 1000);//km/h
currentSpeed = (speed * 3600 / 1000);//km/h
if (type == 3) {
if (a > 40) {//40千米/h
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
if (currentSpeed > 40) {//40千米/h
isSpeedLimitTips=true;
}
} else if (type == 4) {
if (a > 80) {//80千米/h
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
if (currentSpeed > 80) {//80千米/h
isSpeedLimitTips=true;
}
}
@ -1119,40 +1098,37 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
double geometry = GeometryTools.distanceToDouble(startLatLng, endLatLng);//
if (type == 3) {
if (radioPicture == 2) {
double speeds = ((geometry / 1) * 3600 / 1000);
if (speeds > 40) {//40千米/h
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
currentSpeed = ((geometry / 1) * 3600 / 1000);
if (currentSpeed > 40) {//40千米/h
isSpeedLimitTips=true;
}
} else if (radioPicture == 3) {
double speeds = ((geometry / 2) * 3600 / 1000);
if (speeds > 40) {//40千米/h
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
currentSpeed = ((geometry / 2) * 3600 / 1000);
if (currentSpeed > 40) {//40千米/h
isSpeedLimitTips=true;
}
}
} else if (type == 4) {
if (radioPicture == 2) {
double speeds = ((geometry / 1) * 3600 / 1000);
if (speeds > 80) { //80千米/h
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
currentSpeed = ((geometry / 1) * 3600 / 1000);
if (currentSpeed > 80) { //80千米/h
isSpeedLimitTips=true;
}
} else if (radioPicture == 3) {
double speeds = ((geometry / 2) * 3600 / 1000);
if (speeds > 80) { //80千米/h
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
currentSpeed = ((geometry / 2) * 3600 / 1000);
if (currentSpeed > 80) { //80千米/h
isSpeedLimitTips=true;
}
}
}
}
oldCurrentLocation = LocationLifeCycle.getInstance().getMainLocation();
}
if (!hasSpeakSpeedLimit&&isSpeedLimitTips) {
systemTTS.stopSpeak();
systemTTS.playText("您已超速");
hasSpeakSpeedLimit = true;
}
oldCurrentLocation = LocationLifeCycle.getInstance().getMainLocation();
}
@Override
@ -1208,7 +1184,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
public void onComplete() {
dismissLoadingDialog();
Intent intent = new Intent();
finalVideoPath = Objects.requireNonNull(paperFile.getParentFile()).getAbsolutePath() + "/" + videoIndex + ".webp";
finalVideoPath = Objects.requireNonNull(paperFile.getParentFile()).getAbsolutePath() + "/" + (videoIndex-1) + ".webp";
intent.putExtra(Constant.INTENT_PICTURES_PATH, finalVideoPath);
setResult(0x111, intent);
PicturesActivity.this.finish();

View File

@ -3,12 +3,18 @@ package com.navinfo.outdoor.fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.github.lazylibrary.util.PreferencesUtils;
import com.kongzue.dialogx.dialogs.CustomDialog;
import com.kongzue.dialogx.interfaces.OnBindView;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.activity.AutoTakePicture4PoiVideoActivity;
import com.navinfo.outdoor.activity.RegardMapActivity;
import com.navinfo.outdoor.activity.WebActivity;
import com.navinfo.outdoor.base.BaseFragment;
@ -20,7 +26,9 @@ import java.util.Objects;
* 我的-关于页面的fragment
*/
public class AboutFragment extends BaseFragment implements View.OnClickListener {
private View layerSetting; // 设置对应的布局默认隐藏用户连击logo显示
private long lastClickTime = 0;
private int settingHookClickCount = 1;
public static AboutFragment newInstance(Bundle bundle) {
AboutFragment fragment = new AboutFragment();
fragment.setArguments(bundle);
@ -46,13 +54,103 @@ public class AboutFragment extends BaseFragment implements View.OnClickListener
RelativeLayout rlPrivilege = findViewById(R.id.rl_privilege);
ImageView ivAboutFinish = findViewById(R.id.iv_about_finish);
ivAboutFinish.setOnClickListener(this);
ImageView imgLogo = findViewById(R.id.img_logo);
layerSetting = findViewById(R.id.layer_setting);
imgLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (layerSetting.isShown()) {
return;
}
settingHookClickCount++;
if(lastClickTime > 0){
long secondClickTime = System.currentTimeMillis();//距离上次开机时间
long dtime = secondClickTime - lastClickTime;
if(dtime <800){
if (settingHookClickCount>8) {
Toast.makeText(requireActivity(), "打开设置功能", Toast.LENGTH_SHORT).show();
layerSetting.setVisibility(View.VISIBLE);
} else {
if (settingHookClickCount>3) {
Toast.makeText(requireActivity(), "再点击"+(9-settingHookClickCount)+"下打开设置功能", Toast.LENGTH_SHORT).show();
}
}
} else{
lastClickTime = 0;
settingHookClickCount = 1;
}
}
lastClickTime = System.currentTimeMillis();
}
});
// 图像检查参数设置
findViewById(R.id.rl_picture_check_setting).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomDialog.build()
.setAlign(CustomDialog.ALIGN.CENTER)
.setMaskColor(getResources().getColor(R.color.black25))
.setCustomView(new OnBindView<CustomDialog>(R.layout.dialog_picture_check_setting) {
@Override
public void onBind(CustomDialog dialog, View v) {
EditText sensorDegree = v.findViewById(R.id.sensor_degree);
EditText poiMinSpeed = v.findViewById(R.id.poi_speed_min);
EditText poiMaxSpeed = v.findViewById(R.id.poi_speed_max);
EditText roadMinSpeed = v.findViewById(R.id.road_speed_min);
EditText roadMaxSpeed = v.findViewById(R.id.road_speed_max);
EditText satelliteCount = v.findViewById(R.id.satellite_count);
sensorDegree.setText(PreferencesUtils.getString(requireContext(), "sensorDegree", "45"));
poiMinSpeed.setText(PreferencesUtils.getString(requireContext(), "poiMinSpeed", "5"));
poiMaxSpeed.setText(PreferencesUtils.getString(requireContext(), "poiMaxSpeed", "30"));
roadMinSpeed.setText(PreferencesUtils.getString(requireContext(), "roadMinSpeed", "20"));
roadMaxSpeed.setText(PreferencesUtils.getString(requireContext(), "roadMaxSpeed", "120"));
satelliteCount.setText(PreferencesUtils.getString(requireContext(), "satelliteCount", "15"));
v.findViewById(R.id.tv_picture_setting_confirm).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Shared文件中记录对应参数
if (!"".equals(sensorDegree.getText().toString().trim())) {
PreferencesUtils.putString(requireContext(), "sensorDegree", sensorDegree.getText().toString().trim());
}
if (!"".equals(poiMinSpeed.getText().toString().trim())) {
PreferencesUtils.putString(requireContext(), "poiMinSpeed", poiMinSpeed.getText().toString().trim());
}
if (!"".equals(poiMaxSpeed.getText().toString().trim())) {
PreferencesUtils.putString(requireContext(), "poiMaxSpeed", poiMaxSpeed.getText().toString().trim());
}
if (!"".equals(roadMinSpeed.getText().toString().trim())) {
PreferencesUtils.putString(requireContext(), "roadMinSpeed", roadMinSpeed.getText().toString().trim());
}
if (!"".equals(roadMaxSpeed.getText().toString().trim())) {
PreferencesUtils.putString(requireContext(), "roadMaxSpeed", roadMaxSpeed.getText().toString().trim());
}
if (!"".equals(satelliteCount.getText().toString().trim())) {
PreferencesUtils.putString(requireContext(), "satelliteCount", satelliteCount.getText().toString().trim());
}
}
});
v.findViewById(R.id.tv_picture_setting_cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
}
})
.show();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_about_finish:
Objects.requireNonNull(getActivity()).finish();
requireActivity().finish();
break;
case R.id.rl_about:
Intent regardIntent = new Intent(getActivity(), RegardMapActivity.class);

View File

@ -2,8 +2,8 @@ package com.navinfo.outdoor.http;
public class HttpInterface {
// public static final String IP = "http://172.23.138.133:9999/m4";//测试接口-IP
public static final String IP = "http://dtxbmaps.navinfo.com/dtxb/dev/m4";//开发接口-外网
public static final String IP1 = "http://dtxbmaps.navinfo.com/dtxb/test/m4";//测试接口-外网
public static final String IP0 = "http://dtxbmaps.navinfo.com/dtxb/dev/m4";//开发接口-外网
public static final String IP = "http://dtxbmaps.navinfo.com/dtxb/test/m4";//测试接口-外网
public static final String IP2 = "http://dtxbmaps.navinfo.com/dtxb/m4";//正式接口
public static final String USER_PATH = "/user/";//我的
public static final String MSG_LIST_PATH = "/msgList/";//发现

View File

@ -258,6 +258,8 @@ public class GPSUtils {
Log.i(TAG, "卫星状态改变");
if (status != null) {
sateliteCount = status.getSatelliteCount();
} else {
sateliteCount = 0;
}
}
};

View File

@ -1,10 +1,34 @@
package com.navinfo.outdoor.util
import android.app.Activity
import android.content.Context
import com.elvishew.xlog.XLog
import com.github.lazylibrary.util.FileUtils
import com.github.lazylibrary.util.PreferencesUtils
import com.google.gson.Gson
import com.lzy.okgo.model.HttpParams
import com.navinfo.ocr.OCRManager.Companion.instance
import com.navinfo.ocr.model.OcrViewResultModel
import com.navinfo.outdoor.api.Constant
import com.navinfo.outdoor.bean.TaskNameBean
import com.navinfo.outdoor.http.Callback
import com.navinfo.outdoor.http.HttpInterface
import com.navinfo.outdoor.http.OkGoBuilder
import com.otaliastudios.cameraview.PictureResult
import java.io.File
/**
* 照片辅助检查工具类
* */
class PictureCheckHelper {
class PictureCheckHelper(val context: Context) {
val checkResult = CheckResult()
private val sensorDegree by lazy { PreferencesUtils.getString(context, "sensorDegree", "45").toInt()}
private val poiMinSpeed by lazy { PreferencesUtils.getString(context, "poiMinSpeed", "5").toDouble() }
private val poiMaxSpeed by lazy { PreferencesUtils.getString(context, "poiMaxSpeed", "30").toDouble() }
private val roadMinSpeed by lazy { PreferencesUtils.getString(context, "roadMinSpeed", "20").toDouble() }
private val roadMaxSpeed by lazy { PreferencesUtils.getString(context, "roadMaxSpeed", "120").toDouble() }
private val satelliteCount by lazy { PreferencesUtils.getString(context, "satelliteCount", "15").toInt() }
fun addocrCheck(result: Boolean) {
if (result) checkResult.ocrChecked++
@ -25,6 +49,29 @@ class PictureCheckHelper {
if (result) checkResult.speedChecked++
checkResult.speedCount++
}
fun setMockLocationCheck(result: Boolean) { // 只要检查到模拟信号该数据的模拟信号值就为true
if (result and !checkResult.mockLocationChecker) {
checkResult.mockLocationChecker = true
}
}
fun setAutoTakeCheck(result: Boolean) { // 只要是自动捕捉设置该值为自动捕捉值就是true
if (result and !checkResult.autoTakeChecker) {
checkResult.autoTakeChecker = true
}
}
fun addSatelliteCheck(result: Boolean) {
if (result) checkResult.satelliteChecked++
checkResult.satelliteCount++
}
fun addGpsRssiCheck(result: Int) {
checkResult.gpsRssiChecked=checkResult.gpsRssiChecked+result
checkResult.gpsRssiCount=checkResult.gpsRssiCount+4
}
inner class CheckResult {
// ocr检查结果
var ocrChecked: Int = 0
@ -41,5 +88,153 @@ class PictureCheckHelper {
// 速度检查结果
var speedChecked = 0
var speedCount = 0
// 模拟定位结果
var mockLocationChecker = false
// 是否为自动捕捉检查
var autoTakeChecker = false
// 卫星个数检查
var satelliteChecked = 0
var satelliteCount = 0
// 信号强度检查
var gpsRssiChecked = 0
var gpsRssiCount = 0
}
fun savePictureCheckResult(activity: Activity, gson: Gson, type: Int/*采集类型*/,
map: Map<String, Any>, checkFile: File/*检查结果的文件*/,
yDegree: Float/*y轴上的旋转角*/, currentSpeed: Double, isAutoTakePicture: Boolean) {
val resultMap: MutableMap<String, String> = mutableMapOf()
val pictureResult = map["picture"] as PictureResult?
// 如果当前拍照是POI拍照模式才需要做ocr识别以及附近POI查询
// 如果当前拍照是POI拍照模式才需要做ocr识别以及附近POI查询
if (type == 3) {
// 开始ocr文字识别
val ocrViewResultModels = instance.ocr(
BitmapUtil.getBitmapFromBytes(
pictureResult!!.data
)
)
if (ocrViewResultModels != null && !ocrViewResultModels.isEmpty()) {
this.addocrCheck(true)
resultMap["ocr"] = "true"
// 该照片存在文字信息获取占比最大的文字为后续POI判定做准备
val maxOcrViewResult = ocrViewResultModels.stream()
.max { t0, t1 ->
val t0Value = (Math.abs(t0.bounds[2].x - t0.bounds[0].x)
* Math.abs(t0.bounds[2].y - t0.bounds[0].y))
val t1Value = (Math.abs(t1.bounds[2].x - t1.bounds[0].x)
* Math.abs(t1.bounds[2].y - t1.bounds[0].y))
if (t0Value > t1Value) {
return@max 1
} else if (t0Value < t1Value) {
return@max -1
}
return@max 0
}
.get()
resultMap["name"] = maxOcrViewResult.name
// 周边搜索判定周边POI是否存在
if (this.checkResult.nearestChecked < 3) {
// 发送请求查询周边POI是否存在
val name = maxOcrViewResult.name
val httpParams = HttpParams()
val encode = Geohash.getInstance().encode(
LocationLifeCycle.getInstance().mainLocation.latitude,
LocationLifeCycle.getInstance().mainLocation.longitude
)
httpParams.put("geo", encode)
httpParams.put("name", name)
val okGoBuilder = OkGoBuilder.getInstance()
.time(30)
.Builder(activity)
.url(HttpInterface.TASK_NAME)
.cls(TaskNameBean::class.java)
.params(httpParams)
.token(Constant.ACCESS_TOKEN)
okGoBuilder.getRequest(object : Callback<TaskNameBean?> {
override fun onSuccess(taskNameBean: TaskNameBean?, id: Int) {
if (taskNameBean!!.code == 200) {
this@PictureCheckHelper.addNearestCheck(true)
XLog.d("nearest: ${name}, taskBean: ${gson.toJson(taskNameBean)}")
} else {
this@PictureCheckHelper.addNearestCheck(false)
}
FileUtils.writeFile(
checkFile.getAbsolutePath(),
gson.toJson(this@PictureCheckHelper.checkResult),
false
)
}
override fun onError(e: Throwable, id: Int) {
this@PictureCheckHelper.addNearestCheck(false)
FileUtils.writeFile(
checkFile.getAbsolutePath(),
gson.toJson(this@PictureCheckHelper.checkResult),
false
)
}
})
}
} else {
this@PictureCheckHelper.addocrCheck(false)
resultMap["ocr"] = "false"
resultMap["name"] = "null"
}
}
// 获取当前手机姿态,判定该照片手机姿态是否合格
// 获取当前手机姿态,判定该照片手机姿态是否合格
// val yDegree: Float = sensorOritationLifecycle.yDegree
resultMap["angle"] = yDegree.toString() + ""
if (yDegree > -90 - sensorDegree && yDegree < -90 + sensorDegree) {
this@PictureCheckHelper.addAngleCheck(true)
} else {
this@PictureCheckHelper.addAngleCheck(false)
}
// 检查当前速度
resultMap["speed"] = currentSpeed.toString() + ""
if (type == 3) { // poi录像
if (currentSpeed in poiMinSpeed..poiMaxSpeed) {
this@PictureCheckHelper.addSpeedCheck(true)
} else {
this@PictureCheckHelper.addSpeedCheck(false)
}
} else if (type == 4) { // 道路任务
if (currentSpeed in roadMinSpeed..roadMaxSpeed) {
this@PictureCheckHelper.addSpeedCheck(true)
} else {
this@PictureCheckHelper.addSpeedCheck(false)
}
}
// 记录卫星颗数
resultMap["satellite"] = GPSUtils.getInstance(activity).sateliteCount.toString() + ""
if (GPSUtils.getInstance(activity).sateliteCount >= satelliteCount) {
this@PictureCheckHelper.addSatelliteCheck(true)
} else {
this@PictureCheckHelper.addSatelliteCheck(false)
}
// 记录卫星强度
resultMap["gpsRssi"] = LocationLifeCycle.getInstance().tencentLocation.gpsRssi.toString() + ""
this@PictureCheckHelper.addGpsRssiCheck(LocationLifeCycle.getInstance().tencentLocation.gpsRssi)
// 记录json文件到指定文件
FileUtils.writeFile(
checkFile.absolutePath,
gson.toJson(this@PictureCheckHelper.checkResult),
false
)
FileUtils.writeFile(
checkFile.parentFile.absolutePath + "/result.txt",
gson.toJson(resultMap) + "\r",
true
)
}
}

View File

@ -84,6 +84,10 @@ class SensorOritationLifecycle(val context: Context): DefaultLifecycleObserver {
degreesChangeListener?.onDegreesChangeListener(xDegree, yDegree, zDegree)
}
fun getDegrees(): FloatArray {
return floatArrayOf(xDegree, yDegree, zDegree)
}
interface DegreesChangeListener {
fun onDegreesChangeListener(xDegree: Float, yDegree: Float, zDegree: Float)
}

View File

@ -2,7 +2,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="@dimen/default_corner_radius" />
android:radius="@dimen/cardview_default_radius" />
<padding
android:bottom="@dimen/default_widget_padding"
android:left="@dimen/default_widget_padding"

View File

@ -2,7 +2,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="@dimen/default_corner_radius" />
android:radius="@dimen/cardview_default_radius" />
<padding
android:bottom="@dimen/default_widget_padding"
android:left="@dimen/default_widget_padding"

View File

@ -53,6 +53,7 @@
app:layout_constraintTop_toBottomOf="@+id/view1">
<ImageView
android:id="@+id/img_logo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
@ -180,6 +181,37 @@
android:gravity="center"
android:textSize="16sp" />
</RelativeLayout>
<LinearLayout
android:id="@+id/layer_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rl_picture_check_setting"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginLeft="15dp"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical">
<TextView
style="@style/main_about_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="图像检查参数设置" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:background="@drawable/ic_baseline_arrow_forward"
android:gravity="center"
android:textSize="16sp" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/purple_200"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
style="@style/text_style_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="是否可用参数:"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设备姿态偏移量:"></TextView>
<EditText
android:id="@+id/sensor_degree"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="POI拍摄速度(最小):"></TextView>
<EditText
android:id="@+id/poi_speed_min"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="POI拍摄速度(最大):"></TextView>
<EditText
android:id="@+id/poi_speed_max"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="道路拍摄速度(最小):"></TextView>
<EditText
android:id="@+id/road_speed_min"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="道路拍摄速度(最大):"></TextView>
<EditText
android:id="@+id/road_speed_max"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="卫星颗数:"></TextView>
<EditText
android:id="@+id/satellite_count"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<TextView
style="@style/text_style_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="得分参数:"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Tooltip"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_picture_setting_confirm"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="确定"
style="@style/Widget.AppCompat.Button.Colored"></TextView>
<TextView
android:id="@+id/tv_picture_setting_cancel"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="取消"
android:textColor="@color/chuck_status_500"
style="@style/Widget.AppCompat.Button.Colored"></TextView>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -178,4 +178,8 @@
<item name="android:textColor">@color/selector_default_btn_text_color</item>
<item name="android:padding">@dimen/default_widget_padding</item>
</style>
<style name="item_style">
<item name="android:padding">@dimen/default_widget_padding</item>
</style>
</resources>

View File

@ -16,9 +16,9 @@ org.gradle.jvmargs=-Xmx2048m
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=10080
systemProp.http.proxyPort=1080
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=10080
systemProp.https.proxyPort=1080
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
android.injected.testOnly=false

View File

@ -52,8 +52,9 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'
implementation 'com.google.android.material:material:1.6.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@ -1,30 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB