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

1. 刪除垃圾

2. 新增藍芽連線功能
3. 新增藍芽列印功能
4. 調整資料庫欄位
parent 24da35c7
......@@ -12,6 +12,6 @@
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-08-02T03:29:02.338878300Z" />
<timeTargetWasSelectedWithDropDown value="2022-08-03T07:12:30.738727600Z" />
</component>
</project>
\ No newline at end of file
......@@ -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" />
......
......@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "ecom.android.newparkapp"
minSdk 27
targetSdk 32
targetSdk 30
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'
......
......@@ -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 {
......
......@@ -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)
......
......@@ -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" />
......
This diff is collapsed.
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
package ecom.android.newparkapp.entity;
package ecom.android.newparkapp.converter;
import android.location.Location;
......
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();
}
}
package ecom.android.newparkapp.entity;
package ecom.android.newparkapp.converter;
import androidx.room.TypeConverter;
......
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();
}
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;
}
}
......@@ -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();
......
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
......@@ -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
}
}
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];
}
};
}
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;
}
}
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;
}
......@@ -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();
......
......@@ -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);
startActivity(intent);
settingActivityResultLauncher.launch(intent);
}
}
\ No newline at end of file
......@@ -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
......
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();
}
}
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
......@@ -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 系統測試");
......
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);
}
}
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;}
}
......@@ -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"
......
......@@ -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
......
<?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
<?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
<?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" />
......@@ -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">2021©版權所有\n昱通資訊事業股份有限公司</string>
<string name="ecom_title">2022©版權所有\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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment