Commit fb151307 authored by YONG-LIN SU's avatar YONG-LIN SU

修正流程,以拍照為基礎判別是否為新單或舊單

parent 292e92e8
......@@ -12,6 +12,6 @@
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-08-24T09:01:07.838534400Z" />
<timeTargetWasSelectedWithDropDown value="2022-08-29T05:19:03.595558100Z" />
</component>
</project>
\ No newline at end of file
......@@ -25,6 +25,7 @@
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t01_import_db.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t02_key_in_plate_number.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t02_key_in_plate_number_reverse.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t02_plate_and_space_confirm.xml" value="0.3654891304347826" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t02_select_road.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t02_select_space.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t02_select_vehicle_type.xml" value="0.34375" />
......@@ -39,6 +40,7 @@
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/alert_dialog_progress_bar.xml" value="0.29957264957264956" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/alert_dialog_t02_device_list.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/alert_dialog_t03_cumulative_time.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/alert_dialog_t03_new_cumulative_time.xml" value="0.3651041666666667" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/card_view_image_plate_number_item.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/card_view_large_list_files_item.xml" value="0.34375" />
<entry key="..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/card_view_list_files_item.xml" value="0.34375" />
......
......@@ -2,7 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="ecom.android.newparkapp">
<!-- Android 11 調用相機拍照意圖 註冊 -->
<queries>
<intent>
......@@ -23,22 +22,23 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- android 11 管理所有檔案權限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- android 11 管理所有檔案權限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_icon_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_icon_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
tools:targetApi="31">
<activity
android:name=".view.T02PlateAndSpaceConfirmActivity"
android:exported="false" />
<activity
android:name=".view.MainActivity"
android:exported="true">
......@@ -48,7 +48,6 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".view.T01SettingActivity"
android:exported="false"
......@@ -98,16 +97,12 @@
android:name=".view.T03SearchingParkingSpaceActivity"
android:exported="false"
android:label="案件搜尋"
android:theme="@style/Theme.AppCompat.Light"
/>
android:theme="@style/Theme.AppCompat.Light" />
<activity
android:name=".view.T04RenewListActivity"
android:exported="false"
android:label="GPS巡場模式"
android:theme="@style/Theme.AppCompat.Light"
/>
android:theme="@style/Theme.AppCompat.Light" />
<provider
android:name="androidx.core.content.FileProvider"
......
package ecom.android.newparkapp;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import androidx.exifinterface.media.ExifInterface;
import android.media.MediaScannerConnection;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Locale;
import ecom.android.newparkapp.entity.BoxInfo;
public class Common {
public static final String CHANNEL_ID = "ecom.android.park.notification.channel";
......@@ -696,4 +705,83 @@ public class Common {
bitmap.copyPixelsToBuffer(buf);
return buf.array();
}
public static Bitmap decodeFile2ScaledBitmap(String path, Activity activity){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //开启只读取尺寸
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
DisplayMetrics DM = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(DM);
int size = 1;
if (options.outWidth > DM.widthPixels) {
size = options.outWidth / DM.widthPixels; //计算比例
}
options.inSampleSize = size; //设置缩放值
options.inJustDecodeBounds = false; //关闭只读取尺寸
bitmap = BitmapFactory.decodeFile(path, options);
return bitmap;
}
public static Bitmap decodeFile2ScaledPlateBitmap(String path, BoxInfo boxInfo, Activity activity){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
DisplayMetrics DM = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(DM);
int size = 1;
if (options.outWidth > DM.widthPixels) {
size = options.outWidth / DM.widthPixels;
}
// 固定縮放比例
size = 4;
options.inSampleSize = size;
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(path, options);
int x0 = (int)(boxInfo.x0/size);
int y0 = (int)(boxInfo.y0/size);
int w = (int)(boxInfo.getRect().width()/size);
int h = (int)(boxInfo.getRect().height()/size);
Bitmap plateBitmap = null;
try {
plateBitmap = Bitmap.createBitmap(bitmap, x0, y0, w, h);
}catch (Exception exception){
exception.printStackTrace();
}
return plateBitmap;
}
public static void moveFile(String inputPath, String outputPath) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(inputPath);
out = new FileOutputStream(outputPath);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
// write the output file
out.flush();
out.close();
out = null;
// delete the original file
new File(inputPath).delete();
}
catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
}
catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}
package ecom.android.newparkapp;
import static ecom.android.newparkapp.Common.moveFile;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
......@@ -14,9 +16,16 @@ import java.util.Calendar;
public class ModifyPhoto implements Runnable {
private final String path;
private final String newPath;
public ModifyPhoto(String path) {
this.path = path;
this.newPath = path;
}
public ModifyPhoto(String path, String newPath){
this.path = path;
this.newPath = newPath;
}
@Override
......@@ -69,6 +78,12 @@ public class ModifyPhoto implements Runnable {
icon.recycle();
}
}
if (!path.equals(newPath)){
// 搬移檔案至目標位置
moveFile(path, newPath);
}
//Log.d("ModifyPhoto", " Ends Work : " + Thread.currentThread().getName());
}
}
......@@ -13,6 +13,7 @@ import java.util.List;
import ecom.android.newparkapp.entity.Case;
import ecom.android.newparkapp.entity.CaseAndAllCasePhoto;
import ecom.android.newparkapp.entity.Shift;
import ecom.android.newparkapp.entity.Space;
@Dao
public interface CaseDao {
......@@ -26,6 +27,12 @@ public interface CaseDao {
@Query("SELECT * FROM `case` WHERE shift=:shift AND user_id=:userId AND case_time>=:startDate AND case_time<=:endDate")
List<CaseAndAllCasePhoto> getAllWithCasePhotoByShitAndUserIdInDay(Shift shift, int userId, Date startDate, Date endDate);
@Query("SELECT * FROM `case` WHERE shift=:shift AND user_id=:userId AND plate_number=:plateNumber AND case_time>=:startDate AND case_time<=:endDate")
List<Case> getAllByShitAndUserIdAndPlateNumberInDay(Shift shift, int userId, String plateNumber, Date startDate, Date endDate);
@Query("SELECT * FROM `case` WHERE shift=:shift AND user_id=:userId AND plate_number=:plateNumber AND space_id=:spaceId AND case_time>=:startDate AND case_time<=:endDate")
List<Case> getAllByShitAndUserIdAndPlateNumberAndSpaceIdInDay(Shift shift, int userId, String plateNumber, String spaceId, Date startDate, Date endDate);
@Query("SELECT * FROM `case` WHERE space_id=:spaceId")
List<CaseAndAllCasePhoto> getAllWithCasePhotoBySpace(String spaceId);
......
......@@ -27,7 +27,7 @@ public interface SpaceDao {
List<Space> getAllByLocation(double latitudeBigger, double latitudeSmaller, double longitudeBigger , double longitudeSmaller);
@Query("SELECT * FROM space WHERE id IN (:Ids)")
List<Space> loadAllByIds(int[] Ids);
List<Space> loadAllByIds(String [] Ids);
@Query("SELECT * FROM space WHERE road_id=:RoadIds")
List<Space> loadAllByRoadId(String RoadIds);
......
......@@ -164,8 +164,13 @@ public class CarPrinter_TPB250 implements IBluetoothPrinter {
PrintString(outPutBT, " " + carCase.plateNumber, 52, true);
//-------------------------------------------
//路段、格號
PrintString(outPutBT, " " + carCase.space.id + " " + carCase.space.road.name, 52, true);
// 路段、格號
// 避免超出範圍
String roadNSpace = carCase.space.id + " " + carCase.space.road.name;
if (roadNSpace.length() > 11){
roadNSpace = roadNSpace.substring(0, 11);
}
PrintString(outPutBT, " " + roadNSpace, 52, true);
//-------------------------------------------
//日期
......
......@@ -2,12 +2,17 @@ package ecom.android.newparkapp.repository;
import android.app.Application;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import ecom.android.newparkapp.R;
import ecom.android.newparkapp.dao.CaseDao;
......@@ -25,6 +30,7 @@ import ecom.android.newparkapp.database.InfoDatabase;
import ecom.android.newparkapp.entity.Case;
import ecom.android.newparkapp.entity.CaseAndAllCasePhoto;
import ecom.android.newparkapp.entity.Shift;
import ecom.android.newparkapp.entity.Space;
public class InfoRepository {
private InfoDatabase infoDatabase;
......@@ -82,6 +88,29 @@ public class InfoRepository {
return caseDao.getAllWithCasePhotoBySpaceAndShiftAndUserIdInDay(spaceId, shift, userId, startDate, endDate);
}
public List<Case> getAllCaseByShitAndUserIdAndPlateNumberAndSpaceIdToday(Shift shift, int userId, String plateNumber, String spaceId){
getStartEndToday();
return caseDao.getAllByShitAndUserIdAndPlateNumberAndSpaceIdInDay(shift, userId, plateNumber, spaceId,startDate, endDate);
}
public List<Case> getAllCaseByShitAndUserIdAndPlateNumberToday(Shift shift, int userId, String plateNumber){
getStartEndToday();
return caseDao.getAllByShitAndUserIdAndPlateNumberInDay(shift, userId, plateNumber, startDate, endDate);
}
public List<Space> getAllCaseSpaceByShitAndUserIdAndPlateNumberToday(Shift shift, int userId, String plateNumber){
List<Space> spaces = new ArrayList<>();
List<Case> cases = getAllCaseByShitAndUserIdAndPlateNumberToday(shift, userId, plateNumber);
if (cases.size() == 0){
return spaces;
}
Map<String, List<Case>> casesGroupBySpaceId = cases.stream().collect(Collectors.groupingBy(c -> c.space.id));
Set<String> spaceIdKeySet = casesGroupBySpaceId.keySet();
String[] spaceIds = spaceIdKeySet.toArray(new String[spaceIdKeySet.size()]);
return spaceDao.loadAllByIds(spaceIds);
}
private void getStartEndToday()
{
Calendar calendar = Calendar.getInstance(Locale.getDefault());
......
package ecom.android.newparkapp.view;
import static ecom.android.newparkapp.Common.decodeFile2ScaledPlateBitmap;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import java.io.File;
import ecom.android.newparkapp.Common;
import ecom.android.newparkapp.R;
import ecom.android.newparkapp.databinding.ActivityT02KeyInPlateNumberBinding;
import ecom.android.newparkapp.entity.BoxInfo;
public class T02KeyInPlateNumberActivity extends AppCompatActivity {
private ActivityT02KeyInPlateNumberBinding dataBinding;
private BoxInfo boxInfo;
private File file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_t02_key_in_plate_number);
Bundle bundle = getIntent().getExtras();
try {
boxInfo = (BoxInfo) bundle.getSerializable("BoxInfo");
file = (File) bundle.getSerializable("PhotoFile");
}catch (NullPointerException nullPointerException){
nullPointerException.printStackTrace();
}
if (file != null && boxInfo != null && file.exists()){
Bitmap plateBitmap = decodeFile2ScaledPlateBitmap(file.getAbsolutePath(), boxInfo, this);
if (plateBitmap != null){
dataBinding.ivCroppedPlate.setImageBitmap(plateBitmap);
}
}
eventBinding();
}
......
package ecom.android.newparkapp.view;
import static ecom.android.newparkapp.Common.decodeFile2ScaledPlateBitmap;
import android.content.Intent;
import android.graphics.Bitmap;
import android.location.Location;
import android.os.Bundle;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import java.io.File;
import java.util.List;
import ecom.android.newparkapp.R;
import ecom.android.newparkapp.adapter.SelectSpaceAdapter;
import ecom.android.newparkapp.databinding.ActivityT02PlateAndSpaceConfirmBinding;
import ecom.android.newparkapp.entity.BoxInfo;
import ecom.android.newparkapp.entity.Case;
import ecom.android.newparkapp.entity.Road;
import ecom.android.newparkapp.entity.Shift;
import ecom.android.newparkapp.entity.Space;
import ecom.android.newparkapp.repository.InfoRepository;
import ecom.android.newparkapp.viewModel.T02SelectSpaceViewModel;
public class T02PlateAndSpaceConfirmActivity extends AppCompatActivity {
private ActivityT02PlateAndSpaceConfirmBinding dataBinding;
private InfoRepository infoRepository;
private BoxInfo boxInfo;
private File file;
private String plateNumber;
private int userId;
private Shift shift;
private Location location;
private ActivityResultLauncher keyInPlateNumberActivityResultLauncher;
private ActivityResultLauncher roadResultLauncher;
private SelectSpaceAdapter reNewCandidateSpaceAdapter;
private SelectSpaceAdapter selectSpaceAdapter;
private T02SelectSpaceViewModel t02SelectSpaceViewModel;
private ViewModelProvider viewModelProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataBinding = DataBindingUtil.setContentView(this,R.layout.activity_t02_plate_and_space_confirm);
Bundle bundle = getIntent().getExtras();
try {
userId = bundle.getInt("UserId", -1);
shift = bundle.getParcelable("Shift");
location = bundle.getParcelable("Location");
boxInfo = (BoxInfo) bundle.getSerializable("BoxInfo");
file = (File) bundle.getSerializable("PhotoFile");
}catch (NullPointerException nullPointerException){
nullPointerException.printStackTrace();
}
plateNumber = boxInfo == null ? null : boxInfo.getPlateNumbs();
if (userId == -1 || shift == null || location == null){
finish();
}
viewModelProvider = new ViewModelProvider(this);
t02SelectSpaceViewModel = viewModelProvider.get(T02SelectSpaceViewModel.class);
t02SelectSpaceViewModel.searchNearSpace(location);
infoRepository = new InfoRepository(this.getApplication());
selectSpaceAdapter = new SelectSpaceAdapter(space -> nextStage(space));
dataBinding.rvSpaceOption.setLayoutManager(new GridLayoutManager(this, 3));
dataBinding.rvSpaceOption.setAdapter(selectSpaceAdapter);
reNewCandidateSpaceAdapter = new SelectSpaceAdapter(space -> nextStage(space));
dataBinding.rvRenewSpaceOption.setLayoutManager(new GridLayoutManager(this, 3));
dataBinding.rvRenewSpaceOption.setAdapter(reNewCandidateSpaceAdapter);
plateImageInit();
layoutInit();
eventBinding();
resultLauncherRegister();
observeBinding();
if (plateNumber == null || plateNumber.trim().isEmpty()){
btnKeyinPlateNumberOnClicked();
}
}
private void plateImageInit(){
if (boxInfo == null){
return;
}
Bitmap plateBitmap = decodeFile2ScaledPlateBitmap(file.getAbsolutePath(), boxInfo, this);
if (plateBitmap!=null){
dataBinding.ivCroppedPlate.setImageBitmap(plateBitmap);
}
}
private void layoutInit(){
if (plateNumber != null && !plateNumber.trim().isEmpty()){
dataBinding.btnKeyinPlateNumber.setText(plateNumber);
// 搜尋鄰近已知case,當日是否有該車停留
List<Space> reNewCandidateSpace = infoRepository.getAllCaseSpaceByShitAndUserIdAndPlateNumberToday(shift, userId, plateNumber);
reNewCandidateSpaceAdapter.submitList(reNewCandidateSpace);
}
}
private void eventBinding() {
dataBinding.btnKeyinPlateNumber.setOnClickListener(view -> btnKeyinPlateNumberOnClicked());
dataBinding.btnSelectRoad.setOnClickListener(view -> btnSelectRoadOnClicked());
}
private void resultLauncherRegister() {
keyInPlateNumberActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == RESULT_OK && result.getData() != null){
plateNumber = result.getData().getStringExtra("PlateNumber");
layoutInit();
}
});
roadResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == RESULT_OK && result.getData() != null){
Road selectedRoad = result.getData().getParcelableExtra("Road");
if (selectedRoad != null){
t02SelectSpaceViewModel.updateCurrentRoad(selectedRoad);
}
}
});
}
private void observeBinding() {
t02SelectSpaceViewModel.getCurrentRoad().observe(this, road -> {
String roadString = "";
if (road != null){
roadString = road.id + " "+ road.name;
}
dataBinding.btnSelectRoad.setText(roadString);
});
t02SelectSpaceViewModel.getCurrentSpace().observe(this, spaces -> {
if (spaces != null){
selectSpaceAdapter.submitList(spaces);
}
});
}
private void btnSelectRoadOnClicked(){
Intent intent = new Intent();
intent.setClass(this, T02SelectRoadActivity.class);
roadResultLauncher.launch(intent);
}
private void btnKeyinPlateNumberOnClicked(){
// TODO: 2022/8/25 加入reverse選項
Intent intent = new Intent();
if (boxInfo != null && file != null && file.exists()){
Bundle bundle = new Bundle();
bundle.putSerializable("PhotoFile", file);
bundle.putSerializable("BoxInfo", boxInfo);
intent.putExtras(bundle);
}
intent.setClass(this, T02KeyInPlateNumberActivity.class);
keyInPlateNumberActivityResultLauncher.launch(intent);
}
private void nextStage(Space space){
boolean isNewCase = false;
Intent intent = getIntent();
Bundle bundle = new Bundle();
List<Case> selectedCases = infoRepository.getAllCaseByShitAndUserIdAndPlateNumberAndSpaceIdToday(shift, userId, plateNumber, space.id);
if (selectedCases.size() == 0){
// 新單
isNewCase = true;
bundle.putString("PlateNumber", plateNumber);
bundle.putParcelable("Space", space);
}else {
// sort by time
selectedCases.sort((t1, t2) -> t1.caseTime.compareTo(t2.caseTime));
Case selectedCase = selectedCases.get(0);
bundle.putString("BillingNumber2", selectedCase.billingNumber2);
}
bundle.putBoolean("IsNewCase", isNewCase);
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
finish();
}
}
\ No newline at end of file
......@@ -11,6 +11,7 @@ import android.graphics.BitmapFactory;
import android.location.Location;
import android.media.MediaScannerConnection;
import android.os.Environment;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
......@@ -21,8 +22,10 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
......@@ -366,22 +369,21 @@ public class T02StartViewModel extends AndroidViewModel {
/**
* @param photoFile 拍照回傳檔案
*/
public boolean takeNewPhoto(File photoFile){
public BoxInfo takeNewPhoto(File photoFile, boolean withoutModify){
Case tempCase = currentCase.getValue();
// 更新照片數量
tempCase.photoCount+=1;
// 取得完整路徑
final String path = photoFile.getAbsolutePath();
// TODO: 2022/7/29 加入車牌辨識功能
// 進行車牌辨識
String plateNumber = doLPRByFilePath(path, threshold, nms_threshold);
BoxInfo boxInfo = getLPRBoxInfoByFilePath(path, threshold, nms_threshold);
String plateNumber = boxInfo!=null ? boxInfo.getPlateNumbs() : "";
// 車牌結果修正
String newPlateNumber = plateModifyByRule(plateNumber);
CasePhoto newCasePhoto = new CasePhoto(0, tempCase.billingNumber2, path, newPlateNumber);
tempCasePhoto.add(newCasePhoto);
if (boxInfo!=null){
boxInfo.setPlateNumbs(newPlateNumber);
}
// 未填寫車牌,自動填寫
if (tempCase.plateNumber == null || tempCase.plateNumber.trim().isEmpty()){
......@@ -389,11 +391,19 @@ public class T02StartViewModel extends AndroidViewModel {
}
// 為圖片壓制浮水印
if (!withoutModify){
// 更新照片數量
tempCase.photoCount+=1;
CasePhoto newCasePhoto = new CasePhoto(0, tempCase.billingNumber2, path, newPlateNumber);
tempCasePhoto.add(newCasePhoto);
Thread ModifyPhotoT = new Thread(new ModifyPhoto(path), "ModifyPhoto_Thread");
ModifyPhotoT.start();
// 重新搜尋檔案
MediaScannerConnection.scanFile(getApplication().getApplicationContext(), new String[]{path}, null, null);
}
// 更新當前案件
if (tempCase.caseStatus == CaseStatus.LIST || tempCase.caseStatus == CaseStatus.CHANGED){
......@@ -403,7 +413,54 @@ public class T02StartViewModel extends AndroidViewModel {
currentCase.setValue(tempCase);
}
return plateRuleCheck(tempCase.plateNumber);
return boxInfo;
}
public void setNewCasePhoto(File photoFile){
Case tempCase = getCurrentCase().getValue();
// 取得完整路徑
final String path = photoFile.getAbsolutePath();
// TODO: 2022/7/29 加入車牌辨識功能
// 進行車牌辨識
String plateNumber = doLPRByFilePath(path, threshold, nms_threshold);
// 車牌辨識結果 車牌規則 過濾
String newPlateNumber = plateModifyByRule(plateNumber);
String day = new SimpleDateFormat("yyyyMMdd").format(new Date());
String newPath = Environment.getExternalStorageDirectory() + getApplication().getString(R.string.sysDataPhoto_path) + day;
File temp = new File(newPath);
if (!temp.exists()) {
temp.mkdirs();
}
File newFile = new File(newPath, "/" + tempCase.billingNumber2 + tempCase.photoCount + ".jpg");
String newFilePath = newFile.getAbsolutePath();
// 添加車牌辨識 結果
CasePhoto newCasePhoto = new CasePhoto(0, tempCase.billingNumber2, newFilePath, newPlateNumber);
tempCasePhoto.add(newCasePhoto);
// 為圖片壓制浮水印
Thread ModifyPhotoT = new Thread(new ModifyPhoto(path, newFilePath), "ModifyPhoto_Thread");
ModifyPhotoT.start();
// 重新搜尋檔案
MediaScannerConnection.scanFile(getApplication().getApplicationContext(), new String[]{newFilePath}, null, null);
// 更新照片數量
tempCase.photoCount+=1;
if (tempCase.caseStatus != CaseStatus.NEW) {
tempCase.caseStatus = CaseStatus.CHANGED;
}
currentCase.setValue(tempCase);
}
public void addNewPhotos(File photoFile){
setNewCasePhoto(photoFile);
saveCurrentCase(false);
}
......@@ -597,36 +654,47 @@ public class T02StartViewModel extends AndroidViewModel {
* 累加時間處理
* @param photoFile 拍照傳回
*/
public void cumulativeTime(File photoFile) {
public void cumulativeTime(File photoFile, boolean isPhotoProcessed) {
Case tempCase = currentCase.getValue();
tempCase.caseStatus = CaseStatus.CHANGED;
// 更新照片數量
tempCase.photoCount+=1;
// 更新累加時間
int addCount = calcPeriodHourCount(tempCase);
tempCase.periodHour = addCount * tempCase.space.spaceRate.perHours;
tempCase.finalExpenses = addCount * tempCase.space_fee;
if (!isPhotoProcessed){
// 取得完整路徑
final String path = photoFile.getAbsolutePath();
// TODO: 2022/7/29 加入車牌辨識功能
// 進行車牌辨識
String plateNumber = doLPRByFilePath(path, threshold, nms_threshold);
// 車牌辨識結果 車牌規則 過濾
String newPlateNumber = plateModifyByRule(plateNumber);
String day = new SimpleDateFormat("yyyyMMdd").format(new Date());
String newPath = Environment.getExternalStorageDirectory() + getApplication().getString(R.string.sysDataPhoto_path) + day;
File temp = new File(newPath);
if (!temp.exists()) {
temp.mkdirs();
}
File newFile = new File(newPath, "/" + tempCase.billingNumber2 + tempCase.photoCount + ".jpg");
String newFilePath = newFile.getAbsolutePath();
// 添加車牌辨識 結果
CasePhoto newCasePhoto = new CasePhoto(0, tempCase.billingNumber2, path, newPlateNumber);
CasePhoto newCasePhoto = new CasePhoto(0, tempCase.billingNumber2, newFilePath, newPlateNumber);
tempCasePhoto.add(newCasePhoto);
// 為圖片壓制浮水印
Thread ModifyPhotoT = new Thread(new ModifyPhoto(path), "ModifyPhoto_Thread");
Thread ModifyPhotoT = new Thread(new ModifyPhoto(path, newFilePath), "ModifyPhoto_Thread");
ModifyPhotoT.start();
// 重新搜尋檔案
MediaScannerConnection.scanFile(getApplication().getApplicationContext(), new String[]{path}, null, null);
MediaScannerConnection.scanFile(getApplication().getApplicationContext(), new String[]{newFilePath}, null, null);
// 更新照片數量
tempCase.photoCount+=1;
}
// 更新當前案件
currentCase.setValue(tempCase);
......@@ -721,6 +789,41 @@ public class T02StartViewModel extends AndroidViewModel {
return plateNumber;
}
// 車牌辨識回傳Boxinfo
public BoxInfo getLPRBoxInfoByFilePath(String filePath,float threshold, float nms_threshold){
// 進行車牌辨識
BoxInfo boxInfo = null;
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
bitmap = Common.turnPictureDegree(bitmap, filePath);
byte[] imageDataBytes = bitampToByteArray(bitmap);
BoxInfo[] boxInfos = null;
boxInfos = EcomALPR.retinaplate_detect(bitmap, imageDataBytes, bitmap.getWidth(), bitmap.getHeight(), threshold, nms_threshold);
if (boxInfos != null && boxInfos.length != 0){
int maxPlateIndex = 0;
for(int i = 0; i < boxInfos.length; i++){
String plateNumbs = null;
if (boxInfos[i].getLandmarks() != null){
// 整張圖丟進去透過 landmark進行校正
plateNumbs = EcomALPR.ctcocr_recognize(bitmap, imageDataBytes, bitmap.getWidth(), bitmap.getHeight(), boxInfos[i].getLandmarks());
}else {
Bitmap plateBitmap = Bitmap.createBitmap(bitmap, (int)boxInfos[i].x0, (int)boxInfos[i].y0, (int)boxInfos[i].getRect().width(), (int)boxInfos[i].getRect().height());
byte[] plateImageDataBytes = bitampToByteArray(plateBitmap);
plateNumbs = EcomALPR.ctcocr_recognize(plateBitmap, plateImageDataBytes, plateBitmap.getWidth(), plateBitmap.getHeight());
}
if (plateNumbs != null){
boxInfos[i].setPlateNumbs(plateNumbs);
if (boxInfos[maxPlateIndex].getRect().height() * boxInfos[maxPlateIndex].getRect().width() < boxInfos[i].getRect().height() * boxInfos[i].getRect().width()){
maxPlateIndex = i;
}
}
}
boxInfo = boxInfos[maxPlateIndex];
}
return boxInfo;
}
public boolean isWorkTime(){
Calendar calendar = Calendar.getInstance();
Shift currentShift = shift.getValue();
......
......@@ -17,8 +17,8 @@
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/enterTitle_txv"
<ImageView
android:id="@+id/iv_cropped_plate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.333"
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".view.T02PlateAndSpaceConfirmActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.6"
android:orientation="vertical">
<TextView
android:id="@+id/textView25"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="車牌辨識搜尋結果"
android:textAlignment="center"
android:textSize="30sp" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="車牌辨識結果"
android:textSize="24sp" />
<ImageView
android:id="@+id/iv_cropped_plate"
android:layout_width="match_parent"
android:layout_height="50dp"
android:scaleType="fitCenter"
/>
<Button
android:id="@+id/btn_keyin_plate_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="8052-LZ"
android:textSize="24sp" />
<TextView
android:id="@+id/textView28"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="車格搜尋結果"
android:textSize="24sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_renew_space_option"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/recycler_view_space_item"
tools:spanCount="3"
tools:layoutManager="GridLayoutManager" />
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_weight="0.01"
app:srcCompat="@color/black">
</ImageView>
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="選取鄰近車格"
android:textAlignment="center"
android:textSize="30sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.12"
android:gravity="center"
android:orientation="horizontal"
android:paddingEnd="5dp"
tools:ignore="RtlSymmetry">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center|center_vertical"
android:text="格號"
android:textSize="30sp"
tools:ignore="NestedWeights" />
<Button
android:id="@+id/btn_select_road"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.7"
android:textSize="30sp" />
<Button
android:id="@+id/btn_select_space_back"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/label_back"
android:textSize="30sp"
android:visibility="gone" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_space_option"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.4"
tools:listitem="@layout/recycler_view_space_item"
tools:spanCount="3"
tools:layoutManager="GridLayoutManager" />
</LinearLayout>
</layout>
\ No newline at end of file
......@@ -442,11 +442,11 @@ tools:layout_editor_absoluteY="25dp">
app:layout_constraintTop_toBottomOf="@+id/linearLayout4">
<Button
android:id="@+id/btn_cumulative_time"
android:id="@+id/btn_add_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.26"
android:text="@string/cumulativeTime_button_text"
android:text="添加照片"
android:textSize="28sp"
tools:ignore="ButtonStyle" />
......@@ -462,14 +462,6 @@ tools:layout_editor_absoluteY="25dp">
tools:ignore="ButtonStyle"
/>
<Button
android:id="@+id/btn_photograph"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:text="@string/photograph_button_text"
android:textSize="28sp"
tools:ignore="ButtonStyle" />
</LinearLayout>
......@@ -543,11 +535,11 @@ tools:layout_editor_absoluteY="25dp">
</LinearLayout>
<Button
android:id="@+id/btn_new_page"
android:id="@+id/btn_photograph"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/newPage_button_text"
android:text="@string/photograph_button_text"
android:textSize="28sp" />
</LinearLayout>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment