Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
NewParkAPP
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
YONG-LIN SU
NewParkAPP
Commits
d4472e97
Commit
d4472e97
authored
Aug 03, 2022
by
YONG-LIN SU
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1. 刪除垃圾
2. 新增藍芽連線功能 3. 新增藍芽列印功能 4. 調整資料庫欄位
parent
24da35c7
Changes
44
Hide whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
1447 additions
and
529 deletions
+1447
-529
deploymentTargetDropDown.xml
.idea/deploymentTargetDropDown.xml
+1
-1
misc.xml
.idea/misc.xml
+3
-0
build.gradle
app/build.gradle
+2
-1
CaseDaoTest.java
...oidTest/java/ecom/android/newparkapp/dao/CaseDaoTest.java
+0
-1
UserDaoTest.java
...oidTest/java/ecom/android/newparkapp/dao/UserDaoTest.java
+0
-1
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+2
-0
BlueToothComm.java
app/src/main/java/ecom/android/newparkapp/BlueToothComm.java
+321
-0
ConvertBindingAdapter.java
...com/android/newparkapp/adapter/ConvertBindingAdapter.java
+29
-0
LocationConverter.java
.../ecom/android/newparkapp/converter/LocationConverter.java
+1
-1
SpaceTypeConverter.java
...ecom/android/newparkapp/converter/SpaceTypeConverter.java
+22
-0
TimestampConverter.java
...ecom/android/newparkapp/converter/TimestampConverter.java
+1
-1
SpaceTypeDao.java
...c/main/java/ecom/android/newparkapp/dao/SpaceTypeDao.java
+0
-36
CaseDatabase.java
...n/java/ecom/android/newparkapp/database/CaseDatabase.java
+0
-30
InfoDatabase.java
...n/java/ecom/android/newparkapp/database/InfoDatabase.java
+5
-7
RoadDatabase.java
...n/java/ecom/android/newparkapp/database/RoadDatabase.java
+0
-25
SpaceDatabase.java
.../java/ecom/android/newparkapp/database/SpaceDatabase.java
+0
-25
SpaceRateDatabase.java
...a/ecom/android/newparkapp/database/SpaceRateDatabase.java
+0
-25
SpaceStatusDatabase.java
...ecom/android/newparkapp/database/SpaceStatusDatabase.java
+0
-25
SpaceTypeDatabase.java
...a/ecom/android/newparkapp/database/SpaceTypeDatabase.java
+0
-25
UserDatabase.java
...n/java/ecom/android/newparkapp/database/UserDatabase.java
+0
-25
VehicleBrandDatabase.java
...com/android/newparkapp/database/VehicleBrandDatabase.java
+0
-25
VehicleColorDatabase.java
...com/android/newparkapp/database/VehicleColorDatabase.java
+0
-25
VehicleTypeDatabase.java
...ecom/android/newparkapp/database/VehicleTypeDatabase.java
+0
-25
Case.java
app/src/main/java/ecom/android/newparkapp/entity/Case.java
+85
-4
Space.java
app/src/main/java/ecom/android/newparkapp/entity/Space.java
+20
-4
SpaceType.java
...c/main/java/ecom/android/newparkapp/entity/SpaceType.java
+0
-53
CarPrinter_TPB250.java
...va/ecom/android/newparkapp/printer/CarPrinter_TPB250.java
+135
-0
IBluetoothPrinter.java
...va/ecom/android/newparkapp/printer/IBluetoothPrinter.java
+16
-0
InfoRepository.java
...va/ecom/android/newparkapp/repository/InfoRepository.java
+0
-4
MainActivity.java
.../main/java/ecom/android/newparkapp/view/MainActivity.java
+33
-11
T01SettingActivity.java
...java/ecom/android/newparkapp/view/T01SettingActivity.java
+1
-7
T02StartActivity.java
...n/java/ecom/android/newparkapp/view/T02StartActivity.java
+271
-58
BlueToothViewModel.java
...ecom/android/newparkapp/viewModel/BlueToothViewModel.java
+275
-0
FusedGpsViewModel.java
.../ecom/android/newparkapp/viewModel/FusedGpsViewModel.java
+105
-0
T01ImportDbViewModel.java
...om/android/newparkapp/viewModel/T01ImportDbViewModel.java
+5
-23
T01SettingViewModel.java
...com/android/newparkapp/viewModel/T01SettingViewModel.java
+6
-3
T02StartViewModel.java
.../ecom/android/newparkapp/viewModel/T02StartViewModel.java
+7
-0
UserViewModel.java
...java/ecom/android/newparkapp/viewModel/UserViewModel.java
+0
-46
activity_main.xml
app/src/main/res/layout/activity_main.xml
+1
-6
activity_t02_start.xml
app/src/main/res/layout/activity_t02_start.xml
+8
-5
alert_dialog_progress_bar.xml
app/src/main/res/layout/alert_dialog_progress_bar.xml
+21
-0
alert_dialog_t02_device_list.xml
app/src/main/res/layout/alert_dialog_t02_device_list.xml
+62
-0
list_view_device_name_item.xml
app/src/main/res/layout/list_view_device_name_item.xml
+6
-0
strings.xml
app/src/main/res/values/strings.xml
+3
-1
No files found.
.idea/deploymentTargetDropDown.xml
View file @
d4472e97
...
...
@@ -12,6 +12,6 @@
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown
value=
"2022-08-0
2T03:29:02.3388783
00Z"
/>
<timeTargetWasSelectedWithDropDown
value=
"2022-08-0
3T07:12:30.7387276
00Z"
/>
</component>
</project>
\ No newline at end of file
.idea/misc.xml
View file @
d4472e97
...
...
@@ -32,10 +32,13 @@
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t03_img_viewer.xml"
value=
"0.34375"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t03_list_files.xml"
value=
"0.34375"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/activity_t03_total.xml"
value=
"0.34375"
/>
<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/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_list_files_item.xml"
value=
"0.34375"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/content_t02_select_road.xml"
value=
"0.1875"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/list_view_device_name_item.xml"
value=
"0.34375"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/recycler_view_bulletin_board_item.xml"
value=
"0.34375"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/recycler_view_db_table_item.xml"
value=
"0.33"
/>
<entry
key=
"..\:/Users/pp931/Desktop/RD/Projects/NewParkApp/app/src/main/res/layout/recycler_view_item.xml"
value=
"0.34375"
/>
...
...
app/build.gradle
View file @
d4472e97
...
...
@@ -8,7 +8,7 @@ android {
defaultConfig
{
applicationId
"ecom.android.newparkapp"
minSdk
27
targetSdk
3
2
targetSdk
3
0
versionCode
1
versionName
"Dev Ver.0.3.0"
...
...
@@ -45,6 +45,7 @@ dependencies {
implementation
'androidx.preference:preference:1.1.1'
implementation
'androidx.navigation:navigation-fragment:2.5.0'
implementation
'androidx.navigation:navigation-ui:2.5.0'
implementation
'com.google.android.gms:play-services-location:20.0.0'
testImplementation
'junit:junit:4.13.2'
androidTestImplementation
'androidx.test.ext:junit:1.1.3'
androidTestImplementation
'androidx.test.espresso:espresso-core:3.4.0'
...
...
app/src/androidTest/java/ecom/android/newparkapp/dao/CaseDaoTest.java
View file @
d4472e97
...
...
@@ -9,7 +9,6 @@ import org.junit.After;
import
org.junit.Before
;
import
org.junit.Test
;
import
ecom.android.newparkapp.database.CaseDatabase
;
import
ecom.android.newparkapp.entity.Case
;
public
class
CaseDaoTest
{
...
...
app/src/androidTest/java/ecom/android/newparkapp/dao/UserDaoTest.java
View file @
d4472e97
...
...
@@ -17,7 +17,6 @@ import org.junit.runner.RunWith;
import
java.util.List
;
import
ecom.android.newparkapp.database.UserDatabase
;
import
ecom.android.newparkapp.entity.User
;
@RunWith
(
AndroidJUnit4
.
class
)
...
...
app/src/main/AndroidManifest.xml
View file @
d4472e97
...
...
@@ -4,6 +4,8 @@
package=
"ecom.android.newparkapp"
>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_CONNECT"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_SCAN"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_ADMIN"
/>
...
...
app/src/main/java/ecom/android/newparkapp/BlueToothComm.java
0 → 100644
View file @
d4472e97
package
ecom
.
android
.
newparkapp
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
androidx.annotation.NonNull
;
public
class
BlueToothComm
{
private
static
final
byte
NUL
=
0x00
;
//#Line feed
private
static
final
byte
LF
=
0x0A
;
//#Line feed
private
static
final
byte
FF
=
0x0C
;
//#Line feed
private
static
final
byte
SUB
=
0x1A
;
private
static
final
byte
ESC
=
0x1B
;
private
static
final
byte
GS
=
0x1D
;
private
static
final
byte
Z
=
0x5A
;
private
static
final
byte
two
=
0x32
;
private
static
final
byte
three
=
0x33
;
private
static
final
byte
at
=
0x40
;
private
static
final
byte
[]
ESC_2
=
{
ESC
,
two
};
//Set default line spacing
/**
* 相關指令請參考P58CII指令集
*/
public
static
void
InitPrinter
(
@NonNull
OutputStream
out
)
{
byte
[]
bInit
=
{
ESC
,
at
};
//ESC @ #Clear data in buffer and reset modes
//byte[] font = {ESC, 0x4d,0x04};
try
{
out
.
write
(
bInit
);
//out.write(font);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
ToBlackMark
(
@NonNull
OutputStream
out
)
{
byte
[]
test
=
{
SUB
,
FF
,
0x01
,
0x03
,
0x28
,
NUL
};
try
{
out
.
write
(
test
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintChangeLine
(
@NonNull
OutputStream
out
,
int
lines
,
int
dotPitch
)
{
byte
[]
ESC_3_n
=
{
ESC
,
three
,
(
byte
)
dotPitch
};
//Set default line spacing
try
{
out
.
write
(
ESC_3_n
);
for
(
int
i
=
0
;
i
<
lines
;
i
++)
{
out
.
write
(
LF
);
}
out
.
write
(
ESC_2
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintString
(
@NonNull
OutputStream
out
,
String
sCode
,
int
dotPitch
,
byte
[]
widthCode
)
{
byte
[]
ESC_3_n
=
{
ESC
,
three
,
(
byte
)
dotPitch
};
//Set line spacing
try
{
if
(
widthCode
!=
null
)
{
out
.
write
(
widthCode
);
}
out
.
write
(
ESC_3_n
);
out
.
write
(
sCode
.
getBytes
(
"BIG5"
));
out
.
write
(
LF
);
if
(
widthCode
!=
null
)
{
widthCode
[
2
]
=
0x00
;
out
.
write
(
widthCode
);
}
out
.
write
(
ESC_2
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintString
(
@NonNull
OutputStream
out
,
String
sCode
,
int
dotPitch
,
boolean
isDoubleW
)
{
byte
[]
ESC_3_n
=
{
ESC
,
three
,
(
byte
)
dotPitch
};
//Set line spacing
byte
[]
doubleWidth
=
{
ESC
,
0x21
,
0x20
};
//ESC ! n
byte
[]
setEmphasized
=
{
ESC
,
0x45
,
1
};
//ESC E n 強調字體
try
{
if
(
isDoubleW
)
{
out
.
write
(
doubleWidth
);
}
out
.
write
(
setEmphasized
);
out
.
write
(
ESC_3_n
);
out
.
write
(
sCode
.
getBytes
(
"BIG5"
));
out
.
write
(
LF
);
if
(
isDoubleW
)
{
doubleWidth
[
2
]
=
0x00
;
out
.
write
(
doubleWidth
);
}
out
.
write
(
ESC_2
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintBarCode
(
@NonNull
OutputStream
out
,
@NonNull
String
barCode
,
boolean
bSecond
)
{
byte
[]
bCodeHRI
=
{
GS
,
0x48
,
0x02
};
//GS H n #Select HRI character print position
byte
[]
bCodeWidth
=
{
GS
,
0x77
,
2
};
//GS w n #Set bar code horizontal size
byte
[]
bCodeHigh
=
{
GS
,
0x68
,
64
};
//GS h n #Set bar code height
byte
[]
bCodeType
=
{
GS
,
0x6B
,
0x45
};
//GS k m … #Print bar code
try
{
out
.
write
(
bCodeHRI
);
out
.
write
(
bCodeHigh
);
out
.
write
(
bCodeWidth
);
out
.
write
(
bCodeType
);
out
.
write
(
barCode
.
length
());
out
.
write
(
barCode
.
getBytes
());
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintBarCodeTest
(
@NonNull
OutputStream
out
,
@NonNull
String
barCode
,
boolean
bSecond
)
{
byte
[]
A
=
{
0x1b
,
0x40
,
0x1d
,
0x48
,
0x00
,
0x1d
,
0x68
,
64
,
0x1d
,
0x77
,
4
};
byte
[]
B
=
{
0x30
,
0x0D
,
0x0A
};
byte
[]
C
=
{
0x1d
,
0x6b
,
0x04
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
31
};
try
{
out
.
write
(
A
);
out
.
write
(
B
);
out
.
write
(
C
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
TestPrintStringUTF8
(
@NonNull
OutputStream
out
,
String
sCode
,
int
dotPitch
,
boolean
isDoubleW
)
{
byte
[]
ESC_3_n
=
{
ESC
,
three
,
(
byte
)
dotPitch
};
//Set line spacing
byte
[]
doubleWidth
=
{
ESC
,
0x21
,
0x20
};
//ESC ! n
byte
[]
setEmphasized
=
{
ESC
,
0x45
,
1
};
//ESC E n
byte
[]
changeEncode
=
{
ESC
,
0x39
,
1
};
//ESC @ #Clear data in buffer and reset modes
try
{
if
(
isDoubleW
)
{
out
.
write
(
doubleWidth
);
}
out
.
write
(
ESC_3_n
);
out
.
write
(
setEmphasized
);
out
.
write
(
changeEncode
);
out
.
write
(
sCode
.
getBytes
(
StandardCharsets
.
UTF_8
));
out
.
write
(
LF
);
if
(
isDoubleW
)
{
doubleWidth
[
2
]
=
0x00
;
out
.
write
(
doubleWidth
);
}
out
.
write
(
ESC_2
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
TestPrintBarCodeHigh
(
@NonNull
OutputStream
out
,
@NonNull
String
barCode
,
boolean
bSecond
)
{
byte
[]
bCodeHRI
=
{
GS
,
0x48
,
0x02
};
//GS H n #Select HRI character print position
byte
[]
bCodeWidth
=
{
GS
,
0x77
,
2
};
//GS w n #Set bar code horizontal size
byte
[]
bCodeHigh
=
{
GS
,
0x68
,
(
byte
)
128
};
//GS h n #Set bar code height
byte
[]
bCodeType
=
{
GS
,
0x6B
,
0x45
};
//GS k m … #Print bar code
try
{
out
.
write
(
bCodeHRI
);
out
.
write
(
bCodeHigh
);
out
.
write
(
bCodeWidth
);
out
.
write
(
bCodeType
);
out
.
write
(
barCode
.
length
());
out
.
write
(
barCode
.
getBytes
());
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintQRCodeTest
(
@NonNull
OutputStream
out
,
@NonNull
String
barCode
)
{
try
{
int
p
=
barCode
.
getBytes
(
"BIG5"
).
length
;
int
pL
=
0
,
pH
=
0
;
//k(字串字元數量)=(pL+pH×256)-3
pL
=
(
p
+
3
)
%
256
;
pH
=
(
p
+
3
)
/
256
;
byte
[]
initPrinter
=
{
ESC
,
at
};
// GS ( k pL pH cn fn n
byte
[]
initQRCode
=
{
GS
,
0x28
,
0x6b
,
0x03
,
0x00
,
0x31
,
0x43
,
0x03
};
//设置QR码的模块类型
byte
[]
QRCodeECC
=
{
GS
,
0x28
,
0x6b
,
0x03
,
0x00
,
0x31
,
0x45
,
0x31
};
//设置QR码的错误校正水平误差
byte
[]
QRCodeBuff
=
{
GS
,
0x28
,
0x6b
,
(
byte
)
pL
,
(
byte
)
pH
,
0x31
,
0x50
,
0x30
};
//存储QR码的数据到QR码缓冲区
byte
[]
cc
=
{
ESC
,
0x61
,
0x01
};
//置中對齊
byte
[]
initQRCode2
=
{
GS
,
0x28
,
0x6b
,
0x03
,
0x00
,
0x31
,
0x52
,
0x30
};
//设置QR码的图形信息
byte
[]
printQRCode
=
{
GS
,
0x28
,
0x6b
,
0x03
,
0x00
,
0x31
,
0x51
,
0x30
};
//打印QR码
//System.err.println("asdasd "+"台中市大里區立新二街89號".getBytes("BIG5").length);
out
.
write
(
initPrinter
);
out
.
write
(
initQRCode
);
out
.
write
(
QRCodeECC
);
out
.
write
(
QRCodeBuff
);
out
.
write
(
barCode
.
getBytes
(
"BIG5"
));
out
.
write
(
cc
);
out
.
write
(
initQRCode2
);
out
.
write
(
printQRCode
);
out
.
write
(
LF
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
InitPrinterOld
(
@NonNull
OutputStream
outPut
)
{
byte
[]
bInit
=
{
ESC
,
at
};
try
{
outPut
.
write
(
bInit
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintTitleOld
(
@NonNull
OutputStream
outPut
,
@NonNull
String
szTitle
)
{
byte
[]
bDbTypeOn
=
{
ESC
,
Z
,
1
};
byte
[]
bDbTypeOff
=
{
ESC
,
Z
,
0
};
try
{
outPut
.
write
(
bDbTypeOn
);
outPut
.
write
(
szTitle
.
getBytes
(
"BIG5"
));
outPut
.
write
(
LF
);
outPut
.
write
(
bDbTypeOff
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintBarCodeOld
(
@NonNull
OutputStream
outPut
,
String
szBarcode
,
boolean
bSecond
)
{
byte
[]
bStringW
=
{
ESC
,
Z
,
1
};
byte
[]
bCodeHRI
=
{
GS
,
0x48
,
0
,
LF
};
byte
[]
bCodeWidth
=
{
GS
,
0x77
,
1
,
LF
};
byte
[]
bCodeHeigh
=
{
GS
,
0x68
,
64
,
LF
};
byte
[]
bCodeType
=
{
GS
,
0x6b
,
0x45
};
//code39
try
{
outPut
.
write
(
bStringW
);
if
(
bSecond
)
{
outPut
.
write
(
bCodeHRI
);
}
outPut
.
write
(
bCodeHeigh
);
outPut
.
write
(
bCodeWidth
);
outPut
.
write
(
bCodeType
);
outPut
.
write
(
szBarcode
.
length
());
outPut
.
write
(
szBarcode
.
getBytes
());
outPut
.
write
(
LF
);
if
(
bSecond
)
{
int
nLen
=
szBarcode
.
length
();
String
szTemp
=
szBarcode
.
substring
(
0
,
nLen
-
2
)
+
"-"
+
szBarcode
.
substring
(
nLen
-
2
,
nLen
);
outPut
.
write
(
szTemp
.
getBytes
());
outPut
.
write
(
LF
);
bCodeHRI
[
2
]
=
2
;
outPut
.
write
(
bCodeHRI
);
}
bStringW
[
2
]
=
0
;
outPut
.
write
(
bStringW
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintStringOld
(
@NonNull
OutputStream
outPut
,
@NonNull
String
szCode
)
{
byte
[]
bSetDB
=
{
ESC
,
Z
,
1
};
try
{
outPut
.
write
(
bSetDB
);
outPut
.
write
(
szCode
.
getBytes
(
"BIG5"
));
outPut
.
write
(
LF
);
bSetDB
[
2
]
=
0
;
outPut
.
write
(
bSetDB
);
outPut
.
write
(
LF
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
PrintBlankLineOld
(
OutputStream
outPut
,
int
nLines
)
{
try
{
for
(
int
i
=
0
;
i
<
nLines
;
++
i
)
{
outPut
.
write
(
LF
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
ToBlackMarkOld
(
@NonNull
OutputStream
outPut
)
{
byte
[]
bBlackMark
=
{
FF
};
try
{
outPut
.
write
(
bBlackMark
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
\ No newline at end of file
app/src/main/java/ecom/android/newparkapp/adapter/ConvertBindingAdapter.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
adapter
;
import
android.graphics.Color
;
import
android.widget.Button
;
import
android.widget.TextView
;
...
...
@@ -9,6 +10,7 @@ import java.text.SimpleDateFormat;
import
java.util.Date
;
import
ecom.android.newparkapp.entity.Case
;
import
ecom.android.newparkapp.viewModel.BlueToothViewModel
;
public
class
ConvertBindingAdapter
{
...
...
@@ -19,4 +21,31 @@ public class ConvertBindingAdapter {
textView
.
setText
(
dateString
);
}
@BindingAdapter
(
"blueToothStatus2String"
)
public
static
void
BlueToothStatus2String
(
TextView
textView
,
BlueToothViewModel
.
BlueToothStatus
blueToothStatus
){
String
message
=
""
;
int
colorCode
=
Color
.
BLACK
;
switch
(
blueToothStatus
){
case
INIT:
message
=
"尚未連接"
;
break
;
case
CONNECTING:
message
=
"連接中"
;
colorCode
=
Color
.
BLUE
;
break
;
case
CONNECT_FAILED:
message
=
"連線失敗"
;
colorCode
=
Color
.
RED
;
break
;
case
CONNECT_SUCCESS:
message
=
"連線正常"
;
colorCode
=
Color
.
GREEN
;
break
;
default
:
return
;
}
textView
.
setText
(
message
);
textView
.
setTextColor
(
colorCode
);
}
}
\ No newline at end of file
app/src/main/java/ecom/android/newparkapp/
entity
/LocationConverter.java
→
app/src/main/java/ecom/android/newparkapp/
converter
/LocationConverter.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
entity
;
package
ecom
.
android
.
newparkapp
.
converter
;
import
android.location.Location
;
...
...
app/src/main/java/ecom/android/newparkapp/converter/SpaceTypeConverter.java
0 → 100644
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
converter
;
import
static
ecom
.
android
.
newparkapp
.
entity
.
Space
.
SpaceType
.
UNSET_SPACE
;
import
androidx.room.ProvidedTypeConverter
;
import
androidx.room.TypeConverter
;
import
ecom.android.newparkapp.entity.Space.SpaceType
;
@ProvidedTypeConverter
public
class
SpaceTypeConverter
{
@TypeConverter
public
static
SpaceType
toSpaceType
(
int
value
)
{
return
value
>
SpaceType
.
values
().
length
?
UNSET_SPACE:
SpaceType
.
values
()[
value
];
}
@TypeConverter
public
static
int
fromSpaceType
(
SpaceType
spaceType
){
return
spaceType
.
ordinal
();
}
}
app/src/main/java/ecom/android/newparkapp/
entity
/TimestampConverter.java
→
app/src/main/java/ecom/android/newparkapp/
converter
/TimestampConverter.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
entity
;
package
ecom
.
android
.
newparkapp
.
converter
;
import
androidx.room.TypeConverter
;
...
...
app/src/main/java/ecom/android/newparkapp/dao/SpaceTypeDao.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
dao
;
import
androidx.lifecycle.LiveData
;
import
androidx.room.Dao
;
import
androidx.room.Delete
;
import
androidx.room.Insert
;
import
androidx.room.Query
;
import
java.util.List
;
import
ecom.android.newparkapp.entity.SpaceType
;
@Dao
public
interface
SpaceTypeDao
{
@Query
(
"SELECT * FROM spacetype"
)
List
<
SpaceType
>
getAll
();
@Query
(
"SELECT * FROM spacetype"
)
LiveData
<
List
<
SpaceType
>>
getAllLiveData
();
@Query
(
"SELECT * FROM spacetype WHERE id IN (:Ids)"
)
List
<
SpaceType
>
loadAllByIds
(
int
[]
Ids
);
@Query
(
"SELECT * FROM spacetype WHERE name LIKE :first LIMIT 1"
)
SpaceType
findByName
(
String
first
);
@Insert
void
insertAll
(
SpaceType
...
spaceTypes
);
@Delete
void
delete
(
SpaceType
spaceType
);
@Query
(
"DELETE FROM spacetype"
)
void
deleteAll
();
}
app/src/main/java/ecom/android/newparkapp/database/CaseDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
androidx.room.TypeConverters
;
import
ecom.android.newparkapp.dao.CaseDao
;
import
ecom.android.newparkapp.entity.Case
;
import
ecom.android.newparkapp.entity.CasePhoto
;
import
ecom.android.newparkapp.entity.LocationConverter
;
import
ecom.android.newparkapp.entity.TimestampConverter
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
Case
.
class
,
CasePhoto
.
class
},
version
=
1
)
@TypeConverters
({
LocationConverter
.
class
,
TimestampConverter
.
class
})
public
abstract
class
CaseDatabase
extends
RoomDatabase
{
public
abstract
CaseDao
caseDao
();
private
static
CaseDatabase
instance
;
public
static
CaseDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
CaseDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
CaseDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/InfoDatabase.java
View file @
d4472e97
...
...
@@ -8,13 +8,13 @@ import androidx.room.RoomDatabase;
import
androidx.room.TypeConverters
;
import
ecom.android.newparkapp.R
;
import
ecom.android.newparkapp.converter.SpaceTypeConverter
;
import
ecom.android.newparkapp.dao.CaseDao
;
import
ecom.android.newparkapp.dao.CasePhotoDao
;
import
ecom.android.newparkapp.dao.RoadDao
;
import
ecom.android.newparkapp.dao.SpaceDao
;
import
ecom.android.newparkapp.dao.SpaceRateDao
;
import
ecom.android.newparkapp.dao.SpaceStatusDao
;
import
ecom.android.newparkapp.dao.SpaceTypeDao
;
import
ecom.android.newparkapp.dao.UserDao
;
import
ecom.android.newparkapp.dao.UserPermissionDao
;
import
ecom.android.newparkapp.dao.VehicleBrandDao
;
...
...
@@ -22,13 +22,12 @@ import ecom.android.newparkapp.dao.VehicleColorDao;
import
ecom.android.newparkapp.dao.VehicleTypeDao
;
import
ecom.android.newparkapp.entity.Case
;
import
ecom.android.newparkapp.entity.CasePhoto
;
import
ecom.android.newparkapp.
entity
.LocationConverter
;
import
ecom.android.newparkapp.
converter
.LocationConverter
;
import
ecom.android.newparkapp.entity.Road
;
import
ecom.android.newparkapp.entity.Space
;
import
ecom.android.newparkapp.entity.SpaceRate
;
import
ecom.android.newparkapp.entity.SpaceStatus
;
import
ecom.android.newparkapp.entity.SpaceType
;
import
ecom.android.newparkapp.entity.TimestampConverter
;
import
ecom.android.newparkapp.converter.TimestampConverter
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.entity.UserPermission
;
import
ecom.android.newparkapp.entity.VehicleBrand
;
...
...
@@ -36,9 +35,9 @@ import ecom.android.newparkapp.entity.VehicleColor;
import
ecom.android.newparkapp.entity.VehicleType
;
// DataBase 一個資料庫一個,並涵蓋多個資料表
@Database
(
entities
=
{
Case
.
class
,
CasePhoto
.
class
,
Road
.
class
,
Space
.
class
,
SpaceRate
.
class
,
SpaceStatus
.
class
,
SpaceType
.
class
,
User
.
class
,
UserPermission
.
class
,
VehicleBrand
.
class
,
VehicleColor
.
class
,
VehicleType
.
class
},
@Database
(
entities
=
{
Case
.
class
,
CasePhoto
.
class
,
Road
.
class
,
Space
.
class
,
SpaceRate
.
class
,
SpaceStatus
.
class
,
User
.
class
,
UserPermission
.
class
,
VehicleBrand
.
class
,
VehicleColor
.
class
,
VehicleType
.
class
},
version
=
1
)
@TypeConverters
({
LocationConverter
.
class
,
TimestampConverter
.
class
})
@TypeConverters
({
LocationConverter
.
class
,
TimestampConverter
.
class
,
SpaceTypeConverter
.
class
})
public
abstract
class
InfoDatabase
extends
RoomDatabase
{
public
abstract
CaseDao
caseDao
();
public
abstract
CasePhotoDao
casePhotoDao
();
...
...
@@ -46,7 +45,6 @@ public abstract class InfoDatabase extends RoomDatabase {
public
abstract
SpaceDao
spaceDao
();
public
abstract
SpaceRateDao
spaceRateDao
();
public
abstract
SpaceStatusDao
spaceStatusDao
();
public
abstract
SpaceTypeDao
spaceTypeDao
();
public
abstract
UserDao
userDao
();
public
abstract
VehicleBrandDao
vehicleBrandDao
();
public
abstract
VehicleColorDao
vehicleColorDao
();
...
...
app/src/main/java/ecom/android/newparkapp/database/RoadDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.RoadDao
;
import
ecom.android.newparkapp.entity.Road
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
Road
.
class
},
version
=
1
)
public
abstract
class
RoadDatabase
extends
RoomDatabase
{
public
abstract
RoadDao
roadDao
();
private
static
RoadDatabase
instance
;
public
static
RoadDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
RoadDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
RoadDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/SpaceDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.SpaceDao
;
import
ecom.android.newparkapp.entity.Space
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
Space
.
class
},
version
=
1
)
public
abstract
class
SpaceDatabase
extends
RoomDatabase
{
public
abstract
SpaceDao
spaceDao
();
private
static
SpaceDatabase
instance
;
public
static
SpaceDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
SpaceDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
SpaceDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/SpaceRateDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.SpaceRateDao
;
import
ecom.android.newparkapp.entity.SpaceRate
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
SpaceRate
.
class
},
version
=
1
)
public
abstract
class
SpaceRateDatabase
extends
RoomDatabase
{
public
abstract
SpaceRateDao
spaceRateDao
();
private
static
SpaceRateDatabase
instance
;
public
static
SpaceRateDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
SpaceRateDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
SpaceRateDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/SpaceStatusDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.SpaceStatusDao
;
import
ecom.android.newparkapp.entity.SpaceStatus
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
SpaceStatus
.
class
},
version
=
1
)
public
abstract
class
SpaceStatusDatabase
extends
RoomDatabase
{
public
abstract
SpaceStatusDao
spaceStatusDao
();
private
static
SpaceStatusDatabase
instance
;
public
static
SpaceStatusDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
SpaceStatusDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
SpaceStatusDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/SpaceTypeDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.SpaceTypeDao
;
import
ecom.android.newparkapp.entity.SpaceType
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
SpaceType
.
class
},
version
=
1
)
public
abstract
class
SpaceTypeDatabase
extends
RoomDatabase
{
public
abstract
SpaceTypeDao
spaceTypeDao
();
private
static
SpaceTypeDatabase
instance
;
public
static
SpaceTypeDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
SpaceTypeDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
SpaceTypeDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/UserDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.UserDao
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
User
.
class
},
version
=
1
)
public
abstract
class
UserDatabase
extends
RoomDatabase
{
public
abstract
UserDao
userDao
();
private
static
UserDatabase
instance
;
public
static
UserDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
UserDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
UserDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/VehicleBrandDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.VehicleBrandDao
;
import
ecom.android.newparkapp.entity.VehicleBrand
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
VehicleBrand
.
class
},
version
=
1
)
public
abstract
class
VehicleBrandDatabase
extends
RoomDatabase
{
public
abstract
VehicleBrandDao
vehicleBrandDao
();
private
static
VehicleBrandDatabase
instance
;
public
static
VehicleBrandDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
VehicleBrandDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
VehicleBrandDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/VehicleColorDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.VehicleColorDao
;
import
ecom.android.newparkapp.entity.VehicleColor
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
VehicleColor
.
class
},
version
=
1
)
public
abstract
class
VehicleColorDatabase
extends
RoomDatabase
{
public
abstract
VehicleColorDao
vehicleColorDao
();
private
static
VehicleColorDatabase
instance
;
public
static
VehicleColorDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
VehicleColorDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
VehicleColorDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/database/VehicleTypeDatabase.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
database
;
import
android.content.Context
;
import
androidx.room.Database
;
import
androidx.room.Room
;
import
androidx.room.RoomDatabase
;
import
ecom.android.newparkapp.dao.VehicleTypeDao
;
import
ecom.android.newparkapp.entity.VehicleType
;
import
ecom.android.newparkapp.R
;
@Database
(
entities
=
{
VehicleType
.
class
},
version
=
1
)
public
abstract
class
VehicleTypeDatabase
extends
RoomDatabase
{
public
abstract
VehicleTypeDao
vehicleTypeDao
();
private
static
VehicleTypeDatabase
instance
;
public
static
VehicleTypeDatabase
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
RoomDatabase
.
Builder
<
VehicleTypeDatabase
>
builder
=
Room
.
databaseBuilder
(
context
.
getApplicationContext
(),
VehicleTypeDatabase
.
class
,
context
.
getString
(
R
.
string
.
info_db
));
instance
=
builder
.
build
();
}
return
instance
;
}
}
app/src/main/java/ecom/android/newparkapp/entity/Case.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
entity
;
import
android.bluetooth.BluetoothDevice
;
import
android.content.pm.PackageManager
;
import
android.location.Location
;
import
android.os.Build
;
import
androidx.annotation.NonNull
;
import
androidx.core.app.ActivityCompat
;
import
androidx.lifecycle.MutableLiveData
;
import
androidx.room.ColumnInfo
;
import
androidx.room.Embedded
;
import
androidx.room.Entity
;
...
...
@@ -11,8 +16,13 @@ import androidx.room.PrimaryKey;
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.Locale
;
import
java.util.Objects
;
import
ecom.android.newparkapp.printer.CarPrinter_TPB250
;
import
ecom.android.newparkapp.printer.IBluetoothPrinter
;
@Entity
public
class
Case
{
...
...
@@ -68,7 +78,7 @@ public class Case {
public
Date
finalTime
;
// 最後一次續單時間
@ColumnInfo
(
name
=
"auto_pay"
)
public
Boolean
autoPay
;
// 自動扣款
public
Boolean
autoPay
=
false
;
// 自動扣款
@ColumnInfo
(
name
=
"agency"
)
public
int
agency
;
...
...
@@ -143,9 +153,7 @@ public class Case {
// TODO: 2022/7/29 加入GPS座標功能後,修改該處假資料
//String locationString = String.format("Lat:%f Lon:%f", location.getLatitude(), location.getLongitude()); // Lat:24.1434911 Lon:120.7285887
String
locationString
=
"Lat:24.1434911 Lon:120.7285887"
;
String
locationString
=
String
.
format
(
"Lat:%f Lon:%f"
,
location
.
getLatitude
(),
location
.
getLongitude
());
// Lat:24.1434911 Lon:120.7285887
return
String
.
format
(
Locale
.
TAIWAN
,
"%s%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%.1f;%d;%s;%s;%d;\r\n"
,
getShift
(),
user
.
id
,
...
...
@@ -164,4 +172,77 @@ public class Case {
billStatus
,
photoCount
);
}
public
Calendar
getCaseCalendar
()
{
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
this
.
caseTime
);
return
calendar
;
}
public
Calendar
getTermCalendar
()
{
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
this
.
terminateDate
);
return
calendar
;
}
/**
* 傳入時間計算是否在開單員工作時段內
* @param mCalendar 時間
*/
public
boolean
isWorkTime
(
Calendar
mCalendar
)
{
Calendar
endTime
=
Calendar
.
getInstance
();
Calendar
startTime
=
Calendar
.
getInstance
();
if
(
isMorningShift
())
{
//08:00-16:30
startTime
.
set
(
Calendar
.
HOUR_OF_DAY
,
8
);
startTime
.
set
(
Calendar
.
MINUTE
,
0
);
startTime
.
set
(
Calendar
.
SECOND
,
0
);
startTime
.
set
(
Calendar
.
MILLISECOND
,
0
);
endTime
.
set
(
Calendar
.
HOUR_OF_DAY
,
16
);
endTime
.
set
(
Calendar
.
MINUTE
,
30
);
endTime
.
set
(
Calendar
.
SECOND
,
0
);
endTime
.
set
(
Calendar
.
MILLISECOND
,
0
);
}
else
{
//13:30-22:00
startTime
.
set
(
Calendar
.
HOUR_OF_DAY
,
13
);
startTime
.
set
(
Calendar
.
MINUTE
,
30
);
startTime
.
set
(
Calendar
.
SECOND
,
0
);
startTime
.
set
(
Calendar
.
MILLISECOND
,
0
);
endTime
.
set
(
Calendar
.
HOUR_OF_DAY
,
22
);
endTime
.
set
(
Calendar
.
MINUTE
,
0
);
endTime
.
set
(
Calendar
.
SECOND
,
0
);
endTime
.
set
(
Calendar
.
MILLISECOND
,
0
);
}
return
mCalendar
.
after
(
startTime
)
&&
mCalendar
.
before
(
endTime
);
}
/**
* @return 是否為早班
*/
private
boolean
isMorningShift
(){
return
true
;
}
/**
* @return 分級停車金額
*/
public
int
getPricing
()
{
return
this
.
space
.
fee
;
}
public
IBluetoothPrinter
getCasePrinter
(
String
bluetoothDeviceName
)
{
IBluetoothPrinter
printer
;
if
(
Objects
.
equals
(
bluetoothDeviceName
.
toUpperCase
().
trim
(),
"P58C"
)
||
Objects
.
equals
(
bluetoothDeviceName
.
toUpperCase
().
trim
(),
"YH-TPB250"
))
{
printer
=
new
CarPrinter_TPB250
();
//汽車用TPB250型印表機版面
}
else
{
// TODO: 2022/8/3 實作 CarPrinter_PK105B 印表機功能
printer
=
null
;
//printer = new CarPrinter_PK105B();//汽車用PK105B型印表機版面
}
// TODO: 2022/8/3 加入 CarPrinter_LK-P34L 印表機功能
return
printer
;
}
}
app/src/main/java/ecom/android/newparkapp/entity/Space.java
View file @
d4472e97
...
...
@@ -20,7 +20,7 @@ public class Space implements Parcelable {
@Embedded
(
prefix
=
"road_"
)
public
Road
road
;
@
Embedded
(
prefix
=
"space_type_
"
)
@
ColumnInfo
(
name
=
"space_type
"
)
public
SpaceType
spaceType
;
@ColumnInfo
(
name
=
"fee"
)
...
...
@@ -52,7 +52,6 @@ public class Space implements Parcelable {
protected
Space
(
Parcel
in
)
{
id
=
in
.
readString
();
road
=
in
.
readParcelable
(
Road
.
class
.
getClassLoader
());
spaceType
=
in
.
readParcelable
(
SpaceType
.
class
.
getClassLoader
());
fee
=
in
.
readInt
();
spaceRate
=
in
.
readParcelable
(
SpaceRate
.
class
.
getClassLoader
());
latitude
=
in
.
readFloat
();
...
...
@@ -64,7 +63,6 @@ public class Space implements Parcelable {
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
dest
.
writeString
(
id
);
dest
.
writeParcelable
(
road
,
flags
);
dest
.
writeParcelable
(
spaceType
,
flags
);
dest
.
writeInt
(
fee
);
dest
.
writeParcelable
(
spaceRate
,
flags
);
dest
.
writeFloat
(
latitude
);
...
...
@@ -90,6 +88,24 @@ public class Space implements Parcelable {
};
public
String
getCombineInfo
()
{
return
String
.
format
(
"%s %s %s %s"
,
id
,
spaceRate
.
id
,
spaceType
.
id
,
road
.
name
);
return
String
.
format
(
"%s %s %s %s"
,
id
,
spaceRate
.
id
,
spaceType
,
road
.
name
);
}
/**
* 轉換開單週期單位,由小時轉換為分鐘
*
* @return 開單時間(單位 : 分鐘)
*/
public
int
getAddMinutes
()
{
return
(
int
)(
60
*
this
.
spaceRate
.
perHours
);
}
public
enum
SpaceType
{
UNSET_SPACE
,
MOTO_SPACE
,
VEHICLE_SPACE
,
HANDICAPPED_SPACE
,
FRIENDLY_SPACE
}
}
app/src/main/java/ecom/android/newparkapp/entity/SpaceType.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
entity
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
import
androidx.room.ColumnInfo
;
import
androidx.room.Entity
;
import
androidx.room.PrimaryKey
;
/**
* 停車格類型資料表
*/
@Entity
public
class
SpaceType
implements
Parcelable
{
@PrimaryKey
public
int
id
;
@ColumnInfo
(
name
=
"name"
)
public
String
name
;
public
SpaceType
(
int
id
,
String
name
)
{
this
.
id
=
id
;
this
.
name
=
name
;
}
protected
SpaceType
(
Parcel
in
)
{
id
=
in
.
readInt
();
name
=
in
.
readString
();
}
@Override
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
dest
.
writeInt
(
id
);
dest
.
writeString
(
name
);
}
@Override
public
int
describeContents
()
{
return
0
;
}
public
static
final
Creator
<
SpaceType
>
CREATOR
=
new
Creator
<
SpaceType
>()
{
@Override
public
SpaceType
createFromParcel
(
Parcel
in
)
{
return
new
SpaceType
(
in
);
}
@Override
public
SpaceType
[]
newArray
(
int
size
)
{
return
new
SpaceType
[
size
];
}
};
}
app/src/main/java/ecom/android/newparkapp/printer/CarPrinter_TPB250.java
0 → 100644
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
printer
;
import
static
ecom
.
android
.
newparkapp
.
BlueToothComm
.
InitPrinter
;
import
static
ecom
.
android
.
newparkapp
.
BlueToothComm
.
PrintBarCode
;
import
static
ecom
.
android
.
newparkapp
.
BlueToothComm
.
PrintChangeLine
;
import
static
ecom
.
android
.
newparkapp
.
BlueToothComm
.
PrintString
;
import
static
ecom
.
android
.
newparkapp
.
BlueToothComm
.
ToBlackMark
;
import
static
ecom
.
android
.
newparkapp
.
entity
.
Space
.
SpaceType
.
HANDICAPPED_SPACE
;
import
static
ecom
.
android
.
newparkapp
.
printer
.
IBluetoothPrinter
.
ResultCode
.
NOT_CONNECT
;
import
static
ecom
.
android
.
newparkapp
.
printer
.
IBluetoothPrinter
.
ResultCode
.
PRINT_SUCCESS
;
import
android.bluetooth.BluetoothSocket
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.util.Calendar
;
import
java.util.Locale
;
import
ecom.android.newparkapp.Common
;
import
ecom.android.newparkapp.entity.Case
;
/**
* 2021年新型印表機
*/
public
class
CarPrinter_TPB250
implements
IBluetoothPrinter
{
@Override
public
ResultCode
print
(
BluetoothSocket
socketBT
,
Case
thisCase
)
throws
IOException
{
OutputStream
outPutBT
=
socketBT
.
getOutputStream
();
boolean
b60Min
=
false
;
Calendar
nowCalendar
;
Case
carCase
=
thisCase
;
if
(
outPutBT
==
null
||
!
socketBT
.
isConnected
())
{
return
NOT_CONNECT
;
}
InitPrinter
(
outPutBT
);
PrintChangeLine
(
outPutBT
,
1
,
76
);
if
(!
carCase
.
autoPay
)
{
//第一段條碼//
PrintBarCode
(
outPutBT
,
carCase
.
billingNumber1
,
false
);
}
else
{
PrintString
(
outPutBT
,
"※本車已約定金融、電信帳戶代繳,請勿重複繳費、並維持正常扣繳;如扣繳失敗請依背面說明補單繳款。"
,
32
,
false
);
//PrintChangeLine(outPutBT, 1, 24);
}
PrintChangeLine
(
outPutBT
,
1
,
24
);
//-------------------------------------------
//車牌
PrintString
(
outPutBT
,
" "
+
carCase
.
plateNumber
,
52
,
true
);
//-------------------------------------------
//路段、格號
PrintString
(
outPutBT
,
" "
+
carCase
.
space
.
id
+
" "
+
carCase
.
space
.
road
.
name
,
52
,
true
);
//-------------------------------------------
//日期
PrintString
(
outPutBT
,
" "
+
String
.
format
(
"%s年%s月%s日"
,
Common
.
getDate
(
carCase
.
getCaseCalendar
(),
true
).
substring
(
0
,
3
),
Common
.
getDate
(
carCase
.
getCaseCalendar
(),
true
).
substring
(
3
,
5
),
Common
.
getDate
(
carCase
.
getCaseCalendar
(),
true
).
substring
(
5
,
7
)),
40
,
true
);
//-------------------------------------------
//單號2
PrintBarCode
(
outPutBT
,
carCase
.
billingNumber2
,
false
);
PrintChangeLine
(
outPutBT
,
1
,
34
);
//-------------------------------------------
//繳費期限
PrintString
(
outPutBT
,
" "
+
String
.
format
(
"%s %s %s"
,
Common
.
getDate
(
carCase
.
getTermCalendar
(),
true
).
substring
(
0
,
3
),
Common
.
getDate
(
carCase
.
getTermCalendar
(),
true
).
substring
(
3
,
5
),
Common
.
getDate
(
carCase
.
getTermCalendar
(),
true
).
substring
(
5
,
7
)),
90
,
false
);
//-------------------------------------------
nowCalendar
=
(
Calendar
)
carCase
.
getCaseCalendar
().
clone
();
int
nHour
=
carCase
.
getCaseCalendar
().
get
(
Calendar
.
HOUR_OF_DAY
);
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
//開單累加最多累積4次
if
(!
carCase
.
isWorkTime
(
nowCalendar
))
{
//若第i行時間已超過該班次區間,則停止列印(PS.列印長度太短會導致黑點定位查找距離不夠到下一個黑點,利用換行增加)
for
(
int
j
=
0
;
j
<
4
-
i
;
j
++)
{
PrintString
(
outPutBT
,
""
,
52
,
false
);
}
break
;
}
String
szList
=
(
0
==
i
)
?
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5d %s"
,
nHour
,
nowCalendar
.
get
(
Calendar
.
MINUTE
),
carCase
.
getPricing
(),
carCase
.
user
.
name
)
:
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5s %s"
,
nHour
+
(
b60Min
?
1
:
0
),
b60Min
?
0
:
(
nowCalendar
.
get
(
Calendar
.
MINUTE
)
+
1
),
" "
,
"________"
);
if
(
carCase
.
space
.
spaceType
==
HANDICAPPED_SPACE
)
{
//身障車格
if
(
carCase
.
vehicleType
.
id
==
12
)
{
//身心障礙(府-2)
if
(
i
==
0
)
{
szList
=
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5d %s"
,
nHour
,
nowCalendar
.
get
(
Calendar
.
MINUTE
),
carCase
.
getPricing
(),
carCase
.
user
.
name
);
}
else
if
(
i
==
1
)
{
szList
=
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5s %s"
,
nHour
+
(
b60Min
?
1
:
0
),
b60Min
?
0
:
(
nowCalendar
.
get
(
Calendar
.
MINUTE
)
+
1
),
carCase
.
getPricing
(),
"________"
);
}
else
{
szList
=
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5s %s"
,
nHour
+
(
b60Min
?
1
:
0
),
b60Min
?
0
:
(
nowCalendar
.
get
(
Calendar
.
MINUTE
)
+
1
),
" "
,
"________"
);
}
}
else
if
(
carCase
.
vehicleType
.
id
==
13
)
{
//身心障礙(社-4)
szList
=
(
0
==
i
)
?
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5d %s"
,
nHour
,
nowCalendar
.
get
(
Calendar
.
MINUTE
),
carCase
.
getPricing
(),
carCase
.
user
.
name
)
:
String
.
format
(
Locale
.
TAIWAN
,
" %02d:%02d %5s %s"
,
nHour
+
(
b60Min
?
1
:
0
),
b60Min
?
0
:
(
nowCalendar
.
get
(
Calendar
.
MINUTE
)
+
1
),
carCase
.
getPricing
(),
"________"
);
}
}
nowCalendar
.
add
(
Calendar
.
MINUTE
,
carCase
.
space
.
getAddMinutes
());
nHour
=
nowCalendar
.
get
(
Calendar
.
HOUR_OF_DAY
);
b60Min
=
nowCalendar
.
get
(
Calendar
.
MINUTE
)
==
59
;
PrintString
(
outPutBT
,
szList
,
40
,
new
byte
[]{
0x1D
,
0x21
,
0x01
});
}
PrintChangeLine
(
outPutBT
,
1
,
120
);
//PrintString(outPutBT, "※如已有申請停車費自動扣款或行動支付服務,請勿持本單重複繳費。", 26, false);
PrintChangeLine
(
outPutBT
,
2
,
80
);
//減少黑點定位查找距離
//-------------------------------------------
ToBlackMark
(
outPutBT
);
InitPrinter
(
outPutBT
);
return
PRINT_SUCCESS
;
}
}
app/src/main/java/ecom/android/newparkapp/printer/IBluetoothPrinter.java
0 → 100644
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
printer
;
import
android.bluetooth.BluetoothSocket
;
import
java.io.IOException
;
import
ecom.android.newparkapp.entity.Case
;
/**
* 自訂列印的內容、行數
*/
public
interface
IBluetoothPrinter
{
enum
ResultCode
{
PRINT_SUCCESS
,
NOT_CONNECT
,
NOT_WORK_TIME
}
ResultCode
print
(
BluetoothSocket
socketBT
,
Case
thisCase
)
throws
IOException
;
}
app/src/main/java/ecom/android/newparkapp/repository/InfoRepository.java
View file @
d4472e97
...
...
@@ -12,14 +12,12 @@ import ecom.android.newparkapp.dao.RoadDao;
import
ecom.android.newparkapp.dao.SpaceDao
;
import
ecom.android.newparkapp.dao.SpaceRateDao
;
import
ecom.android.newparkapp.dao.SpaceStatusDao
;
import
ecom.android.newparkapp.dao.SpaceTypeDao
;
import
ecom.android.newparkapp.dao.UserDao
;
import
ecom.android.newparkapp.dao.UserPermissionDao
;
import
ecom.android.newparkapp.dao.VehicleBrandDao
;
import
ecom.android.newparkapp.dao.VehicleColorDao
;
import
ecom.android.newparkapp.dao.VehicleTypeDao
;
import
ecom.android.newparkapp.database.InfoDatabase
;
import
ecom.android.newparkapp.entity.Road
;
public
class
InfoRepository
{
private
InfoDatabase
infoDatabase
;
...
...
@@ -33,7 +31,6 @@ public class InfoRepository {
public
UserDao
userDao
;
public
UserPermissionDao
userPermissionDao
;
public
SpaceTypeDao
spaceTypeDao
;
public
SpaceStatusDao
spaceStatusDao
;
public
SpaceRateDao
spaceRateDao
;
public
RoadDao
roadDao
;
...
...
@@ -51,7 +48,6 @@ public class InfoRepository {
userDao
=
infoDatabase
.
userDao
();
userPermissionDao
=
infoDatabase
.
userPermissionDao
();
spaceTypeDao
=
infoDatabase
.
spaceTypeDao
();
spaceStatusDao
=
infoDatabase
.
spaceStatusDao
();
spaceRateDao
=
infoDatabase
.
spaceRateDao
();
roadDao
=
infoDatabase
.
roadDao
();
...
...
app/src/main/java/ecom/android/newparkapp/view/MainActivity.java
View file @
d4472e97
...
...
@@ -24,32 +24,31 @@ import java.util.Map;
import
ecom.android.newparkapp.R
;
import
ecom.android.newparkapp.databinding.ActivityMainBinding
;
import
ecom.android.newparkapp.viewModel.UserViewModel
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.viewModel.T01SettingViewModel
;
public
class
MainActivity
extends
AppCompatActivity
{
private
ActivityMainBinding
dataBinding
;
private
ViewModelProvider
viewModelProvider
;
private
UserViewModel
userViewModel
;
private
T01SettingViewModel
t01SettingViewModel
;
private
ActivityResultLauncher
<
String
[]>
requestPermissionLauncher
;
private
String
[]
permissions
=
new
String
[]{
WRITE_EXTERNAL_STORAGE
,
READ_EXTERNAL_STORAGE
,
ACCESS_COARSE_LOCATION
,
ACCESS_FINE_LOCATION
,
ACCESS_LOCATION_EXTRA_COMMANDS
};
private
MutableLiveData
<
Boolean
>
hasPermissions
=
new
MutableLiveData
<>();
private
ActivityResultLauncher
settingActivityResultLauncher
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
dataBinding
=
DataBindingUtil
.
setContentView
(
this
,
R
.
layout
.
activity_main
);
viewModelProvider
=
new
ViewModelProvider
(
this
);
userViewModel
=
viewModelProvider
.
get
(
UserViewModel
.
class
);
userViewModel
.
setCurrentUser
();
dataBinding
.
setUserViewModel
(
userViewModel
);
t01SettingViewModel
=
viewModelProvider
.
get
(
T01SettingViewModel
.
class
);
initLayout
();
// 註冊權限請求結果處理
resultLauncherRegister
();
// 檢查權限
...
...
@@ -59,6 +58,7 @@ public class MainActivity extends AppCompatActivity {
// 有權限再綁定按鈕功能
hasPermissions
.
observe
(
this
,
has
->
{
if
(
has
){
// 註冊事件綁定
eventBinding
();
}
});
...
...
@@ -79,6 +79,14 @@ public class MainActivity extends AppCompatActivity {
// 離開按鈕事件註冊
dataBinding
.
btnExitApp
.
setOnClickListener
(
view
->
android
.
os
.
Process
.
killProcess
(
android
.
os
.
Process
.
myPid
()));
// 當前使用者設置
User
currentUser
=
t01SettingViewModel
.
getCurrentUser
();
if
(
currentUser
!=
null
){
dataBinding
.
tvCurrentUsr
.
setText
(
getString
(
R
.
string
.
current_user
,
currentUser
.
id
+
" "
+
currentUser
.
name
));
}
else
{
dataBinding
.
tvCurrentUsr
.
setText
(
"請先設定當前使用者"
);
}
}
/**
...
...
@@ -123,6 +131,20 @@ public class MainActivity extends AppCompatActivity {
hasPermissions
.
setValue
(
true
);
}
);
settingActivityResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
// 重新讀取setting
t01SettingViewModel
.
restorePrefs
();
// 當前使用者設置
User
currentUser
=
t01SettingViewModel
.
getCurrentUser
();
if
(
currentUser
!=
null
){
dataBinding
.
tvCurrentUsr
.
setText
(
getString
(
R
.
string
.
current_user
,
currentUser
.
id
+
" "
+
currentUser
.
name
));
}
else
{
dataBinding
.
tvCurrentUsr
.
setText
(
"請先設定當前使用者"
);
}
});
}
/**
...
...
@@ -136,20 +158,20 @@ public class MainActivity extends AppCompatActivity {
private
void
btnStartOnClicked
(){
if
(
userViewModel
.
getCurrentUser
().
getValue
()
==
null
){
if
(
t01SettingViewModel
.
getCurrentUser
()
==
null
||
t01SettingViewModel
.
getCurrentUser
().
id
==
999
){
Toast
.
makeText
(
this
,
"請先設定使用者"
,
Toast
.
LENGTH_LONG
).
show
();
return
;
}
Intent
intent
=
new
Intent
();
intent
.
setClass
(
this
,
T02StartActivity
.
class
);
intent
.
putExtra
(
"CurrentUser"
,
userViewModel
.
getCurrentUser
().
getValue
());
intent
.
putExtra
(
"CurrentUser"
,
t01SettingViewModel
.
getCurrentUser
());
startActivity
(
intent
);
}
private
void
btnGoSettingOnClicked
(){
Intent
intent
=
new
Intent
();
intent
.
setClass
(
this
,
T01SettingActivity
.
class
);
s
tartActivity
(
intent
);
s
ettingActivityResultLauncher
.
launch
(
intent
);
}
}
\ No newline at end of file
app/src/main/java/ecom/android/newparkapp/view/T01SettingActivity.java
View file @
d4472e97
...
...
@@ -13,9 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
import
androidx.appcompat.app.ActionBar
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.databinding.DataBindingUtil
;
import
androidx.lifecycle.LiveData
;
import
androidx.lifecycle.ViewModelProvider
;
import
androidx.preference.PreferenceFragmentCompat
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -23,9 +21,7 @@ import java.util.List;
import
ecom.android.newparkapp.R
;
import
ecom.android.newparkapp.databinding.ActivityT01SettingLayoutBinding
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.entity.VehicleType
;
import
ecom.android.newparkapp.viewModel.T01SettingViewModel
;
import
ecom.android.newparkapp.viewModel.UserViewModel
;
public
class
T01SettingActivity
extends
AppCompatActivity
{
...
...
@@ -35,7 +31,7 @@ public class T01SettingActivity extends AppCompatActivity {
private
T01SettingViewModel
t01SettingViewModel
;
private
ActivityResultLauncher
UserResultLauncher
;
private
List
<
User
>
Users
;
private
UserViewModel
userViewModel
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
...
...
@@ -45,7 +41,6 @@ public class T01SettingActivity extends AppCompatActivity {
viewModelProvider
=
new
ViewModelProvider
(
this
);
t01SettingViewModel
=
viewModelProvider
.
get
(
T01SettingViewModel
.
class
);
userViewModel
=
viewModelProvider
.
get
(
UserViewModel
.
class
);
dataBinding
.
setT01SettingViewModel
(
t01SettingViewModel
);
ActionBar
actionBar
=
getSupportActionBar
();
...
...
@@ -63,7 +58,6 @@ public class T01SettingActivity extends AppCompatActivity {
protected
void
onPause
()
{
super
.
onPause
();
t01SettingViewModel
.
savePrefs
();
userViewModel
.
setCurrentUser
(
t01SettingViewModel
.
getCurrentUser
());
}
// public static class SettingsFragment extends PreferenceFragmentCompat {
// @Override
...
...
app/src/main/java/ecom/android/newparkapp/view/T02StartActivity.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
view
;
import
androidx.activity.result.ActivityResultLauncher
;
import
androidx.activity.result.contract.ActivityResultContracts
;
import
androidx.appcompat.app.AlertDialog
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.core.content.FileProvider
;
import
androidx.databinding.DataBindingUtil
;
import
androidx.lifecycle.ViewModelProvider
;
import
static
android
.
Manifest
.
permission
.
BLUETOOTH_CONNECT
;
import
static
android
.
Manifest
.
permission
.
BLUETOOTH_SCAN
;
import
android.bluetooth.BluetoothAdapter
;
import
android.content.Intent
;
import
android.content.pm.ActivityInfo
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Environment
;
import
android.provider.MediaStore
;
import
android.util.DisplayMetrics
;
import
android.view.LayoutInflater
;
import
android.view.WindowManager
;
import
android.widget.ArrayAdapter
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
androidx.activity.result.ActivityResultLauncher
;
import
androidx.activity.result.contract.ActivityResultContracts
;
import
androidx.appcompat.app.AlertDialog
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.FileProvider
;
import
androidx.databinding.DataBindingUtil
;
import
androidx.lifecycle.MutableLiveData
;
import
androidx.lifecycle.ViewModelProvider
;
import
java.io.File
;
import
java.text.SimpleDateFormat
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.Map
;
import
ecom.android.newparkapp.R
;
import
ecom.android.newparkapp.databinding.ActivityT02StartBinding
;
import
ecom.android.newparkapp.databinding.AlertDialogT02DeviceListBinding
;
import
ecom.android.newparkapp.databinding.AlertDialogT03CumulativeTimeBinding
;
import
ecom.android.newparkapp.databinding.AlertDialogProgressBarBinding
;
import
ecom.android.newparkapp.entity.Case
;
import
ecom.android.newparkapp.entity.CaseStatus
;
import
ecom.android.newparkapp.entity.Space
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.entity.VehicleType
;
import
ecom.android.newparkapp.viewModel.BlueToothViewModel
;
import
ecom.android.newparkapp.viewModel.FusedGpsViewModel
;
import
ecom.android.newparkapp.viewModel.T01SettingViewModel
;
import
ecom.android.newparkapp.viewModel.T02StartViewModel
;
import
ecom.android.newparkapp.databinding.ActivityT02StartBinding
;
import
ecom.android.newparkapp.databinding.AlertDialogT03CumulativeTimeBinding
;
public
class
T02StartActivity
extends
AppCompatActivity
{
private
ActivityT02StartBinding
dataBinding
;
private
ViewModelProvider
viewModelProvider
;
private
T02StartViewModel
t02StartViewModel
;
private
T01SettingViewModel
t01SettingViewModel
;
private
FusedGpsViewModel
fusedGpsViewModel
;
private
BlueToothViewModel
blueToothViewModel
;
//藍芽相關
private
ArrayAdapter
<
String
>
deviceNameArrayAdapter
;
private
MutableLiveData
<
Boolean
>
hasPermissions
=
new
MutableLiveData
<>();
private
String
[]
bluetoothPermissions
=
new
String
[]{
BLUETOOTH_CONNECT
,
BLUETOOTH_SCAN
};
private
ActivityResultLauncher
vehicleTypeResultLauncher
;
private
ActivityResultLauncher
spaceResultLauncher
;
...
...
@@ -44,10 +71,15 @@ public class T02StartActivity extends AppCompatActivity {
private
ActivityResultLauncher
takePhotosActivityResultLauncher
;
private
ActivityResultLauncher
cumulativeTimeActivityResultLauncher
;
private
ActivityResultLauncher
inventoryActivityResultLauncher
;
private
ActivityResultLauncher
requestMultiplePermissions
;
private
ActivityResultLauncher
requestBluetooth
;
private
User
currentUser
;
private
File
photoFile
;
private
AlertDialog
alertDialogProgress
;
private
AlertDialogProgressBarBinding
alertDialogProgressBarBinding
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
...
...
@@ -56,23 +88,39 @@ public class T02StartActivity extends AppCompatActivity {
viewModelProvider
=
new
ViewModelProvider
(
this
);
t02StartViewModel
=
viewModelProvider
.
get
(
T02StartViewModel
.
class
);
t01SettingViewModel
=
viewModelProvider
.
get
(
T01SettingViewModel
.
class
);
fusedGpsViewModel
=
viewModelProvider
.
get
(
FusedGpsViewModel
.
class
);
blueToothViewModel
=
viewModelProvider
.
get
(
BlueToothViewModel
.
class
);
currentUser
=
t01SettingViewModel
.
getCurrentUser
();
if
(
currentUser
==
null
)
{
finish
();
}
t02StartViewModel
.
setCurrentUser
(
currentUser
);
t02StartViewModel
.
initCurrentCase
();
dataBinding
.
setT02StartViewModel
(
t02StartViewModel
);
dataBinding
.
setBlueToothViewModel
(
blueToothViewModel
);
eventBinding
();
resultLauncherRegister
();
observeBinding
();
currentUser
=
getIntent
().
getParcelableExtra
(
"CurrentUser"
);
t02StartViewModel
.
setCurrentUser
(
currentUser
);
t02StartViewModel
.
initCurrentCase
();
// 搜尋監聽藍芽裝置
hasPermissions
.
setValue
(
false
);
initBlueTooth
();
// progress alert dialog init
initAlertDialogProgress
();
}
private
void
eventBinding
(){
private
void
eventBinding
()
{
dataBinding
.
btnParkingSpace
.
setOnClickListener
(
v
->
btnParkingSpaceOnClicked
());
dataBinding
.
btnVehicleType
.
setOnClickListener
(
v
->
btnVehicleTypeOnClicked
());
dataBinding
.
btnTimeNow
.
setOnClickListener
(
v
->
btnTimeNowOnClicked
());
dataBinding
.
btnPlateNumber
.
setOnClickListener
(
v
->
btnPlateNumberOnClicked
());
dataBinding
.
btnPlateNumber
.
setOnClickListener
(
v
->
btnPlateNumberOnClicked
());
dataBinding
.
btnPhotograph
.
setOnClickListener
(
v
->
btnPhotographOnClicked
());
dataBinding
.
btnNewPage
.
setOnClickListener
(
v
->
btnNewPageOnClicked
());
dataBinding
.
btnPageDown
.
setOnClickListener
(
v
->
btnPageDownOnClicked
());
...
...
@@ -80,16 +128,18 @@ public class T02StartActivity extends AppCompatActivity {
dataBinding
.
btnPhotoCount
.
setOnClickListener
(
v
->
btnPhotoCountOnClicked
());
dataBinding
.
btnCumulativeTime
.
setOnClickListener
(
v
->
btnCumulativeTimeOnClicked
());
dataBinding
.
btnInventory
.
setOnClickListener
(
v
->
btnInventoryOnClicked
());
dataBinding
.
btnMonthlyReport
.
setOnClickListener
(
v
->
btnMonthlyReportOnClicked
());
dataBinding
.
btnMonthlyReport
.
setOnClickListener
(
v
->
btnMonthlyReportOnClicked
());
dataBinding
.
btnPrint
.
setOnClickListener
(
v
->
btnPrintOnClicked
());
dataBinding
.
btnStartBack
.
setOnClickListener
(
v
->
{
finish
();});
dataBinding
.
btnStartBack
.
setOnClickListener
(
v
->
{
finish
();
});
}
private
void
resultLauncherRegister
(){
private
void
resultLauncherRegister
()
{
vehicleTypeResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
)
{
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
)
{
VehicleType
selectedVehicleType
=
result
.
getData
().
getParcelableExtra
(
"VehicleType"
);
Toast
.
makeText
(
this
,
selectedVehicleType
.
id
+
" "
+
selectedVehicleType
.
name
,
Toast
.
LENGTH_SHORT
).
show
();
...
...
@@ -98,7 +148,7 @@ public class T02StartActivity extends AppCompatActivity {
});
spaceResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
){
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
)
{
Space
selectedSpace
=
result
.
getData
().
getParcelableExtra
(
"Space"
);
Toast
.
makeText
(
this
,
selectedSpace
.
road
.
name
+
" "
+
selectedSpace
.
id
,
Toast
.
LENGTH_SHORT
).
show
();
...
...
@@ -107,7 +157,7 @@ public class T02StartActivity extends AppCompatActivity {
});
plateNumberResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
){
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
)
{
String
plateNumber
=
result
.
getData
().
getStringExtra
(
"PlateNumber"
);
t02StartViewModel
.
setPlateNumber
(
plateNumber
);
...
...
@@ -115,8 +165,8 @@ public class T02StartActivity extends AppCompatActivity {
});
takePhotosActivityResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
){
if
(
photoFile
==
null
)
{
if
(
result
.
getResultCode
()
==
RESULT_OK
)
{
if
(
photoFile
==
null
)
{
return
;
}
t02StartViewModel
.
takeNewPhoto
(
photoFile
);
...
...
@@ -124,8 +174,8 @@ public class T02StartActivity extends AppCompatActivity {
});
cumulativeTimeActivityResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
){
if
(
photoFile
==
null
)
{
if
(
result
.
getResultCode
()
==
RESULT_OK
)
{
if
(
photoFile
==
null
)
{
return
;
}
t02StartViewModel
.
cumulativeTime
(
photoFile
);
...
...
@@ -133,41 +183,79 @@ public class T02StartActivity extends AppCompatActivity {
});
inventoryActivityResultLauncher
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
){
if
(
result
.
getResultCode
()
==
RESULT_OK
&&
result
.
getData
()
!=
null
)
{
int
position
=
result
.
getData
().
getIntExtra
(
"Position"
,
-
1
);
boolean
hasCase
=
false
;
if
(
position
>=
0
){
if
(
position
>=
0
)
{
hasCase
=
t02StartViewModel
.
go2Page
(
position
);
}
if
(!
hasCase
){
if
(!
hasCase
)
{
Toast
.
makeText
(
this
,
"指標索引錯誤"
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
});
requestMultiplePermissions
=
registerForActivityResult
(
new
ActivityResultContracts
.
RequestMultiplePermissions
(),
results
->
{
for
(
Map
.
Entry
<
String
,
Boolean
>
result
:
results
.
entrySet
())
{
if
(!
result
.
getValue
()){
return
;
}
}
hasPermissions
.
setValue
(
true
);
});
requestBluetooth
=
registerForActivityResult
(
new
ActivityResultContracts
.
StartActivityForResult
(),
result
->
{
if
(
result
.
getResultCode
()
==
RESULT_OK
)
{
selectPrinterDialog
();
}
});
}
private
void
observeBinding
(){
private
void
observeBinding
()
{
t02StartViewModel
.
getCaseCursor
().
observe
(
this
,
caseCursor
->
{
// 判斷當前,是否為第一筆
if
(
caseCursor
==
0
){
if
(
caseCursor
==
0
)
{
if
(
dataBinding
.
btnPageUp
.
isEnabled
())
dataBinding
.
btnPageUp
.
setEnabled
(
false
);
}
else
{
if
(!
dataBinding
.
btnPageUp
.
isEnabled
())
dataBinding
.
btnPageUp
.
setEnabled
(
true
);
}
else
{
if
(!
dataBinding
.
btnPageUp
.
isEnabled
())
dataBinding
.
btnPageUp
.
setEnabled
(
true
);
}
// 判斷當前,是否為最後一起
if
(
t02StartViewModel
.
isLastCase
()){
if
(
t02StartViewModel
.
isLastCase
())
{
if
(
dataBinding
.
btnPageDown
.
isEnabled
())
dataBinding
.
btnPageDown
.
setEnabled
(
false
);
}
else
{
}
else
{
if
(!
dataBinding
.
btnPageDown
.
isEnabled
())
dataBinding
.
btnPageDown
.
setEnabled
(
true
);
}
});
fusedGpsViewModel
.
getLocation
().
observe
(
this
,
location
->
{
if
(
t02StartViewModel
.
getCurrentCase
().
getValue
()
!=
null
&&
t02StartViewModel
.
getCurrentCase
().
getValue
().
caseStatus
==
CaseStatus
.
NEW
)
{
t02StartViewModel
.
setLocation
(
location
);
}
});
fusedGpsViewModel
.
getLastUpdateTime
().
observe
(
this
,
date
->
{
if
(
t02StartViewModel
.
getCurrentCase
().
getValue
()
!=
null
&&
t02StartViewModel
.
getCurrentCase
().
getValue
().
caseStatus
==
CaseStatus
.
NEW
)
{
SimpleDateFormat
simpleDateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
dataBinding
.
lastUpdateTimeText
.
setText
(
getString
(
R
.
string
.
last_location_time_textView
,
simpleDateFormat
.
format
(
date
)));
}
});
blueToothViewModel
.
getBlueToothStatus
().
observe
(
this
,
blueToothStatus
->
{
if
(
blueToothStatus
==
BlueToothViewModel
.
BlueToothStatus
.
PRINTING
){
setAlertDialogProgressMessage
(
"列印中,請稍後"
);
alertDialogProgress
.
show
();
}
if
(
blueToothStatus
==
BlueToothViewModel
.
BlueToothStatus
.
PRINT_COMPLETE
){
alertDialogProgress
.
dismiss
();
}
});
}
private
void
btnParkingSpaceOnClicked
(){
private
void
btnParkingSpaceOnClicked
()
{
Intent
intent
=
new
Intent
();
Bundle
bundle
=
new
Bundle
();
intent
.
setClass
(
this
,
T02SelectSpaceActivity
.
class
);
...
...
@@ -176,7 +264,7 @@ public class T02StartActivity extends AppCompatActivity {
spaceResultLauncher
.
launch
(
intent
);
}
private
void
btnVehicleTypeOnClicked
(){
private
void
btnVehicleTypeOnClicked
()
{
Intent
intent
=
new
Intent
();
Bundle
bundle
=
new
Bundle
();
intent
.
setClass
(
this
,
T02SelectVehicleTypeActivity
.
class
);
...
...
@@ -184,7 +272,7 @@ public class T02StartActivity extends AppCompatActivity {
vehicleTypeResultLauncher
.
launch
(
intent
);
}
private
void
btnTimeNowOnClicked
(){
private
void
btnTimeNowOnClicked
()
{
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
this
);
builder
.
setTitle
(
"時間修改"
);
builder
.
setMessage
(
"是否更改為現在的時間"
);
...
...
@@ -192,20 +280,20 @@ public class T02StartActivity extends AppCompatActivity {
builder
.
setPositiveButton
(
"確認"
,
(
dialogInterface
,
i
)
->
{
t02StartViewModel
.
updateCaseDate
();
});
builder
.
setNegativeButton
(
"取消"
,(
dialogInterface
,
i
)
->
{
builder
.
setNegativeButton
(
"取消"
,
(
dialogInterface
,
i
)
->
{
dialogInterface
.
dismiss
();
});
builder
.
create
().
show
();
}
private
void
btnPlateNumberOnClicked
(){
private
void
btnPlateNumberOnClicked
()
{
Intent
intent
=
new
Intent
();
intent
.
setClass
(
this
,
T02KeyInPlateNumberActivity
.
class
);
plateNumberResultLauncher
.
launch
(
intent
);
}
private
void
btnPhotographOnClicked
(){
private
void
btnPhotographOnClicked
()
{
takePhoto
(
takePhotosActivityResultLauncher
);
}
...
...
@@ -213,10 +301,10 @@ public class T02StartActivity extends AppCompatActivity {
* 拍照功能,傳入不同的 ActivityResultLauncher,來接收不同的拍照邏輯
* @param activityResultLauncher 不同的事件處理器
*/
private
void
takePhoto
(
ActivityResultLauncher
activityResultLauncher
){
private
void
takePhoto
(
ActivityResultLauncher
activityResultLauncher
)
{
Case
currentCase
=
t02StartViewModel
.
getCurrentCase
().
getValue
();
if
(
currentCase
==
null
){
if
(
currentCase
==
null
)
{
return
;
}
...
...
@@ -244,37 +332,37 @@ public class T02StartActivity extends AppCompatActivity {
activityResultLauncher
.
launch
(
takePhotoIntent
);
}
private
void
btnNewPageOnClicked
(){
if
(!
t02StartViewModel
.
caseDataConfirm
()){
private
void
btnNewPageOnClicked
()
{
if
(!
t02StartViewModel
.
caseDataConfirm
())
{
// 資料不完整
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
this
);
builder
.
setTitle
(
"檔案保存"
);
builder
.
setMessage
(
"資料不完整,請重新確認"
);
builder
.
setPositiveButton
(
"清空"
,(
dialogInterface
,
i
)
->
{
builder
.
setPositiveButton
(
"清空"
,
(
dialogInterface
,
i
)
->
{
t02StartViewModel
.
initCurrentCase
();
});
builder
.
setNegativeButton
(
"返回"
,(
dialogInterface
,
i
)
->
{
builder
.
setNegativeButton
(
"返回"
,
(
dialogInterface
,
i
)
->
{
dialogInterface
.
dismiss
();
});
builder
.
create
().
show
();
}
else
{
}
else
{
// 資料完整
// 儲存
t02StartViewModel
.
saveCurrentCase
();
}
}
private
void
btnPageDownOnClicked
(){
private
void
btnPageDownOnClicked
()
{
t02StartViewModel
.
pageDown
();
}
private
void
btnPageUpOnClicked
(){
private
void
btnPageUpOnClicked
()
{
t02StartViewModel
.
pageUp
();
}
private
void
btnPhotoCountOnClicked
(){
private
void
btnPhotoCountOnClicked
()
{
Case
tempCase
=
t02StartViewModel
.
getCurrentCase
().
getValue
();
if
(
tempCase
==
null
||
tempCase
.
photoCount
==
0
||
tempCase
.
billingNumber2
.
trim
().
isEmpty
()){
if
(
tempCase
==
null
||
tempCase
.
photoCount
==
0
||
tempCase
.
billingNumber2
.
trim
().
isEmpty
())
{
return
;
}
Intent
intent
=
new
Intent
();
...
...
@@ -284,11 +372,13 @@ public class T02StartActivity extends AppCompatActivity {
}
private
void
btnCumulativeTimeOnClicked
(){
private
void
btnCumulativeTimeOnClicked
()
{
Case
tempCase
=
t02StartViewModel
.
getCurrentCase
().
getValue
();
if
(
tempCase
==
null
){
return
;}
if
(
tempCase
.
caseStatus
==
CaseStatus
.
NEW
){
if
(
tempCase
==
null
)
{
return
;
}
if
(
tempCase
.
caseStatus
==
CaseStatus
.
NEW
)
{
Toast
.
makeText
(
this
,
"請先設定格位"
,
Toast
.
LENGTH_SHORT
).
show
();
return
;
}
...
...
@@ -310,7 +400,7 @@ public class T02StartActivity extends AppCompatActivity {
t03CumulativeTimeDataBinding
.
diaParkingHoursTextView
.
setText
(
String
.
valueOf
(
newPeriodHour
));
// 顯示 累加時間 開單時間
SimpleDateFormat
simpleDate
=
new
SimpleDateFormat
(
"HH:mm"
);
SimpleDateFormat
simpleDate
=
new
SimpleDateFormat
(
"HH:mm"
);
t03CumulativeTimeDataBinding
.
diaBillingTimeTextView
.
setText
(
simpleDate
.
format
(
tempCase
.
caseTime
));
t03CumulativeTimeDataBinding
.
diaCumulativeTimeTextView
.
setText
(
simpleDate
.
format
(
tempCase
.
finalTime
));
...
...
@@ -346,13 +436,13 @@ public class T02StartActivity extends AppCompatActivity {
}
private
void
btnInventoryOnClicked
(){
private
void
btnInventoryOnClicked
()
{
Intent
intent
=
new
Intent
();
intent
.
setClass
(
this
,
T03ListFilesActivity
.
class
);
inventoryActivityResultLauncher
.
launch
(
intent
);
}
private
void
btnMonthlyReportOnClicked
(){
private
void
btnMonthlyReportOnClicked
()
{
Intent
intent
=
new
Intent
();
intent
.
setClass
(
this
,
T03TotalActivity
.
class
);
Bundle
bundle
=
new
Bundle
();
...
...
@@ -362,4 +452,127 @@ public class T02StartActivity extends AppCompatActivity {
intent
.
putExtras
(
bundle
);
startActivity
(
intent
);
}
/**
* 初始化藍芽連線
*
* @return 初始化藍芽是否成功
*/
private
boolean
initBlueTooth
()
{
deviceNameArrayAdapter
=
blueToothViewModel
.
getDeviceNameArrayAdapter
();
if
(
blueToothViewModel
.
getBluetoothAdapter
()
==
null
)
{
Toast
.
makeText
(
getApplication
(),
"Bluetooth is not available"
,
Toast
.
LENGTH_LONG
).
show
();
return
false
;
}
if
(!
blueToothViewModel
.
getBluetoothAdapter
().
isEnabled
())
{
// TODO: 2022/8/3 Android 12 以上的版本 需額外請求藍芽權限
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
requestMultiplePermissions
.
launch
(
bluetoothPermissions
);
}
else
{
Intent
enableIntent
=
new
Intent
(
BluetoothAdapter
.
ACTION_REQUEST_ENABLE
);
requestBluetooth
.
launch
(
enableIntent
);
}
}
selectPrinterDialog
();
return
true
;
}
private
void
selectPrinterDialog
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
this
,
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
AlertDialogT02DeviceListBinding
t02DeviceListDataBinding
=
AlertDialogT02DeviceListBinding
.
inflate
(
LayoutInflater
.
from
(
this
));
AlertDialog
.
Builder
alertDialog
=
new
AlertDialog
.
Builder
(
this
);
final
AlertDialog
tempDialog
=
alertDialog
.
create
();
t02DeviceListDataBinding
.
lvPairedDevices
.
setAdapter
(
deviceNameArrayAdapter
);
t02DeviceListDataBinding
.
lvPairedDevices
.
setOnItemClickListener
((
adapterView
,
view
,
i
,
l
)
->
{
// 藍芽裝置選取事件
blueToothViewModel
.
cancelDiscovery
();
String
info
=
((
TextView
)
view
).
getText
().
toString
();
String
address
=
info
.
substring
(
info
.
length
()
-
17
);
// 進行藍芽連線
blueToothViewModel
.
connect
(
address
);
tempDialog
.
dismiss
();
});
// 搜尋功能綁定
t02DeviceListDataBinding
.
btnScan
.
setOnClickListener
(
view
->
{
if
(
deviceNameArrayAdapter
.
getPosition
(
getString
(
R
.
string
.
none_paired
))
>=
0
)
{
deviceNameArrayAdapter
.
remove
(
getString
(
R
.
string
.
none_paired
));
}
if
(!
blueToothViewModel
.
getBluetoothAdapter
().
isDiscovering
())
{
t02DeviceListDataBinding
.
btnScan
.
setText
(
R
.
string
.
button_stop_scan
);
t02DeviceListDataBinding
.
titlePairedDevices
.
setText
(
getString
(
R
.
string
.
title_other_devices
));
// 開始搜尋
blueToothViewModel
.
startDiscovery
();
}
else
{
t02DeviceListDataBinding
.
btnScan
.
setText
(
R
.
string
.
button_scan
);
// 停止搜尋
blueToothViewModel
.
cancelDiscovery
();
}
});
// dialog 關閉
t02DeviceListDataBinding
.
dialogClose
.
setOnClickListener
(
view
->
{
tempDialog
.
dismiss
();
});
tempDialog
.
setCanceledOnTouchOutside
(
false
);
tempDialog
.
setView
(
t02DeviceListDataBinding
.
getRoot
());
tempDialog
.
show
();
// 對話框大小調整
DisplayMetrics
metrics
=
new
DisplayMetrics
();
getWindowManager
().
getDefaultDisplay
().
getMetrics
(
metrics
);
WindowManager
.
LayoutParams
p
=
tempDialog
.
getWindow
().
getAttributes
();
//获取对话框当前的参数值
p
.
height
=
(
int
)
(
metrics
.
heightPixels
*
0.7
);
//高度設置为螢幕的0.7
p
.
width
=
(
int
)
(
metrics
.
widthPixels
*
0.9
);
//寬度設置為螢幕的0.9
tempDialog
.
getWindow
().
setAttributes
(
p
);
}
private
void
btnPrintOnClicked
(){
Case
tempCase
=
t02StartViewModel
.
getCurrentCase
().
getValue
();
if
(
tempCase
.
caseStatus
!=
CaseStatus
.
LIST
){
Toast
.
makeText
(
this
,
"請先確認資料後再列印"
,
Toast
.
LENGTH_SHORT
).
show
();
return
;
}
if
(
blueToothViewModel
.
getBlueToothStatus
().
getValue
()
!=
BlueToothViewModel
.
BlueToothStatus
.
CONNECT_SUCCESS
){
Toast
.
makeText
(
this
,
"請先連結藍芽印表機裝置"
,
Toast
.
LENGTH_SHORT
).
show
();
return
;
}
blueToothViewModel
.
printCase
(
tempCase
);
}
private
void
initAlertDialogProgress
(){
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
this
);
builder
.
setCancelable
(
false
);
// if you want user to wait for some process to finish,
alertDialogProgressBarBinding
=
AlertDialogProgressBarBinding
.
inflate
(
LayoutInflater
.
from
(
this
));
builder
.
setView
(
alertDialogProgressBarBinding
.
getRoot
());
alertDialogProgress
=
builder
.
create
();
}
private
void
setAlertDialogProgressMessage
(
String
message
){
alertDialogProgressBarBinding
.
tvProgressBarMsg
.
setText
(
message
);
}
}
\ No newline at end of file
app/src/main/java/ecom/android/newparkapp/viewModel/BlueToothViewModel.java
0 → 100644
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
viewModel
;
import
static
android
.
Manifest
.
permission
.
BLUETOOTH_CONNECT
;
import
static
android
.
Manifest
.
permission
.
BLUETOOTH_SCAN
;
import
android.app.Application
;
import
android.bluetooth.BluetoothAdapter
;
import
android.bluetooth.BluetoothDevice
;
import
android.bluetooth.BluetoothSocket
;
import
android.content.BroadcastReceiver
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.IntentFilter
;
import
android.content.pm.PackageManager
;
import
android.os.Build
;
import
android.widget.ArrayAdapter
;
import
android.widget.ListAdapter
;
import
android.widget.ListView
;
import
android.widget.Toast
;
import
androidx.annotation.NonNull
;
import
androidx.core.app.ActivityCompat
;
import
androidx.lifecycle.AndroidViewModel
;
import
androidx.lifecycle.LiveData
;
import
androidx.lifecycle.MutableLiveData
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.util.Set
;
import
java.util.UUID
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
ecom.android.newparkapp.R
;
import
ecom.android.newparkapp.entity.Case
;
import
ecom.android.newparkapp.printer.IBluetoothPrinter
;
import
ecom.android.newparkapp.view.T02StartActivity
;
public
class
BlueToothViewModel
extends
AndroidViewModel
{
private
ExecutorService
executorService
;
private
BluetoothAdapter
bluetoothAdapter
;
private
BluetoothSocket
bluetoothSocket
;
private
BTDeviceReceiver
btDeviceReceiver
;
private
OutputStream
outputStream
;
private
ArrayAdapter
<
String
>
deviceNameArrayAdapter
;
private
String
[]
bluetoothPermissions
=
new
String
[]{};
private
MutableLiveData
<
BluetoothDevice
>
bluetoothDevice
=
new
MutableLiveData
<>();
private
MutableLiveData
<
BlueToothStatus
>
blueToothStatusMutableLiveData
=
new
MutableLiveData
<>();
public
BlueToothViewModel
(
@NonNull
Application
application
)
{
super
(
application
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
application
,
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
executorService
=
Executors
.
newFixedThreadPool
(
application
.
getResources
().
getInteger
(
R
.
integer
.
number_db_thread_pool
));
blueToothStatusMutableLiveData
.
setValue
(
BlueToothStatus
.
INIT
);
bluetoothAdapter
=
BluetoothAdapter
.
getDefaultAdapter
();
deviceNameArrayAdapter
=
new
ArrayAdapter
<
String
>(
application
,
R
.
layout
.
list_view_device_name_item
);
IntentFilter
filter
=
new
IntentFilter
();
filter
.
addAction
(
BluetoothDevice
.
ACTION_FOUND
);
filter
.
addAction
(
BluetoothAdapter
.
ACTION_DISCOVERY_FINISHED
);
btDeviceReceiver
=
new
BTDeviceReceiver
();
application
.
registerReceiver
(
btDeviceReceiver
,
filter
);
//取得已綁定過的裝置
Set
<
BluetoothDevice
>
pairedDevices
=
bluetoothAdapter
.
getBondedDevices
();
if
(
pairedDevices
.
size
()
>
0
)
{
for
(
BluetoothDevice
device
:
pairedDevices
)
{
deviceNameArrayAdapter
.
add
(
device
.
getName
()
+
"\n"
+
device
.
getAddress
());
}
}
else
{
deviceNameArrayAdapter
.
add
(
application
.
getString
(
R
.
string
.
none_paired
));
}
}
public
LiveData
<
BlueToothStatus
>
getBlueToothStatus
(){
return
blueToothStatusMutableLiveData
;
}
public
LiveData
<
BluetoothDevice
>
getBluetoothDevice
(){
return
bluetoothDevice
;
}
public
ArrayAdapter
<
String
>
getDeviceNameArrayAdapter
(){
return
deviceNameArrayAdapter
;
}
public
BluetoothAdapter
getBluetoothAdapter
(){
return
bluetoothAdapter
;
}
/**
* 藍芽連線
* @param device 藍芽裝置
*/
private
void
connect
(
BluetoothDevice
device
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
getApplication
(),
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
if
(
device
==
null
){
blueToothStatusMutableLiveData
.
setValue
(
BlueToothStatus
.
CONNECT_FAILED
);
return
;
}
bluetoothDevice
.
setValue
(
device
);
executorService
.
execute
(()
->
{
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
CONNECTING
);
try
{
BluetoothDevice
thisBluetoothDevice
=
bluetoothDevice
.
getValue
();
if
(
thisBluetoothDevice
==
null
){
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
CONNECT_FAILED
);
return
;
}
bluetoothSocket
=
thisBluetoothDevice
.
createRfcommSocketToServiceRecord
(
UUID
.
fromString
(
"00001101-0000-1000-8000-00805F9B34FB"
));
//SerialPortServiceClass_UUID
bluetoothSocket
.
connect
();
outputStream
=
bluetoothSocket
.
getOutputStream
();
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
CONNECT_SUCCESS
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
try
{
if
(
bluetoothSocket
!=
null
)
{
bluetoothSocket
.
close
();
}
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
CONNECT_FAILED
);
}
catch
(
IOException
ex
)
{
ex
.
printStackTrace
();
}
}
});
}
public
void
connect
(
String
address
){
BluetoothDevice
bluetoothDeviceFromAddress
=
bluetoothAdapter
.
getRemoteDevice
(
address
);
connect
(
bluetoothDeviceFromAddress
);
}
/**
* 中斷當前藍芽連線
*/
public
void
disconnect
(){
}
/**
* 開始藍芽搜尋
*/
public
void
startDiscovery
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
getApplication
(),
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
if
(
bluetoothAdapter
!=
null
&&
!
bluetoothAdapter
.
isDiscovering
()){
bluetoothAdapter
.
startDiscovery
();
}
}
/**
* 停止藍芽搜尋
*/
public
void
cancelDiscovery
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
getApplication
(),
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
if
(
bluetoothAdapter
!=
null
&&
bluetoothAdapter
.
isDiscovering
()){
bluetoothAdapter
.
cancelDiscovery
();
}
}
public
void
printCase
(
Case
tempCase
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
getApplication
(),
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
blueToothStatusMutableLiveData
.
setValue
(
BlueToothStatus
.
PRINTING
);
executorService
.
execute
(()->{
/*-----取得CasePrinter-----*/
IBluetoothPrinter
printer
=
tempCase
.
getCasePrinter
(
bluetoothDevice
.
getValue
().
getName
());
try
{
printer
.
print
(
bluetoothSocket
,
tempCase
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
PRINT_FAILED
);
return
;
}
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
PRINT_COMPLETE
);
try
{
Thread
.
sleep
(
1000
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
blueToothStatusMutableLiveData
.
postValue
(
BlueToothStatus
.
CONNECT_SUCCESS
);
});
}
/**
* 監聽藍芽裝置廣播
*/
private
class
BTDeviceReceiver
extends
BroadcastReceiver
{
@Override
public
void
onReceive
(
Context
context
,
@NonNull
Intent
intent
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
// Android 12 額外檢查藍芽權限
for
(
String
permission
:
bluetoothPermissions
){
if
(
ActivityCompat
.
checkSelfPermission
(
getApplication
(),
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
){
return
;
}
}
}
String
action
=
intent
.
getAction
();
if
(
BluetoothDevice
.
ACTION_FOUND
.
equals
(
action
))
{
//如果藍芽掃瞄有裝置
BluetoothDevice
device
=
intent
.
getParcelableExtra
(
BluetoothDevice
.
EXTRA_DEVICE
);
if
(
device
==
null
)
{
return
;
}
if
(
device
.
getBondState
()
!=
BluetoothDevice
.
BOND_BONDED
&&
deviceNameArrayAdapter
.
getPosition
(
device
.
getName
()
+
"\n"
+
device
.
getAddress
())
<
0
)
{
deviceNameArrayAdapter
.
add
(
device
.
getName
()
+
"\n"
+
device
.
getAddress
());
}
}
else
if
(
BluetoothAdapter
.
ACTION_DISCOVERY_FINISHED
.
equals
(
action
))
{
if
(
deviceNameArrayAdapter
.
getCount
()
==
0
)
{
String
noDevices
=
getApplication
().
getString
(
R
.
string
.
none_found
);
deviceNameArrayAdapter
.
add
(
noDevices
);
}
}
}
}
public
enum
BlueToothStatus
{
INIT
,
CONNECTING
,
CONNECT_SUCCESS
,
CONNECT_FAILED
,
PRINTING
,
PRINT_COMPLETE
,
PRINT_FAILED
}
}
app/src/main/java/ecom/android/newparkapp/viewModel/FusedGpsViewModel.java
0 → 100644
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
viewModel
;
import
android.Manifest
;
import
android.app.Application
;
import
android.content.pm.PackageManager
;
import
android.location.Location
;
import
androidx.annotation.NonNull
;
import
androidx.core.app.ActivityCompat
;
import
androidx.lifecycle.AndroidViewModel
;
import
androidx.lifecycle.LiveData
;
import
androidx.lifecycle.MutableLiveData
;
import
com.google.android.gms.location.FusedLocationProviderClient
;
import
com.google.android.gms.location.LocationCallback
;
import
com.google.android.gms.location.LocationRequest
;
import
com.google.android.gms.location.LocationResult
;
import
com.google.android.gms.location.LocationServices
;
import
com.google.android.gms.location.LocationSettingsRequest
;
import
com.google.android.gms.location.Priority
;
import
com.google.android.gms.location.SettingsClient
;
import
java.text.DateFormat
;
import
java.util.Date
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
ecom.android.newparkapp.R
;
public
class
FusedGpsViewModel
extends
AndroidViewModel
{
private
long
UPDATE_INTERVAL_IN_MILLISECONDS
=
100
;
private
long
FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS
=
50
;
private
FusedLocationProviderClient
fusedLocationProviderClient
;
private
SettingsClient
settingsClient
;
private
LocationRequest
locationRequest
;
private
LocationSettingsRequest
locationSettingsRequest
;
private
LocationCallback
locationCallback
;
private
Boolean
requestingLocationUpdates
;
private
MutableLiveData
<
Location
>
location
=
new
MutableLiveData
<>();
private
MutableLiveData
<
Date
>
lastUpdateTime
=
new
MutableLiveData
<>();
//最後定位時間
private
ExecutorService
executorService
;
public
FusedGpsViewModel
(
@NonNull
Application
application
)
{
super
(
application
);
fusedLocationProviderClient
=
LocationServices
.
getFusedLocationProviderClient
(
application
);
settingsClient
=
LocationServices
.
getSettingsClient
(
application
);
executorService
=
Executors
.
newFixedThreadPool
(
application
.
getResources
().
getInteger
(
R
.
integer
.
number_db_thread_pool
));
createLocationCallback
();
createLocationRequest
();
buildLocationSettingsRequest
();
if
(
ActivityCompat
.
checkSelfPermission
(
application
,
Manifest
.
permission
.
ACCESS_FINE_LOCATION
)
!=
PackageManager
.
PERMISSION_GRANTED
&&
ActivityCompat
.
checkSelfPermission
(
application
,
Manifest
.
permission
.
ACCESS_COARSE_LOCATION
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
;
}
fusedLocationProviderClient
.
requestLocationUpdates
(
locationRequest
,
executorService
,
locationCallback
);
}
public
LiveData
<
Location
>
getLocation
(){
return
location
;
}
public
LiveData
<
Date
>
getLastUpdateTime
(){
return
lastUpdateTime
;
}
private
void
createLocationCallback
()
{
locationCallback
=
new
LocationCallback
()
{
@Override
public
void
onLocationResult
(
@NonNull
LocationResult
locationResult
)
{
super
.
onLocationResult
(
locationResult
);
location
.
postValue
(
locationResult
.
getLastLocation
());
lastUpdateTime
.
postValue
(
new
Date
());
}
};
}
private
void
createLocationRequest
()
{
locationRequest
=
LocationRequest
.
create
()
.
setInterval
(
UPDATE_INTERVAL_IN_MILLISECONDS
)
.
setFastestInterval
(
FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS
)
.
setPriority
(
Priority
.
PRIORITY_HIGH_ACCURACY
)
.
setMaxWaitTime
(
0
);
}
private
void
buildLocationSettingsRequest
(){
LocationSettingsRequest
.
Builder
builder
=
new
LocationSettingsRequest
.
Builder
();
builder
.
addLocationRequest
(
locationRequest
);
locationSettingsRequest
=
builder
.
build
();
}
}
app/src/main/java/ecom/android/newparkapp/viewModel/T01ImportDbViewModel.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
viewModel
;
import
static
ecom
.
android
.
newparkapp
.
converter
.
SpaceTypeConverter
.
toSpaceType
;
import
android.Manifest
;
import
android.app.Application
;
import
android.content.pm.PackageManager
;
...
...
@@ -19,9 +21,9 @@ import ecom.android.newparkapp.Common;
import
ecom.android.newparkapp.R
;
import
ecom.android.newparkapp.entity.Road
;
import
ecom.android.newparkapp.entity.Space
;
import
ecom.android.newparkapp.entity.Space.SpaceType
;
import
ecom.android.newparkapp.entity.SpaceRate
;
import
ecom.android.newparkapp.entity.SpaceStatus
;
import
ecom.android.newparkapp.entity.SpaceType
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.entity.UserPermission
;
import
ecom.android.newparkapp.entity.VehicleBrand
;
...
...
@@ -218,24 +220,6 @@ public class T01ImportDbViewModel extends AndroidViewModel {
}
});
break
;
case
SpaceType:
infoRepository
.
executorService
.
execute
(()->{
infoRepository
.
spaceTypeDao
.
deleteAll
();
for
(
int
i
=
0
;
i
<
lines
.
length
;
i
++){
String
[]
columnString
=
lines
[
i
].
trim
().
split
(
"[ ]"
);
int
newId
;
if
(
columnString
.
length
!=
2
){
break
;
}
try
{
newId
=
Integer
.
parseInt
(
columnString
[
0
]);
}
catch
(
NumberFormatException
exception
){
break
;
}
String
newName
=
columnString
[
1
];
SpaceType
newSpaceType
=
new
SpaceType
(
newId
,
newName
);
infoRepository
.
spaceTypeDao
.
insertAll
(
newSpaceType
);
}
});
break
;
case
Road:
infoRepository
.
executorService
.
execute
(()->{
infoRepository
.
roadDao
.
deleteAll
();
...
...
@@ -278,9 +262,7 @@ public class T01ImportDbViewModel extends AndroidViewModel {
if
(
spaceRateList
.
size
()
==
0
){
break
;}
SpaceRate
newSpaceRate
=
spaceRateList
.
get
(
0
);
List
<
SpaceType
>
spaceTypeList
=
infoRepository
.
spaceTypeDao
.
loadAllByIds
(
new
int
[]{
spaceTypeId
});
if
(
spaceTypeList
.
size
()
==
0
){
break
;}
SpaceType
newSpaceType
=
spaceTypeList
.
get
(
0
);
SpaceType
newSpaceType
=
toSpaceType
(
spaceTypeId
);
List
<
SpaceStatus
>
spaceStatusList
=
infoRepository
.
spaceStatusDao
.
loadAllByIds
(
new
int
[]{
spaceStatusId
});
if
(
spaceStatusList
.
size
()
==
0
){
break
;}
...
...
@@ -299,6 +281,6 @@ public class T01ImportDbViewModel extends AndroidViewModel {
}
public
enum
DBTableName
{
UserPermission
,
User
,
VehicleBrand
,
VehicleColor
,
VehicleType
,
SpaceRate
,
SpaceStatus
,
SpaceType
,
Road
,
Space
UserPermission
,
User
,
VehicleBrand
,
VehicleColor
,
VehicleType
,
SpaceRate
,
SpaceStatus
,
Road
,
Space
}
}
\ No newline at end of file
app/src/main/java/ecom/android/newparkapp/viewModel/T01SettingViewModel.java
View file @
d4472e97
...
...
@@ -41,14 +41,17 @@ public class T01SettingViewModel extends AndroidViewModel {
super
(
application
);
tempPREF
=
new
PreferenceSettings
();
restorePrefs
(
application
,
tempPREF
);
PREF
.
setValue
(
tempPREF
);
restorePrefs
();
infoRepository
=
new
InfoRepository
(
application
);
Users
=
infoRepository
.
userDao
.
getAllLiveData
();
}
public
void
restorePrefs
(){
restorePrefs
(
getApplication
(),
tempPREF
);
PREF
.
setValue
(
tempPREF
);
}
private
void
restorePrefs
(
@NonNull
Application
application
,
PreferenceSettings
PREF
)
{
settings
=
application
.
getSharedPreferences
(
Common
.
PREF
,
MODE_PRIVATE
);
PREF
.
pref_user
=
settings
.
getString
(
Common
.
PREF_USER
,
"999 系統測試"
);
...
...
app/src/main/java/ecom/android/newparkapp/viewModel/T02StartViewModel.java
View file @
d4472e97
package
ecom
.
android
.
newparkapp
.
viewModel
;
import
android.app.Application
;
import
android.location.Location
;
import
android.media.MediaScannerConnection
;
import
android.os.Environment
;
import
android.widget.Toast
;
...
...
@@ -452,4 +453,10 @@ public class T02StartViewModel extends AndroidViewModel {
// 寫入DB
saveCurrentCase
();
}
public
void
setLocation
(
Location
location
)
{
Case
tempCase
=
currentCase
.
getValue
();
tempCase
.
location
=
location
;
currentCase
.
setValue
(
tempCase
);
}
}
app/src/main/java/ecom/android/newparkapp/viewModel/UserViewModel.java
deleted
100644 → 0
View file @
24da35c7
package
ecom
.
android
.
newparkapp
.
viewModel
;
import
android.app.Application
;
import
androidx.annotation.NonNull
;
import
androidx.lifecycle.AndroidViewModel
;
import
androidx.lifecycle.LiveData
;
import
androidx.lifecycle.MediatorLiveData
;
import
androidx.lifecycle.MutableLiveData
;
import
androidx.lifecycle.Transformations
;
import
java.util.List
;
import
ecom.android.newparkapp.entity.User
;
import
ecom.android.newparkapp.repository.InfoRepository
;
public
class
UserViewModel
extends
AndroidViewModel
{
private
InfoRepository
infoRepository
;
private
LiveData
<
List
<
User
>>
allUsers
;
private
LiveData
<
User
>
userLiveData
;
private
MutableLiveData
<
User
>
currentUser
=
new
MutableLiveData
<>();
public
UserViewModel
(
@NonNull
Application
application
)
{
super
(
application
);
infoRepository
=
new
InfoRepository
(
application
);
userLiveData
=
infoRepository
.
userDao
.
getLiveDataById
(
1
);
allUsers
=
infoRepository
.
userDao
.
getAllLiveData
();
}
public
LiveData
<
List
<
User
>>
getAllUsers
()
{
return
allUsers
;
}
public
LiveData
<
User
>
getCurrentUser
()
{
return
currentUser
;}
public
void
setCurrentUser
(){
User
cUser
=
infoRepository
.
userDao
.
findByName
(
"Root"
);
currentUser
.
setValue
(
cUser
);
}
public
void
setCurrentUser
(
User
cUser
){
currentUser
.
setValue
(
cUser
);
}
public
LiveData
<
User
>
getUserLiveData
(){
return
userLiveData
;}
}
app/src/main/res/layout/activity_main.xml
View file @
d4472e97
...
...
@@ -2,11 +2,6 @@
<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"
>
<data>
<variable
name=
"userViewModel"
type=
"ecom.android.newparkapp.viewModel.UserViewModel"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width=
"match_parent"
...
...
@@ -86,7 +81,7 @@
android:id=
"@+id/tv_current_usr"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:text=
"
當前使用者
"
android:text=
"
@string/current_user
"
android:textAlignment=
"center"
android:textSize=
"30sp"
app:layout_constraintBottom_toBottomOf=
"parent"
...
...
app/src/main/res/layout/activity_t02_start.xml
View file @
d4472e97
...
...
@@ -8,10 +8,13 @@
<import
type=
"ecom.android.newparkapp.entity.Road"
/>
<import
type=
"ecom.android.newparkapp.entity.SpaceStatus"
/>
<import
type=
"ecom.android.newparkapp.entity.SpaceRate"
/>
<import
type=
"ecom.android.newparkapp.entity.SpaceType"
/>
<variable
name=
"t02StartViewModel"
type=
"ecom.android.newparkapp.viewModel.T02StartViewModel"
/>
<variable
name=
"blueToothViewModel"
type=
"ecom.android.newparkapp.viewModel.BlueToothViewModel"
/>
</data>
<androidx.core.widget.NestedScrollView
android:id=
"@+id/t02_start_border"
...
...
@@ -50,7 +53,7 @@ tools:layout_editor_absoluteY="25dp">
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:text=
"
YH-TB250
"
android:text=
"
@{blueToothViewModel.bluetoothDevice.name}
"
android:textAlignment=
"center"
android:textSize=
"20sp"
/>
...
...
@@ -59,10 +62,10 @@ tools:layout_editor_absoluteY="25dp">
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:text=
"連線正常"
android:textAlignment=
"center"
android:textColor=
"#8BC34A"
android:textSize=
"20sp"
/>
android:textSize=
"20sp"
app:blueToothStatus2String=
"@{blueToothViewModel.blueToothStatus}"
/>
<LinearLayout
android:layout_width=
"wrap_content"
...
...
@@ -582,7 +585,7 @@ tools:layout_editor_absoluteY="25dp">
android:layout_height=
"match_parent"
android:textSize=
"21sp"
android:layout_weight=
"1"
android:text=
"
座標更新時間:
"
/>
android:text=
"
@string/last_location_time_textView
"
/>
</LinearLayout>
<!-- Printer
<Button
...
...
app/src/main/res/layout/alert_dialog_progress_bar.xml
0 → 100644
View file @
d4472e97
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:padding=
"20dp"
>
<ProgressBar
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
/>
<TextView
android:id=
"@+id/tv_progress_bar_msg"
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"4"
android:gravity=
"center"
android:text=
"Please wait! This may take a moment."
/>
</LinearLayout>
</layout>
\ No newline at end of file
app/src/main/res/layout/alert_dialog_t02_device_list.xml
0 → 100644
View file @
d4472e97
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<TextView
android:id=
"@+id/title_paired_devices"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"5dp"
android:background=
"@color/colorPrimaryDark"
android:gravity=
"center"
android:padding=
"5dp"
android:text=
"@string/title_paired_devices"
android:textColor=
"#fff"
android:textSize=
"30sp"
app:layout_constraintBottom_toTopOf=
"@+id/btn_scan"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
<ImageButton
android:id=
"@+id/dialog_close"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"5dp"
android:background=
"@drawable/ic_baseline_cancel_24"
app:layout_constraintBottom_toBottomOf=
"@+id/title_paired_devices"
app:layout_constraintEnd_toEndOf=
"@+id/title_paired_devices"
app:layout_constraintTop_toTopOf=
"@+id/title_paired_devices"
/>
<Button
android:id=
"@+id/btn_scan"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"5dp"
android:layout_marginEnd=
"5dp"
android:text=
"@string/button_scan"
android:textSize=
"18sp"
app:layout_constraintBottom_toTopOf=
"@+id/lv_paired_devices"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/title_paired_devices"
/>
<ListView
android:id=
"@+id/lv_paired_devices"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"5dp"
android:layout_marginEnd=
"5dp"
android:stackFromBottom=
"false"
app:layout_constraintBottom_toTopOf=
"@+id/title_paired_devices"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/btn_scan"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
\ No newline at end of file
app/src/main/res/layout/list_view_device_name_item.xml
0 → 100644
View file @
d4472e97
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:padding=
"5dp"
android:textSize=
"30sp"
/>
app/src/main/res/values/strings.xml
View file @
d4472e97
...
...
@@ -6,7 +6,7 @@
<!-- 1050830 阿達:改時間 by JiaRong-->
<!--<string name="morning_button_text">早班 08:00~16:00</string>-->
<!--<string name="afternoon_button_text">晚班 14:00~22:00</string>-->
<string
name=
"ecom_title"
>
202
1
©版權所有\n昱通資訊事業股份有限公司
</string>
<string
name=
"ecom_title"
>
202
2
©版權所有\n昱通資訊事業股份有限公司
</string>
<string
name=
"morning_button_text"
>
早班 08:00~16:30
</string>
<string
name=
"afternoon_button_text"
>
晚班 13:30~22:00
</string>
<string
name=
"label_setting"
>
設定
</string>
...
...
@@ -78,4 +78,6 @@
<string
name=
"hello_first_fragment"
>
Hello first fragment
</string>
<string
name=
"hello_second_fragment"
>
Hello second fragment. Arg: %1$s
</string>
<string
name=
"current_user"
>
當前使用者: %s
</string>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment