Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
supplier
Overview
Overview
Details
Activity
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
王宇航
supplier
Commits
7e27ec13
Commit
7e27ec13
authored
Feb 26, 2021
by
宁斌
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1、打印流程可視化調整 2、prj長連接替換輪詢
parent
d315d8ac
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1284 additions
and
1362 deletions
+1284
-1362
component-coldchain/src/main/java/com/gingersoft/coldchain_module/mvp/ui/activity/ColdChainMainActivity.java
+4
-4
component-delivery-pick/src/main/debug/AndroidManifest.xml
+1
-1
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/DeliveryPickComponent.java
+2
-2
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/model/viewModel/PageViewModel.kt
+7
-7
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/ui/activity/DeliveryOrderMainActivity.kt
+4
-4
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/ui/activity/LogActivity.java
+3
-3
component-login/build.gradle
+1
-1
component-main/src/main/java/com/gingersoft/gsa/cloud/main/mvp/ui/activity/NewMainActivity.java
+27
-13
component-print/src/main/debug/AndroidManifest.xml
+5
-2
component-print/src/main/java/com/joe/print/PrintComponent.java
+6
-1
component-print/src/main/java/com/joe/print/mvp/print/EpsonPrint.java
+3
-4
component-print/src/main/java/com/joe/print/mvp/print/PrinterManger/PrinterManager.java
+3
-0
component-print/src/main/java/com/joe/print/mvp/print/PrinterManger/PrjPtinterManager.java
+853
-0
component-print/src/main/java/com/joe/print/mvp/print/PrinterRoot.java
+15
-8
component-print/src/main/java/com/joe/print/mvp/print/service/PrjService.java
+8
-7
component-print/src/main/java/com/joe/print/mvp/ui/activity/PrintActivity.java
+113
-32
component-print/src/main/java/com/joe/print/mvp/ui/view/PrinterLoadingDialog.java
+103
-31
component-print/src/main/res/layout/print_dialog_loading.xml
+12
-16
component-print/src/main/res/raw/printer_loading.json
+0
-0
component-print/src/main/res/raw/printer_loading2.json
+0
-1209
library-common/src/main/AndroidManifest.xml
+4
-1
library-common/src/main/java/com/gingersoft/gsa/cloud/app/GsaCloudApplication.java
+10
-1
library-common/src/main/java/com/gingersoft/gsa/cloud/common/config/LoganConfig.java
+1
-1
library-common/src/main/java/com/gingersoft/gsa/cloud/common/printer/plugins/ExternalPrinterConnection.java
+1
-1
library-common/src/main/java/com/gingersoft/gsa/cloud/common/service/DataNotificationService.kt
+97
-12
library-print/src/main/java/com/gingersoft/gsa/cloud/print/PrintSocketHolder.java
+1
-1
No files found.
component-coldchain/src/main/java/com/gingersoft/coldchain_module/mvp/ui/activity/ColdChainMainActivity.java
View file @
7e27ec13
...
@@ -40,7 +40,7 @@ import com.gingersoft.gsa.cloud.common.constans.DeliveryPickConstans;
...
@@ -40,7 +40,7 @@ import com.gingersoft.gsa.cloud.common.constans.DeliveryPickConstans;
import
com.gingersoft.gsa.cloud.common.constans.ExpandConstant
;
import
com.gingersoft.gsa.cloud.common.constans.ExpandConstant
;
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
;
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
;
import
com.gingersoft.gsa.cloud.common.core.restaurant.utils.RestaurantExpandInfoUtils
;
import
com.gingersoft.gsa.cloud.common.core.restaurant.utils.RestaurantExpandInfoUtils
;
import
com.gingersoft.gsa.cloud.common.service.
GetInfoUpdate
Service
;
import
com.gingersoft.gsa.cloud.common.service.
DataNotification
Service
;
import
com.gingersoft.gsa.cloud.common.utils.other.TextUtil
;
import
com.gingersoft.gsa.cloud.common.utils.other.TextUtil
;
import
com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils
;
import
com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils
;
import
com.gingersoft.gsa.cloud.ui.utils.AppDialog
;
import
com.gingersoft.gsa.cloud.ui.utils.AppDialog
;
...
@@ -220,7 +220,7 @@ public class ColdChainMainActivity extends BaseFragmentActivity<ColdChainMainPre
...
@@ -220,7 +220,7 @@ public class ColdChainMainActivity extends BaseFragmentActivity<ColdChainMainPre
private
void
initService
()
{
private
void
initService
()
{
//開啟websocket
//開啟websocket
Intent
intent
=
new
Intent
(
getApplicationContext
(),
GetInfoUpdate
Service
.
class
);
Intent
intent
=
new
Intent
(
getApplicationContext
(),
DataNotification
Service
.
class
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
startForegroundService
(
intent
);
startForegroundService
(
intent
);
}
else
{
}
else
{
...
@@ -235,13 +235,13 @@ public class ColdChainMainActivity extends BaseFragmentActivity<ColdChainMainPre
...
@@ -235,13 +235,13 @@ public class ColdChainMainActivity extends BaseFragmentActivity<ColdChainMainPre
registerReceiver
(
clearHeartBroadcastReceiver
,
intentFilter
);
registerReceiver
(
clearHeartBroadcastReceiver
,
intentFilter
);
}
}
private
GetInfoUpdate
Service
.
MyBind
bind
=
null
;
private
DataNotification
Service
.
MyBind
bind
=
null
;
private
ServiceConnection
serviceConnection
=
new
ServiceConnection
()
{
private
ServiceConnection
serviceConnection
=
new
ServiceConnection
()
{
@Override
@Override
public
void
onServiceConnected
(
ComponentName
name
,
IBinder
service
)
{
public
void
onServiceConnected
(
ComponentName
name
,
IBinder
service
)
{
bind
=
(
GetInfoUpdate
Service
.
MyBind
)
service
;
bind
=
(
DataNotification
Service
.
MyBind
)
service
;
if
(
bind
!=
null
)
{
if
(
bind
!=
null
)
{
bind
.
setOnPostCallBack
(
type
->
{
bind
.
setOnPostCallBack
(
type
->
{
// -1斷開連接,\n-2:消息傳輸錯誤,\n0:連接消息,\n1:登錄通知,\n2:登出通知,\n3:外賣送單通知,\n4:自取送單通知,\n5:歷史訂單通知,\n6:修改訂單狀態通知,\n7:支付成功通知"
// -1斷開連接,\n-2:消息傳輸錯誤,\n0:連接消息,\n1:登錄通知,\n2:登出通知,\n3:外賣送單通知,\n4:自取送單通知,\n5:歷史訂單通知,\n6:修改訂單狀態通知,\n7:支付成功通知"
...
...
component-delivery-pick/src/main/debug/AndroidManifest.xml
View file @
7e27ec13
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
</intent-filter>
</intent-filter>
</activity>
</activity>
<service
android:name=
"com.gingersoft.gsa.cloud.common.service.
GetInfoUpdate
Service"
/>
<service
android:name=
"com.gingersoft.gsa.cloud.common.service.
DataNotification
Service"
/>
<meta-data
<meta-data
android:name=
"com.gingersoft.gsa.cloud.common.config.globalconfig.GlobalConfiguration"
android:name=
"com.gingersoft.gsa.cloud.common.config.globalconfig.GlobalConfiguration"
...
...
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/DeliveryPickComponent.java
View file @
7e27ec13
...
@@ -7,7 +7,7 @@ import com.billy.cc.core.component.CCResult;
...
@@ -7,7 +7,7 @@ import com.billy.cc.core.component.CCResult;
import
com.billy.cc.core.component.CCUtil
;
import
com.billy.cc.core.component.CCUtil
;
import
com.billy.cc.core.component.IComponent
;
import
com.billy.cc.core.component.IComponent
;
import
com.gingersoft.gsa.cloud.component.ComponentName
;
import
com.gingersoft.gsa.cloud.component.ComponentName
;
import
com.gingersoft.gsa.cloud.common.service.
GetInfoUpdate
Service
;
import
com.gingersoft.gsa.cloud.common.service.
DataNotification
Service
;
import
com.gingersoft.gsa.delivery_pick_mode.data.network.ServiceCreator
;
import
com.gingersoft.gsa.delivery_pick_mode.data.network.ServiceCreator
;
import
com.gingersoft.gsa.delivery_pick_mode.mvp.ui.activity.PrjQueryActivity
;
import
com.gingersoft.gsa.delivery_pick_mode.mvp.ui.activity.PrjQueryActivity
;
import
com.gingersoft.gsa.delivery_pick_mode.mvp.ui.activity.SendOrderActivity
;
import
com.gingersoft.gsa.delivery_pick_mode.mvp.ui.activity.SendOrderActivity
;
...
@@ -52,7 +52,7 @@ public class DeliveryPickComponent implements IComponent {
...
@@ -52,7 +52,7 @@ public class DeliveryPickComponent implements IComponent {
CC
.
sendCCResult
(
cc
.
getCallId
(),
CCResult
.
success
());
CC
.
sendCCResult
(
cc
.
getCallId
(),
CCResult
.
success
());
break
;
break
;
case
"closeHeart"
:
case
"closeHeart"
:
Intent
intent
=
new
Intent
(
cc
.
getContext
(),
GetInfoUpdate
Service
.
class
);
Intent
intent
=
new
Intent
(
cc
.
getContext
(),
DataNotification
Service
.
class
);
cc
.
getContext
().
stopService
(
intent
);
cc
.
getContext
().
stopService
(
intent
);
break
;
break
;
case
"historyActivity"
:
case
"historyActivity"
:
...
...
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/model/viewModel/PageViewModel.kt
View file @
7e27ec13
...
@@ -22,7 +22,7 @@ import com.gingersoft.gsa.cloud.common.core.delivery.OrderDetails.Companion.veri
...
@@ -22,7 +22,7 @@ import com.gingersoft.gsa.cloud.common.core.delivery.OrderDetails.Companion.veri
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
import
com.gingersoft.gsa.cloud.common.core.user.UserContext
import
com.gingersoft.gsa.cloud.common.core.user.UserContext
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
import
com.gingersoft.gsa.cloud.common.service.
GetInfoUpdate
Service
import
com.gingersoft.gsa.cloud.common.service.
DataNotification
Service
import
com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils
import
com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils
import
com.gingersoft.gsa.cloud.common.utils.okhttpUtils.OkHttp3Utils
import
com.gingersoft.gsa.cloud.common.utils.okhttpUtils.OkHttp3Utils
import
com.gingersoft.gsa.cloud.common.utils.other.TextUtil
import
com.gingersoft.gsa.cloud.common.utils.other.TextUtil
...
@@ -434,8 +434,8 @@ class PageViewModel(private val repository: WeatherRepository) : ViewModel() {
...
@@ -434,8 +434,8 @@ class PageViewModel(private val repository: WeatherRepository) : ViewModel() {
},
{
},
{
listener
.
invoke
(
getMsgBean
(
0
,
""
,
false
))
listener
.
invoke
(
getMsgBean
(
0
,
""
,
false
))
it
.
printStackTrace
()
it
.
printStackTrace
()
GetInfoUpdate
Service
.
loginfo
.
append
(
"錯誤信息111:"
+
it
.
message
+
" LOCALIZEDMESSAGE:"
+
it
.
localizedMessage
+
it
.
cause
)
DataNotification
Service
.
loginfo
.
append
(
"錯誤信息111:"
+
it
.
message
+
" LOCALIZEDMESSAGE:"
+
it
.
localizedMessage
+
it
.
cause
)
GetInfoUpdate
Service
.
loginfo
.
append
(
"\n"
)
DataNotification
Service
.
loginfo
.
append
(
"\n"
)
})
})
}
}
...
@@ -575,12 +575,12 @@ class PageViewModel(private val repository: WeatherRepository) : ViewModel() {
...
@@ -575,12 +575,12 @@ class PageViewModel(private val repository: WeatherRepository) : ViewModel() {
//添加PRJ
//添加PRJ
//單獨包起來,哪怕這接口報錯也不要影響到正常的邏輯
//單獨包起來,哪怕這接口報錯也不要影響到正常的邏輯
repository
.
addPrj
(
dataBean
.
Order_ID
.
toString
(),
restaurantId
.
toString
(),
ids
.
toString
())
repository
.
addPrj
(
dataBean
.
Order_ID
.
toString
(),
restaurantId
.
toString
(),
ids
.
toString
())
GetInfoUpdate
Service
.
loginfo
.
append
(
"添加PRJ:orderId:"
+
dataBean
.
Order_ID
.
toString
()
+
"restaurantId:"
+
restaurantId
+
"orderDetailsIds:"
+
ids
.
toString
())
DataNotification
Service
.
loginfo
.
append
(
"添加PRJ:orderId:"
+
dataBean
.
Order_ID
.
toString
()
+
"restaurantId:"
+
restaurantId
+
"orderDetailsIds:"
+
ids
.
toString
())
GetInfoUpdate
Service
.
loginfo
.
append
(
"\n"
)
DataNotification
Service
.
loginfo
.
append
(
"\n"
)
},
{
},
{
it
.
printStackTrace
()
it
.
printStackTrace
()
GetInfoUpdate
Service
.
loginfo
.
append
(
"錯誤信息222:"
+
it
.
message
+
" LOCALIZEDMESSAGE:"
+
it
.
localizedMessage
+
it
.
cause
)
DataNotification
Service
.
loginfo
.
append
(
"錯誤信息222:"
+
it
.
message
+
" LOCALIZEDMESSAGE:"
+
it
.
localizedMessage
+
it
.
cause
)
GetInfoUpdate
Service
.
loginfo
.
append
(
"\n"
)
DataNotification
Service
.
loginfo
.
append
(
"\n"
)
})
})
}
}
if
(
isPrintBill
)
{
if
(
isPrintBill
)
{
...
...
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/ui/activity/DeliveryOrderMainActivity.kt
View file @
7e27ec13
...
@@ -31,7 +31,7 @@ import com.gingersoft.gsa.cloud.common.constans.ExpandConstant
...
@@ -31,7 +31,7 @@ import com.gingersoft.gsa.cloud.common.constans.ExpandConstant
import
com.gingersoft.gsa.cloud.common.constans.FoodSummaryConstans.TAKEAWAY_TYPE
import
com.gingersoft.gsa.cloud.common.constans.FoodSummaryConstans.TAKEAWAY_TYPE
import
com.gingersoft.gsa.cloud.common.constans.FunctionManagerConstants
import
com.gingersoft.gsa.cloud.common.constans.FunctionManagerConstants
import
com.gingersoft.gsa.cloud.common.function.FunctionManager
import
com.gingersoft.gsa.cloud.common.function.FunctionManager
import
com.gingersoft.gsa.cloud.common.service.
GetInfoUpdate
Service
import
com.gingersoft.gsa.cloud.common.service.
DataNotification
Service
import
com.gingersoft.gsa.cloud.common.service.PostCallBack
import
com.gingersoft.gsa.cloud.common.service.PostCallBack
import
com.gingersoft.gsa.cloud.order.order.BaseOrder
import
com.gingersoft.gsa.cloud.order.order.BaseOrder
import
com.gingersoft.gsa.cloud.ui.utils.AppDialog
import
com.gingersoft.gsa.cloud.ui.utils.AppDialog
...
@@ -395,7 +395,7 @@ class DeliveryOrderMainActivity : BaseActivity<IPresenter>(), View.OnClickListen
...
@@ -395,7 +395,7 @@ class DeliveryOrderMainActivity : BaseActivity<IPresenter>(), View.OnClickListen
private
fun
initWebsocket
()
{
private
fun
initWebsocket
()
{
//開啟websocket
//開啟websocket
val
service
=
Intent
(
applicationContext
,
GetInfoUpdate
Service
::
class
.
java
)
val
service
=
Intent
(
applicationContext
,
DataNotification
Service
::
class
.
java
)
val
notification
:
NotificationManagerCompat
=
NotificationManagerCompat
.
from
(
this
)
val
notification
:
NotificationManagerCompat
=
NotificationManagerCompat
.
from
(
this
)
if
(!
notification
.
areNotificationsEnabled
())
{
if
(!
notification
.
areNotificationsEnabled
())
{
//未開啟通知權限
//未開啟通知權限
...
@@ -446,12 +446,12 @@ class DeliveryOrderMainActivity : BaseActivity<IPresenter>(), View.OnClickListen
...
@@ -446,12 +446,12 @@ class DeliveryOrderMainActivity : BaseActivity<IPresenter>(), View.OnClickListen
unbindService
(
serviceConnection
)
unbindService
(
serviceConnection
)
}
}
var
bind
:
GetInfoUpdate
Service
.
MyBind
?
=
null
var
bind
:
DataNotification
Service
.
MyBind
?
=
null
var
lastRefreshTime
:
Long
=
0
var
lastRefreshTime
:
Long
=
0
private
var
serviceConnection
=
object
:
ServiceConnection
{
private
var
serviceConnection
=
object
:
ServiceConnection
{
override
fun
onServiceConnected
(
name
:
ComponentName
,
service
:
IBinder
)
{
override
fun
onServiceConnected
(
name
:
ComponentName
,
service
:
IBinder
)
{
bind
=
service
as
GetInfoUpdate
Service
.
MyBind
bind
=
service
as
DataNotification
Service
.
MyBind
bind
?.
let
{
it
->
bind
?.
let
{
it
->
it
.
setOnPostCallBack
(
object
:
PostCallBack
{
it
.
setOnPostCallBack
(
object
:
PostCallBack
{
override
fun
callBack
(
type
:
Int
)
{
override
fun
callBack
(
type
:
Int
)
{
...
...
component-delivery-pick/src/main/java/com/gingersoft/gsa/delivery_pick_mode/ui/activity/LogActivity.java
View file @
7e27ec13
...
@@ -5,7 +5,7 @@ import android.widget.TextView;
...
@@ -5,7 +5,7 @@ import android.widget.TextView;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.appcompat.app.AppCompatActivity
;
import
com.gingersoft.gsa.cloud.common.service.
GetInfoUpdate
Service
;
import
com.gingersoft.gsa.cloud.common.service.
DataNotification
Service
;
import
com.gingersoft.gsa.delivery_pick_mode.R
;
import
com.gingersoft.gsa.delivery_pick_mode.R
;
public
class
LogActivity
extends
AppCompatActivity
{
public
class
LogActivity
extends
AppCompatActivity
{
...
@@ -16,13 +16,13 @@ public class LogActivity extends AppCompatActivity {
...
@@ -16,13 +16,13 @@ public class LogActivity extends AppCompatActivity {
setContentView
(
R
.
layout
.
activity_log
);
setContentView
(
R
.
layout
.
activity_log
);
loadInfo
();
loadInfo
();
findViewById
(
R
.
id
.
btn_clear_log
).
setOnClickListener
(
v
->
{
findViewById
(
R
.
id
.
btn_clear_log
).
setOnClickListener
(
v
->
{
GetInfoUpdate
Service
.
loginfo
.
setLength
(
0
);
DataNotification
Service
.
loginfo
.
setLength
(
0
);
loadInfo
();
loadInfo
();
});
});
findViewById
(
R
.
id
.
btn_back
).
setOnClickListener
(
v
->
finish
());
findViewById
(
R
.
id
.
btn_back
).
setOnClickListener
(
v
->
finish
());
}
}
private
void
loadInfo
()
{
private
void
loadInfo
()
{
((
TextView
)
findViewById
(
R
.
id
.
tv_log
)).
setText
(
GetInfoUpdate
Service
.
loginfo
.
toString
());
((
TextView
)
findViewById
(
R
.
id
.
tv_log
)).
setText
(
DataNotification
Service
.
loginfo
.
toString
());
}
}
}
}
component-login/build.gradle
View file @
7e27ec13
...
@@ -126,7 +126,7 @@ dependencies {
...
@@ -126,7 +126,7 @@ dependencies {
addComponent
'component-delivery-pick'
addComponent
'component-delivery-pick'
addComponent
'component-manager'
addComponent
'component-manager'
addComponent
'component-coldchain'
addComponent
'component-coldchain'
addComponent
'component-supply-chain'
//
addComponent 'component-supply-chain'
addComponent
'component-webview'
addComponent
'component-webview'
addComponent
'component-scan'
addComponent
'component-scan'
addComponent
'component-pay'
addComponent
'component-pay'
...
...
component-main/src/main/java/com/gingersoft/gsa/cloud/main/mvp/ui/activity/NewMainActivity.java
View file @
7e27ec13
...
@@ -4,9 +4,12 @@ import android.content.ClipData;
...
@@ -4,9 +4,12 @@ import android.content.ClipData;
import
android.content.ClipboardManager
;
import
android.content.ClipboardManager
;
import
android.content.Context
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.Intent
;
import
android.content.ServiceConnection
;
import
android.graphics.drawable.Drawable
;
import
android.graphics.drawable.Drawable
;
import
android.graphics.drawable.GradientDrawable
;
import
android.graphics.drawable.GradientDrawable
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.os.IBinder
;
import
android.os.Message
;
import
android.os.Message
;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
android.util.SparseArray
;
import
android.util.SparseArray
;
...
@@ -35,6 +38,7 @@ import com.gingersoft.gsa.cloud.common.function.FunctionManager;
...
@@ -35,6 +38,7 @@ import com.gingersoft.gsa.cloud.common.function.FunctionManager;
import
com.gingersoft.gsa.cloud.common.function.jump.ActivityJumpBean
;
import
com.gingersoft.gsa.cloud.common.function.jump.ActivityJumpBean
;
import
com.gingersoft.gsa.cloud.common.function.jump.ActivityJumpStrategy
;
import
com.gingersoft.gsa.cloud.common.function.jump.ActivityJumpStrategy
;
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
;
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
;
import
com.gingersoft.gsa.cloud.common.service.DataNotificationService
;
import
com.gingersoft.gsa.cloud.common.utils.AppDevices
;
import
com.gingersoft.gsa.cloud.common.utils.AppDevices
;
import
com.gingersoft.gsa.cloud.common.utils.JsonUtils
;
import
com.gingersoft.gsa.cloud.common.utils.JsonUtils
;
import
com.gingersoft.gsa.cloud.common.utils.StytemUtils
;
import
com.gingersoft.gsa.cloud.common.utils.StytemUtils
;
...
@@ -196,27 +200,15 @@ public class NewMainActivity extends BaseFragmentActivity<NewMainPresenter> impl
...
@@ -196,27 +200,15 @@ public class NewMainActivity extends BaseFragmentActivity<NewMainPresenter> impl
}
}
@Override
@Override
protected
void
onNewIntent
(
Intent
intent
)
{
super
.
onNewIntent
(
intent
);
}
@Override
protected
void
onResume
()
{
protected
void
onResume
()
{
super
.
onResume
();
super
.
onResume
();
initService
();
initFuncationData
();
initFuncationData
();
if
(((
int
)
SPUtils
.
get
(
"isFormal"
,
0
))
!=
0
)
{
if
(((
int
)
SPUtils
.
get
(
"isFormal"
,
0
))
!=
0
)
{
tv_version_name
.
setText
(
"v_"
+
DeviceUtils
.
getVersionName
(
this
)
+
"\u3000Beta"
);
tv_version_name
.
setText
(
"v_"
+
DeviceUtils
.
getVersionName
(
this
)
+
"\u3000Beta"
);
}
else
{
}
else
{
tv_version_name
.
setText
(
"v_"
+
DeviceUtils
.
getVersionName
(
this
));
tv_version_name
.
setText
(
"v_"
+
DeviceUtils
.
getVersionName
(
this
));
}
}
boolean
prjServiceRunning
=
StytemUtils
.
isServiceRunning
(
"com.joe.print.mvp.print.service.PrjService"
,
this
);
if
(!
prjServiceRunning
)
{
//開啟Prj打印服務
CC
.
obtainBuilder
(
ComponentName
.
COMPONENT_PRINT
)
.
setActionName
(
"openPrintService"
)
.
build
()
.
call
();
}
}
}
@Override
@Override
...
@@ -225,6 +217,28 @@ public class NewMainActivity extends BaseFragmentActivity<NewMainPresenter> impl
...
@@ -225,6 +217,28 @@ public class NewMainActivity extends BaseFragmentActivity<NewMainPresenter> impl
updateTitleInfo
();
updateTitleInfo
();
}
}
private
void
initService
()
{
boolean
deliveryOrderServiceRunning
=
StytemUtils
.
isServiceRunning
(
"com.gingersoft.gsa.cloud.common.service.DataNotificationService"
,
this
);
if
(!
deliveryOrderServiceRunning
)
{
Intent
service
=
new
Intent
(
GsaCloudApplication
.
getAppContext
(),
DataNotificationService
.
class
);
service
.
putExtra
(
DataNotificationService
.
CONNECTION_TYPE
,
DataNotificationService
.
mCurrConnectionType
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
startForegroundService
(
service
);
}
else
{
startService
(
service
);
}
}
// boolean prjServiceRunning = StytemUtils.isServiceRunning("com.joe.print.mvp.print.service.PrjService", this);
// if (!prjServiceRunning) {
// //開啟Prj打印服務
// CC.obtainBuilder(ComponentName.COMPONENT_PRINT)
// .setActionName("openPrintService")
// .build()
// .call();
// }
}
/**
/**
* 初始化側邊欄菜單項
* 初始化側邊欄菜單項
*/
*/
...
...
component-print/src/main/debug/AndroidManifest.xml
View file @
7e27ec13
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
<uses-permission
android:name=
"android.permission.WAKE_LOCK"
/>
<uses-permission
android:name=
"android.permission.WAKE_LOCK"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<application
<application
android:name=
"com.gingersoft.gsa.cloud.app.GsaCloudApplication"
android:name=
"com.gingersoft.gsa.cloud.app.GsaCloudApplication"
android:allowBackup=
"true"
android:allowBackup=
"true"
...
@@ -19,8 +20,10 @@
...
@@ -19,8 +20,10 @@
android:roundIcon=
"@mipmap/ic_launcher"
android:roundIcon=
"@mipmap/ic_launcher"
android:supportsRtl=
"true"
android:supportsRtl=
"true"
android:theme=
"@style/AppTheme"
>
android:theme=
"@style/AppTheme"
>
<activity
android:name=
".mvp.ui.activity.PrintAddCurrencyActivity"
/>
<activity
android:name=
".mvp.ui.activity.PrintAddCurrencyActivity"
/>
<activity
android:name=
".mvp.ui.activity.PrintActivity"
/>
<activity
android:name=
".mvp.ui.activity.PrintActivity"
android:launchMode=
"singleTop"
/>
<activity
android:name=
".mvp.ui.activity.PrinterAddActivity"
/>
<activity
android:name=
".mvp.ui.activity.PrinterAddActivity"
/>
<activity
android:name=
".mvp.ui.activity.PrintTestActivity"
>
<activity
android:name=
".mvp.ui.activity.PrintTestActivity"
>
<intent-filter>
<intent-filter>
...
...
component-print/src/main/java/com/joe/print/PrintComponent.java
View file @
7e27ec13
...
@@ -6,8 +6,10 @@ import com.billy.cc.core.component.CC;
...
@@ -6,8 +6,10 @@ import com.billy.cc.core.component.CC;
import
com.billy.cc.core.component.CCResult
;
import
com.billy.cc.core.component.CCResult
;
import
com.billy.cc.core.component.CCUtil
;
import
com.billy.cc.core.component.CCUtil
;
import
com.billy.cc.core.component.IComponent
;
import
com.billy.cc.core.component.IComponent
;
import
com.gingersoft.gsa.cloud.common.constans.PrintConstans
;
import
com.gingersoft.gsa.cloud.component.ComponentName
;
import
com.gingersoft.gsa.cloud.component.ComponentName
;
import
com.jess.arms.utils.ArmsUtils
;
import
com.jess.arms.utils.ArmsUtils
;
import
com.joe.print.mvp.print.PrinterManger.PrjPtinterManager
;
import
com.joe.print.mvp.print.service.PrjService
;
import
com.joe.print.mvp.print.service.PrjService
;
import
com.joe.print.mvp.ui.activity.PrintActivity
;
import
com.joe.print.mvp.ui.activity.PrintActivity
;
import
com.joe.print.mvp.ui.activity.PrinterListActivity
;
import
com.joe.print.mvp.ui.activity.PrinterListActivity
;
...
@@ -64,11 +66,14 @@ public class PrintComponent implements IComponent {
...
@@ -64,11 +66,14 @@ public class PrintComponent implements IComponent {
cc
.
getContext
().
stopService
(
new
Intent
(
cc
.
getContext
(),
PrjService
.
class
));
cc
.
getContext
().
stopService
(
new
Intent
(
cc
.
getContext
(),
PrjService
.
class
));
CC
.
sendCCResult
(
cc
.
getCallId
(),
CCResult
.
success
());
CC
.
sendCCResult
(
cc
.
getCallId
(),
CCResult
.
success
());
break
;
break
;
case
"getPrjData"
:
PrjPtinterManager
.
getInstance
(
cc
.
getContext
()).
initUsbPrint
();
PrjPtinterManager
.
getInstance
(
cc
.
getContext
()).
getPrjInfo
();
break
;
default
:
default
:
// cc.callAsync(new IComponentCallback() {
// cc.callAsync(new IComponentCallback() {
// @Override
// @Override
// public void onResult(CC cc, CCResult result) {
// public void onResult(CC cc, CCResult result) {
//
// }
// }
// });
// });
//这个逻辑分支上没有调用CC.sendCCResult(...),是一种错误的示例
//这个逻辑分支上没有调用CC.sendCCResult(...),是一种错误的示例
...
...
component-print/src/main/java/com/joe/print/mvp/print/EpsonPrint.java
View file @
7e27ec13
...
@@ -294,7 +294,6 @@ public class EpsonPrint implements ReceiveListener {
...
@@ -294,7 +294,6 @@ public class EpsonPrint implements ReceiveListener {
Log
.
d
(
"eee"
,
"針式打印機創建數據失敗"
);
Log
.
d
(
"eee"
,
"針式打印機創建數據失敗"
);
//如果是創建數據失敗,說明這個數據有問題,移除掉
//如果是創建數據失敗,說明這個數據有問題,移除掉
bitmaps
.
remove
(
bitmap
);
bitmaps
.
remove
(
bitmap
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"針式打印機添加數據失敗"
+
ip
));
updatePrintState
(
PrintSocketHolder
.
ERROR_6
);
updatePrintState
(
PrintSocketHolder
.
ERROR_6
);
isPrint
=
false
;
isPrint
=
false
;
return
;
return
;
...
@@ -315,11 +314,11 @@ public class EpsonPrint implements ReceiveListener {
...
@@ -315,11 +314,11 @@ public class EpsonPrint implements ReceiveListener {
if
(
statusInfo
.
getPaper
()
==
2
)
{
if
(
statusInfo
.
getPaper
()
==
2
)
{
//沒紙了
//沒紙了
updatePrintState
(
PrintSocketHolder
.
ERROR_11
);
updatePrintState
(
PrintSocketHolder
.
ERROR_11
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"針式打印機缺紙,打印失敗"
+
ip
)
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"針式打印機缺紙,打印失敗"
+
ip
),
0
);
}
else
{
}
else
{
//紙張狀態異常
//紙張狀態異常
updatePrintState
(
PrintSocketHolder
.
ERROR_11
);
updatePrintState
(
PrintSocketHolder
.
ERROR_11
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"針式打印機紙張異常,請重啟打印機"
+
ip
)
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"針式打印機紙張異常,請重啟打印機"
+
ip
),
0
);
}
}
isPrint
=
false
;
isPrint
=
false
;
return
;
return
;
...
@@ -331,7 +330,7 @@ public class EpsonPrint implements ReceiveListener {
...
@@ -331,7 +330,7 @@ public class EpsonPrint implements ReceiveListener {
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
d
(
"eee"
,
"針式打印機打印失敗"
+
",任務數:"
+
bitmaps
.
size
()
+
e
.
getMessage
());
Log
.
d
(
"eee"
,
"針式打印機打印失敗"
+
",任務數:"
+
bitmaps
.
size
()
+
e
.
getMessage
());
updatePrintState
(
PrintSocketHolder
.
ERROR_10
);
updatePrintState
(
PrintSocketHolder
.
ERROR_10
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"針式打印機打印報錯"
+
ip
)
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"打印機連接成功,發送數據出現問題"
),
0
);
mPrinter
.
clearCommandBuffer
();
mPrinter
.
clearCommandBuffer
();
disconnectPrinter
();
disconnectPrinter
();
isPrint
=
false
;
isPrint
=
false
;
...
...
component-print/src/main/java/com/joe/print/mvp/print/PrinterManger/PrinterManager.java
View file @
7e27ec13
...
@@ -26,4 +26,7 @@ public class PrinterManager {
...
@@ -26,4 +26,7 @@ public class PrinterManager {
public
void
setDeviceBeans
(
List
<
PrinterDeviceBean
>
deviceBeans
)
{
public
void
setDeviceBeans
(
List
<
PrinterDeviceBean
>
deviceBeans
)
{
this
.
deviceBeans
=
deviceBeans
;
this
.
deviceBeans
=
deviceBeans
;
}
}
}
}
component-print/src/main/java/com/joe/print/mvp/print/PrinterManger/PrjPtinterManager.java
0 → 100644
View file @
7e27ec13
package
com
.
joe
.
print
.
mvp
.
print
.
PrinterManger
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.os.Build
;
import
android.os.IBinder
;
import
android.os.RemoteException
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
com.epson.epos2.printer.Printer
;
import
com.epson.epos2.printer.PrinterStatusInfo
;
import
com.epson.epos2.printer.ReceiveListener
;
import
com.gingersoft.gsa.cloud.common.constans.HttpsConstans
;
import
com.gingersoft.gsa.cloud.common.constans.PrintConstans
;
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
;
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
;
import
com.gingersoft.gsa.cloud.common.printer.AidlUtil
;
import
com.gingersoft.gsa.cloud.common.printer.plugins.PrinterPlugins
;
import
com.gingersoft.gsa.cloud.common.utils.JsonUtils
;
import
com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils
;
import
com.gingersoft.gsa.cloud.common.utils.okhttpUtils.OkHttp3Utils
;
import
com.gingersoft.gsa.cloud.common.utils.other.TextUtil
;
import
com.gingersoft.gsa.cloud.common.utils.threadPool.ThreadPoolManager
;
import
com.gingersoft.gsa.cloud.common.utils.time.TimeUtils
;
import
com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils
;
import
com.gingersoft.gsa.cloud.database.bean.PrintCurrencyBean
;
import
com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean
;
import
com.gingersoft.gsa.cloud.database.utils.PrinterDeviceDaoUtils
;
import
com.gingersoft.gsa.cloud.print.PrintExecutor
;
import
com.gingersoft.gsa.cloud.print.PrinterWriter58mm
;
import
com.gingersoft.gsa.cloud.print.bean.PrjBean
;
import
com.gingersoft.gsa.cloud.print.bean.UpdateBean
;
import
com.hyweb.n5.lib.constant.PrinterConstant
;
import
com.hyweb.n5.lib.util.PrinterUtil
;
import
com.hyweb.n5.server.aidl.IOnPrintCallback
;
import
com.joe.print.mvp.print.EpsonPrint
;
import
com.joe.print.mvp.print.PrintPrjKitchen
;
import
com.joe.print.mvp.print.common.PrinterFinderCallback
;
import
com.joe.print.mvp.print.common.SendResultCode
;
import
com.joe.print.mvp.print.maker.PrjPrintMaker
;
import
com.joe.print.mvp.print.usb.EscCommand
;
import
com.joe.print.mvp.print.usb.UsbPrint
;
import
com.joe.print.mvp.print.usb.UsbPrinter
;
import
com.joe.print.mvp.print.usb.UsbPrinterFinder
;
import
com.joe.print.mvp.print.utils.MyPrintUtils
;
import
com.sunmi.peripheral.printer.InnerResultCallbcak
;
import
com.xuexiang.rxutil2.rxjava.RxJavaUtils
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.io.IOException
;
import
java.io.PrintStream
;
import
java.net.ConnectException
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.TimeUnit
;
import
io.reactivex.Observer
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.schedulers.Schedulers
;
import
jcifs.smb.SmbFile
;
import
jcifs.smb.SmbFileOutputStream
;
import
okhttp3.MediaType
;
import
okhttp3.RequestBody
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
database
.
bean
.
PrinterDeviceBean
.
PRINT_IP
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
database
.
bean
.
PrinterDeviceBean
.
PRINT_LOCAL
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
database
.
bean
.
PrinterDeviceBean
.
PRINT_PRJ_PC
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
database
.
bean
.
PrinterDeviceBean
.
PRINT_USB
;
/**
* Created by Wyh on 2020/1/17.
*/
public
class
PrjPtinterManager
implements
ReceiveListener
{
private
String
TAG
=
"Prj"
;
private
Context
mContext
;
private
int
totalPrj
;
private
int
currentIndex
;
private
UsbPrinterFinder
printerFinder
;
private
List
<
UsbPrinter
>
mUsbPrinters
;
private
volatile
static
PrjPtinterManager
prjPtinterManager
;
public
static
PrjPtinterManager
getInstance
(
Context
context
)
{
if
(
prjPtinterManager
==
null
)
{
synchronized
(
PrjPtinterManager
.
class
)
{
if
(
prjPtinterManager
==
null
)
{
prjPtinterManager
=
new
PrjPtinterManager
(
context
);
}
}
}
return
prjPtinterManager
;
}
public
PrjPtinterManager
(
Context
context
)
{
this
.
mContext
=
context
;
}
public
void
initUsbPrint
()
{
if
(
printerFinder
!=
null
)
{
return
;
}
printerFinder
=
new
UsbPrinterFinder
(
mContext
,
new
PrinterFinderCallback
<
UsbPrinter
>()
{
@Override
public
void
onStart
()
{
}
@Override
public
void
onFound
(
UsbPrinter
usbPrinter
)
{
}
@Override
public
void
onFinished
(
List
<
UsbPrinter
>
usbPrinters
)
{
mUsbPrinters
=
usbPrinters
;
}
});
//開啟監聽USB連接
printerFinder
.
startFinder
();
}
/**
* 請求prj數據
*/
public
void
getPrjInfo
()
{
OkHttp3Utils
.
get
(
HttpsConstans
.
ROOT_SERVER_ADDRESS_FORMAL
+
"printerRecording/get?restaurantId="
+
RestaurantInfoManager
.
newInstance
().
getRestaurantId
())
.
subscribeOn
(
Schedulers
.
io
())
//切换到io线程進行網絡請求
.
observeOn
(
Schedulers
.
io
())
//切換到io线程處理請求結果
.
subscribe
(
new
Observer
<
String
>()
{
@Override
public
void
onSubscribe
(
Disposable
d
)
{
LoganManager
.
w_printer
(
TAG
,
"獲取Prj數據 Disposable"
);
}
@Override
public
void
onNext
(
String
prjInfo
)
{
LoganManager
.
w_printer
(
TAG
,
"獲取Prj數據 onNext: "
+
prjInfo
);
//請求到數據,停止輪詢,開始打印,在打印完之後再重新開始輪詢
actionPrint
(
prjInfo
);
}
@Override
public
void
onError
(
Throwable
e
)
{
LoganManager
.
w_printer
(
TAG
,
"獲取Prj數據 onError:"
+
e
.
getMessage
());
}
@Override
public
void
onComplete
()
{
LoganManager
.
w_printer
(
TAG
,
"獲取Prj數據 onComplete"
);
}
});
}
public
void
actionPrint
(
String
json
)
{
if
(
TextUtils
.
isEmpty
(
json
))
{
return
;
}
Map
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
listMap
=
new
HashMap
<>();
currentIndex
=
0
;
totalPrj
=
0
;
PrjBean
prjBean
=
JsonUtils
.
parseObject
(
json
,
PrjBean
.
class
);
if
(
prjBean
==
null
||
prjBean
.
getData
()
==
null
)
{
LoganManager
.
w_printer
(
TAG
,
"newPrint prjBean == null || prjBean.getData() == null "
);
return
;
}
//第一步:解析PRJ數據,格式為 Map<廚房位置,需要打印的數據>
try
{
JSONObject
jsonObject
=
new
JSONObject
(
prjBean
.
getData
());
//通过迭代器获取这段json当中所有的key值
Iterator
keys
=
jsonObject
.
keys
();
//然后通过一个循环取出所有的key值
while
(
keys
.
hasNext
())
{
String
key
=
String
.
valueOf
(
keys
.
next
());
//最后就可以通过刚刚得到的key值去解析后面的json了
JSONArray
dataJson
=
(
JSONArray
)
jsonObject
.
get
(
key
);
List
<
PrjBean
.
DataBean
.
Bean
>
datas
=
JsonUtils
.
parseArray
(
dataJson
.
toString
(),
PrjBean
.
DataBean
.
Bean
.
class
);
if
(
datas
!=
null
&&
datas
.
size
()
>
0
)
{
//打印位置和需要打印的數據
listMap
.
put
(
key
,
datas
);
//計算本次打印的prj總張數有沒有不需要切紙的
boolean
isHasNoCut
=
false
;
for
(
PrjBean
.
DataBean
.
Bean
bean
:
datas
)
{
if
(
bean
.
getStatus
()
==
2
)
{
//需要切紙,prj總數就+1
totalPrj
++;
}
else
{
isHasNoCut
=
true
;
}
}
if
(
isHasNoCut
)
{
//有不需要切紙的食物,prj總數+1
totalPrj
++;
}
}
}
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
LoganManager
.
w_printer
(
TAG
,
"newPrint JSONException: "
+
e
.
getMessage
());
}
setPrjIndex
(
listMap
,
totalPrj
);
foreachPrint
(
listMap
,
getPrinterDevices
());
}
private
Map
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
setPrjIndex
(
Map
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
listMap
,
int
totalPrj
)
{
for
(
Map
.
Entry
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
prjMap
:
listMap
.
entrySet
())
{
//上一個對象是否切紙
boolean
lastIsCute
=
false
;
for
(
PrjBean
.
DataBean
.
Bean
bean
:
prjMap
.
getValue
())
{
bean
.
setTotalPrj
(
totalPrj
);
if
(
bean
.
getStatus
()
==
2
)
{
//要切紙,紙張數+1
currentIndex
++;
lastIsCute
=
true
;
}
else
{
if
(
currentIndex
==
0
)
{
currentIndex
=
1
;
}
else
if
(
lastIsCute
)
{
//如果上一張切紙,那這一張下標就要+1
currentIndex
++;
}
lastIsCute
=
false
;
}
bean
.
setCurrentIndex
(
currentIndex
);
}
currentIndex
++;
}
return
listMap
;
}
private
void
foreachPrint
(
Map
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
listMap
,
List
<
PrinterDeviceBean
>
printerDeviceBeans
)
{
//雙重遍歷可以以後優化
//第二步:遍歷 Map<廚房位置,需要打印的數據>,通過廚房位置找到對應的打印機,並且通過數據拿到對應的通用配置
for
(
Map
.
Entry
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
prjMap
:
listMap
.
entrySet
())
{
boolean
isFindDevice
=
false
;
for
(
PrinterDeviceBean
deviceBean
:
printerDeviceBeans
)
{
//遍歷得到當前打印機,如果沒找到打印機,就不打印
if
(
prjMap
.
getKey
().
toLowerCase
().
equals
(
deviceBean
.
getName
().
toLowerCase
()))
{
isFindDevice
=
true
;
//如果PRJ數據的廚房位置和打印機名稱相同,則就是這台打印機打印
//通過需要打印的數據,得到通用配置
PrintCurrencyBean
printCurrencyBean
=
getPrintCurrencyBean
(
prjMap
.
getValue
());
//將通用配置設置給了對應的打印機對象後,得到新的打印機對象
PrinterDeviceBean
configPrinterDeviceBean
=
MyPrintUtils
.
configPrinterProperties
(
printCurrencyBean
,
deviceBean
);
// 判斷打印機的類型,調用不同的打印方式,
// 這裡已經拿到這台打印機需要打印的所有數據,為prjMp.getValue(),
// 生成對應的打印數據,除了針式打印機,其他都生成bitmap
generatePrintData
(
prjMap
.
getKey
(),
prjMap
.
getValue
(),
configPrinterDeviceBean
);
}
}
if
(!
isFindDevice
)
{
//用戶沒有這個打印機,打印失敗,返回後台原因
updatePrjState
(
UpdateBean
.
FAIL_PRINT_BY_NOT_FIND_DEVICE
,
getPrintIdsByPrjData
(
prjMap
.
getValue
()));
}
}
}
/**
* 獲取打印設備
*
* @return 打印機列表
*/
private
List
<
PrinterDeviceBean
>
getPrinterDevices
()
{
//讀取打印機和通用配置,可以優化
//獲取所有打印機
PrinterDeviceDaoUtils
printerDeviceDaoUtils
=
new
PrinterDeviceDaoUtils
(
mContext
);
LoganManager
.
w_printer
(
TAG
,
"获取打印設備信息"
);
return
printerDeviceDaoUtils
.
queryAllPrinterDeviceBean
();
}
/**
* 獲取通用打印配置
*
* @param beans prj數據
* @return 通用配置
*/
private
PrintCurrencyBean
getPrintCurrencyBean
(
List
<
PrjBean
.
DataBean
.
Bean
>
beans
)
{
PrintCurrencyBean
printCurrencyBean
=
null
;
if
(
beans
!=
null
&&
beans
.
size
()
>
0
)
{
if
(
beans
.
get
(
0
).
getOrderType
()
==
1
||
beans
.
get
(
0
).
getOrderType
()
==
3
)
{
//堂食,skyorder
printCurrencyBean
=
MyPrintUtils
.
getPrintCurrencyBeanByType
(
mContext
,
1
);
}
else
{
//外賣
printCurrencyBean
=
MyPrintUtils
.
getPrintCurrencyBeanByType
(
mContext
,
2
);
}
}
return
printCurrencyBean
;
}
/**
* 生成用於打印的prj的Bitmap
*/
private
void
generatePrintData
(
String
key
,
List
<
PrjBean
.
DataBean
.
Bean
>
beans
,
PrinterDeviceBean
printerDeviceBean
)
{
int
orderType
=
1
;
if
(
beans
!=
null
&&
beans
.
size
()
>
0
)
{
orderType
=
beans
.
get
(
0
).
getOrderType
();
}
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrinterDataBefore
(
orderType
,
PrintConstans
.
PRINT_KITCHEN
,
GsonUtils
.
GsonString
(
beans
),
GsonUtils
.
GsonString
(
printerDeviceBean
));
if
(
isPinPrinter
(
printerDeviceBean
)
&&
printerDeviceBean
.
getPrinterDeviceType
()
==
PRINT_IP
)
{
//針式打印
stylusPrinting
(
key
,
beans
,
printerDeviceBean
);
}
else
if
(
printerDeviceBean
.
getPrinterDeviceType
()
==
PRINT_PRJ_PC
)
{
//prj模式,生成文件到共享電腦上
prjToPc
(
beans
,
printerDeviceBean
);
}
else
if
(
printerDeviceBean
.
getPrinterDeviceType
()
==
PRINT_LOCAL
&&
PrintConstans
.
PRINT_MODEL_WISEPOS
.
contains
(
Build
.
MODEL
))
{
//本機打印並且是BBPOS
}
else
{
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
=
generatePrintMaps
(
key
,
beans
,
printerDeviceBean
);
switch
(
printerDeviceBean
.
getPrinterDeviceType
())
{
case
PRINT_IP:
LoganManager
.
w_printer
(
TAG
,
"開始IP打印-->"
);
//IP打印
ipPrint
(
printerDeviceBean
,
bitmapMaps
);
break
;
case
PRINT_LOCAL:
//本地N5或Sunmi打印
locationPrint
(
bitmapMaps
);
break
;
case
PRINT_USB:
LoganManager
.
w_printer
(
TAG
,
"開始USB打印-->"
);
//USB打印
usbPrint
(
bitmapMaps
);
break
;
default
:
break
;
}
}
}
/**
* PRJ模式,生成PRJ文件到共享的電腦上
*
* @param beans prj數據
* @param printerDeviceBean 打印設備
*/
private
void
prjToPc
(
List
<
PrjBean
.
DataBean
.
Bean
>
beans
,
PrinterDeviceBean
printerDeviceBean
)
{
//PRJ模式,生成PRJ文件到共享的電腦上
ThreadPoolManager
.
getInstence
().
putExecutableTasks
(()
->
{
List
<
PrjBean
.
DataBean
.
Bean
>
noCutList
=
new
ArrayList
<>();
List
<
PrjBean
.
DataBean
.
Bean
>
cutList
=
new
ArrayList
<>();
for
(
PrjBean
.
DataBean
.
Bean
bean
:
beans
)
{
if
(
bean
.
getStatus
()
==
2
)
{
//需要切紙
cutList
.
add
(
bean
);
}
else
{
//不需要切紙
noCutList
.
add
(
bean
);
}
}
String
rootPath
=
"smb://"
+
printerDeviceBean
.
getPrintPath
()
+
"/"
;
try
{
SmbFile
smbFile
=
new
SmbFile
(
rootPath
);
smbFile
.
connect
();
if
(
smbFile
.
isDirectory
())
{
for
(
int
i
=
0
;
i
<
cutList
.
size
();
i
++)
{
String
newFilePath
=
rootPath
+
System
.
currentTimeMillis
()
+
".prj"
;
SmbFile
createFile
=
new
SmbFile
(
newFilePath
);
createFile
.
createNewFile
();
if
(
createFile
.
exists
())
{
PrintStream
ps
=
new
PrintStream
(
new
SmbFileOutputStream
(
createFile
));
// 往文件里写入字符串
String
prjInfo
=
"[printType]ptKitchen\n"
+
"[table]4\n"
+
"[date]落單時間:11-13 17:48\n"
+
"[waiter]n5 收銀員\n"
+
"[KP]K2烤爐\n"
+
"[PAX]人數:2\n"
+
"[line]\n"
+
"[food_1]1 包子(主項)\n"
+
"[food_1]1 包子(主項)\n"
+
"[table2]4\n"
;
ps
.
println
(
prjInfo
);
}
}
if
(
noCutList
.
size
()
>
0
)
{
String
newFilePath
=
rootPath
+
System
.
currentTimeMillis
()
+
".prj"
;
SmbFile
createFile
=
new
SmbFile
(
newFilePath
);
createFile
.
createNewFile
();
if
(
createFile
.
exists
())
{
PrintStream
ps
=
new
PrintStream
(
new
SmbFileOutputStream
(
createFile
));
PrjBean
.
DataBean
.
Bean
bean
=
noCutList
.
get
(
0
);
String
tableName
=
""
;
if
(
TextUtil
.
isEmptyOrNullOrUndefined
(
bean
.
getTableName
()))
{
if
(
bean
.
getOrderType
()
==
7
)
{
tableName
=
"自取"
;
}
else
{
tableName
=
"外賣"
;
}
}
else
{
tableName
=
bean
.
getTableName
();
}
// 往文件里写入字符串
// String prjInfo = "[printType]ptKitchen\n" +
// "[table]4\n" +
// "[date]落單時間:11-13 17:48\n" +
// "[waiter]n5 收銀員\n" +
// "[KP]K2烤爐\n" +
// "[PAX]人數:2\n" +
// "[line]\n" +
// "[food_1]1 包子(主項)\n" +
// "[food_1]1 包子(主項)\n" +
// "[table2]4\n";
String
prjInfo
=
"[printType]ptKitchen\n"
+
"[table]"
+
tableName
+
"\n"
+
"[date]落單時間:11-13 17:48\n"
+
"[waiter]n5 收銀員\n"
+
"[KP]K2烤爐\n"
+
"[PAX]人數:2\n"
+
"[line]\n"
+
"[food_1]1 包子(主項)\n"
+
"[food_1]1 包子(主項)\n"
+
"[table2]"
+
tableName
+
"\n"
;
ps
.
println
(
prjInfo
);
}
}
}
else
{
ToastUtils
.
show
(
mContext
,
"PRJ輸出路徑必須為文件夾"
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
});
}
/**
* 針式打印機
*
* @param key 廚房位置
* @param beans prj數據
* @param printerDeviceBean 打印機
*/
private
void
stylusPrinting
(
String
key
,
List
<
PrjBean
.
DataBean
.
Bean
>
beans
,
PrinterDeviceBean
printerDeviceBean
)
{
//針式打印機並且打印機類型為IP打印,生成獨特的格式
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
=
generatePrintMaps
(
key
,
beans
,
printerDeviceBean
);
//將打印的圖片保存到手機中
hookPrinterBitmap
(
bitmapMaps
,
beans
);
boolean
initResult
=
EpsonPrint
.
getInstance
().
initializeObject
(
mContext
,
this
,
errorCode
->
updatePrjState
(
errorCode
,
getPrintIds
(
bitmapMaps
)));
if
(!
initResult
)
{
//初始化打印機失敗
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
ConnectException
(
"初始化針式打印機失敗"
));
updatePrjState
(
UpdateBean
.
FAIL_EPSON_INIT
,
getPrintIds
(
bitmapMaps
));
return
;
}
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionBefore
(
"針式打印機"
+
bitmapMaps
.
size
(),
printerDeviceBean
.
getIp
(),
printerDeviceBean
.
getPort
(),
0
,
0
);
Log
.
d
(
"eee"
,
"針式打印機本次PRJ數量:"
+
bitmapMaps
.
size
());
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
mapEntry
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
EpsonPrint
.
getInstance
().
putPrintData
(
printerDeviceBean
.
getIp
(),
mapEntry
.
getValue
(),
mapEntry
.
getKey
());
}
}
}
/**
* ip設備打印
*/
public
void
ipPrint
(
PrinterDeviceBean
printerDeviceBean
,
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
)
{
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
// if (executor == null) {
// executor = new PrintExecutor().setOnPrjPrintResultListener((errorCode, ids) -> {
// switch (errorCode) {
// case PrintSocketHolder.ERROR_0:
// //更新狀態
// updatePrjSuccess(ids);
// break;
// case PrintSocketHolder.ERROR_2:
// updatePrjFailure(ids);
// break;
// }
// });
// }
// PrjPrintMaker maker = new PrjPrintMaker(bitmapMaps.get(i), printerDeviceBean.getIp(), printerDeviceBean.getPort());
// executor.doPrinterRequestAsync(maker);
PrintExecutor
.
getInstance
().
setOnPrjPrintResultListener
(
this
::
updatePrjState
);
PrjPrintMaker
maker
=
new
PrjPrintMaker
(
bitmapMaps
.
get
(
i
),
printerDeviceBean
.
getIp
(),
printerDeviceBean
.
getPort
());
PrintExecutor
.
getInstance
().
doPrinterRequestAsync
(
maker
);
}
}
/**
* usb打印
*/
public
void
usbPrint
(
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
)
{
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
bitmapMap
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
final
String
key
=
bitmapMap
.
getKey
();
UsbPrint
usbPrint
=
new
UsbPrint
(
mContext
,
(
code
,
printId
)
->
{
//打印結果
if
(
code
==
SendResultCode
.
SEND_SUCCESS
)
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
updatePrjSuccess
(
key
);
}
else
if
(
code
==
SendResultCode
.
SEND_FAILED
)
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"發送打印數據失敗"
),
code
);
updatePrjFailure
(
key
);
}
});
if
(
mUsbPrinters
!=
null
&&
mUsbPrinters
.
size
()
>
0
)
{
EscCommand
esc
=
new
EscCommand
();
ArrayList
<
byte
[]>
bytes
=
new
ArrayList
<>();
try
{
bytes
.
addAll
(
new
PrinterWriter58mm
().
getImageByte
(
bitmapMap
.
getValue
()));
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
bytes
.
add
(
esc
.
getPrintAndFeedLines
((
byte
)
8
));
bytes
.
add
(
esc
.
getCutPaper
());
bytes
.
add
(
esc
.
getCleanCache
());
usbPrint
.
sendPrintCommand
(
mUsbPrinters
.
get
(
0
),
bytes
);
}
else
{
//打印失敗
updatePrjFailure
(
key
);
}
}
}
}
/**
* 本機打印
*/
public
void
locationPrint
(
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
)
{
String
model
=
Build
.
MODEL
;
if
(
PrintConstans
.
PRINT_MODEL_V2
.
contains
(
model
))
{
//商米打印
LoganManager
.
w_printer
(
TAG
,
"開始商米打印-->"
);
sunmiPrint
(
bitmapMaps
);
}
else
if
(
PrintConstans
.
PRINT_MODEL_N5
.
contains
(
model
))
{
//N5打印
LoganManager
.
w_printer
(
TAG
,
"開始N5打印-->"
);
n5Print
(
bitmapMaps
);
}
else
if
(
PrintConstans
.
PRINT_MODEL_WISEPOS
.
contains
(
model
))
{
//BBPOS,生成data
ToastUtils
.
show
(
mContext
,
"BBPOS不支持打印廚房單"
);
}
else
{
updatePrjState
(
UpdateBean
.
FAIL_LOCAL_PRINT_NOT_DEVICE
,
getPrintIds
(
bitmapMaps
));
}
}
/**
* 獲取本次打印的prj id
*
* @return prj的id集合
*/
private
String
getPrintIdsByPrjData
(
List
<
PrjBean
.
DataBean
.
Bean
>
prjBeans
)
{
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
PrjBean
.
DataBean
.
Bean
prjBean
:
prjBeans
)
{
stringBuilder
.
append
(
prjBean
.
getId
());
if
(
stringBuilder
.
toString
().
lastIndexOf
(
","
)
!=
stringBuilder
.
length
()
-
1
)
{
//如果最後一位不是逗號,才添加
stringBuilder
.
append
(
","
);
}
}
return
stringBuilder
.
toString
();
}
/**
* 獲取本次打印的prj id
*
* @param bitmapMaps
* @return
*/
private
String
getPrintIds
(
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
)
{
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
mapEntry
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
stringBuilder
.
append
(
mapEntry
.
getKey
()).
append
(
","
);
}
}
if
(
stringBuilder
.
length
()
<=
0
)
{
return
""
;
}
//最後一位是逗號,去掉
return
stringBuilder
.
substring
(
0
,
stringBuilder
.
length
()
-
1
);
}
/**
* 商米打印
*/
private
void
sunmiPrint
(
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
)
{
//商米打印
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
mapEntry
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
final
String
ids
=
mapEntry
.
getKey
();
AidlUtil
.
getInstance
().
printBitmap
(
mapEntry
.
getValue
(),
new
InnerResultCallbcak
()
{
@Override
public
void
onRunResult
(
boolean
isSuccess
)
{
LoganManager
.
w_printer
(
TAG
,
"商米onRunResult: "
+
isSuccess
);
//返回接⼝执⾏的情况(并⾮真实打印):成功或失败
if
(
isSuccess
)
{
updatePrjSuccess
(
ids
);
}
else
{
updatePrjFailure
(
ids
);
}
}
@Override
public
void
onReturnString
(
String
result
)
{
//部分接⼝会异步返回查询数据
LoganManager
.
w_printer
(
TAG
,
"商米onReturnString: "
+
result
);
}
@Override
public
void
onRaiseException
(
int
code
,
String
msg
)
{
//接⼝执⾏失败时,返回的异常状态
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
msg
),
code
);
LoganManager
.
w_printer
(
TAG
,
"商米onRaiseException: "
+
code
+
msg
);
switch
(
code
)
{
case
3
:
//通訊異常
updatePrjState
(
UpdateBean
.
FAIL_PRINT_BY_NOT_CONNECT
,
ids
);
break
;
case
4
:
//缺紙
updatePrjState
(
UpdateBean
.
FAIL_NOT_PAPER
,
ids
);
break
;
case
5
:
//過熱
updatePrjState
(
UpdateBean
.
FAIL_SUNMI_PRINT_HOT
,
ids
);
break
;
case
6
:
//蓋子未合上
updatePrjState
(
UpdateBean
.
FAIL_LID_NOT_CLOSED_SUNMI
,
ids
);
break
;
case
7
:
//切刀異常
updatePrjState
(
UpdateBean
.
FAIL_CUT_ABNORMAL_SUNMI
,
ids
);
break
;
case
9
:
//黑標異常
updatePrjState
(
UpdateBean
.
FAIL_SUNMI_NO_BLACK_MARK_DETECTED
,
ids
);
break
;
default
:
updatePrjState
(
UpdateBean
.
FAIL_PRINT_BY_NOT_FIND_DEVICE_SUNMI
,
ids
);
break
;
}
}
@Override
public
void
onPrintResult
(
int
code
,
String
msg
)
{
//事务模式下真实的打印结果返回
LoganManager
.
w_printer
(
TAG
,
"商米onPrintResult: "
+
msg
);
}
});
}
}
}
/**
* n5打印
*/
private
void
n5Print
(
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
)
{
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
mapEntry
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
final
String
ids
=
mapEntry
.
getKey
();
try
{
PrinterUtil
.
appendImage
(
mapEntry
.
getValue
(),
PrinterConstant
.
ALIGN_CENTER
);
PrinterUtil
.
appendPrnStr
(
"\n"
,
24
,
PrinterConstant
.
ALIGN_CENTER
,
false
);
PrinterUtil
.
appendPrnStr
(
"\n"
,
24
,
PrinterConstant
.
ALIGN_CENTER
,
false
);
PrinterUtil
.
startPrint
(
true
,
new
IOnPrintCallback
.
Stub
()
{
@Override
public
void
onPrintResult
(
int
i
)
{
LoganManager
.
w_printer
(
TAG
,
"N5 onPrintResult: "
+
i
);
if
(
i
==
0
)
{
//打印成功
updatePrjSuccess
(
ids
);
}
else
{
//打印失敗
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
UpdateBean
.
getStateByCode
(
i
)),
i
);
updatePrjState
(
i
,
ids
);
}
}
@Override
public
IBinder
asBinder
()
{
LoganManager
.
w_printer
(
TAG
,
"N5 asBinder"
);
return
this
;
}
});
}
catch
(
RemoteException
e
)
{
e
.
printStackTrace
();
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
e
,
i
);
LoganManager
.
w_printer
(
TAG
,
"N5 RemoteException :"
+
e
.
getLocalizedMessage
());
updatePrjFailure
(
ids
);
}
}
}
}
/**
* 生成打印需要的Map集合,Map的key是這張PRJ的所有PRJ記錄的id,然後會同時打印多張,所以是一個List集合
*
* @param key 打印位置
* @param beans 打印的食品和其他的一些信息
*/
private
List
<
Map
<
String
,
Bitmap
>>
generatePrintMaps
(
String
key
,
List
<
PrjBean
.
DataBean
.
Bean
>
beans
,
PrinterDeviceBean
printerDeviceBean
)
{
PrintPrjKitchen
printPrjKitchen
=
new
PrintPrjKitchen
();
//這個Map的key是這張PRJ的所有PRJ記錄的id,然後會同時打印多張,所以是一個List集合
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
=
new
ArrayList
<>();
List
<
PrjBean
.
DataBean
.
Bean
>
noCut
=
new
ArrayList
<>();
//不帶*號,所有同樣廚房位置的食品都在一張紙上
for
(
PrjBean
.
DataBean
.
Bean
bean
:
beans
)
{
if
(
bean
.
getStatus
()
==
2
)
{
Map
<
String
,
Bitmap
>
map
=
new
HashMap
<>();
//帶*,需要切紙的,單獨放一張紙
map
.
put
(
bean
.
getId
()
+
""
,
printPrjKitchen
.
getKitChenPrintBitmap
(
mContext
,
key
,
bean
,
printerDeviceBean
));
bitmapMaps
.
add
(
map
);
}
else
{
noCut
.
add
(
bean
);
}
}
if
(
noCut
.
size
()
>
0
)
{
Map
<
String
,
Bitmap
>
map
=
new
HashMap
<>();
//遍歷拿到這張紙所有的PRJ記錄ID
StringBuilder
stringBuffer
=
new
StringBuilder
();
for
(
PrjBean
.
DataBean
.
Bean
noCutData
:
noCut
)
{
stringBuffer
.
append
(
noCutData
.
getId
());
stringBuffer
.
append
(
","
);
}
Bitmap
prjBitmap
=
printPrjKitchen
.
getKitChenPrintBitmap
(
mContext
,
key
,
noCut
,
printerDeviceBean
);
map
.
put
(
stringBuffer
.
toString
(),
prjBitmap
);
bitmapMaps
.
add
(
map
);
}
hookPrinterBitmap
(
bitmapMaps
,
beans
);
return
bitmapMaps
;
}
private
void
hookPrinterBitmap
(
List
<
Map
<
String
,
Bitmap
>>
bitmapMaps
,
List
<
PrjBean
.
DataBean
.
Bean
>
beans
)
{
if
(
bitmapMaps
.
size
()
>
0
)
{
String
prjName
=
String
.
valueOf
(
System
.
currentTimeMillis
());
int
orderType
=
1
;
if
(
beans
.
size
()
>
0
)
{
PrjBean
.
DataBean
.
Bean
prjBean
=
beans
.
get
(
0
);
if
(
prjBean
!=
null
)
{
if
(!
TextUtils
.
isEmpty
(
prjBean
.
getBillNo
()))
{
prjName
=
prjBean
.
getBillNo
();
}
else
{
prjName
=
prjBean
.
getOrderNo
();
}
orderType
=
prjBean
.
getOrderType
();
}
}
List
<
Bitmap
>
bitmapList
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
Set
<
Map
.
Entry
<
String
,
Bitmap
>>
bitmapSet
=
bitmapMaps
.
get
(
i
).
entrySet
();
Iterator
<
Map
.
Entry
<
String
,
Bitmap
>>
bitmapIterator
=
bitmapSet
.
iterator
();
while
(
bitmapIterator
.
hasNext
())
{
bitmapList
.
add
(
bitmapIterator
.
next
().
getValue
());
}
}
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrinterBitmapBefore
(
orderType
,
PrintConstans
.
PRINT_KITCHEN
,
prjName
,
bitmapList
);
}
}
/**
* 是否為針式打印機
*
* @param printerDeviceBean 打印機實體類
* @return true是
*/
private
boolean
isPinPrinter
(
PrinterDeviceBean
printerDeviceBean
)
{
return
(
printerDeviceBean
!=
null
&&
printerDeviceBean
.
getPrinterName
()
!=
null
&&
printerDeviceBean
.
getPrinterName
().
toLowerCase
().
contains
(
"EPSON"
.
toLowerCase
()))
&&
(
printerDeviceBean
.
getModel
()
!=
null
&&
printerDeviceBean
.
getModel
().
toLowerCase
().
contains
(
"TM-U220B"
.
toLowerCase
()));
}
private
void
updatePrjSuccess
(
String
ids
)
{
updatePrjState
(
UpdateBean
.
ALREADY_PRINT
,
ids
);
}
/**
* 打印失敗,將打印狀態改為未打印,並不是改為打印失敗,失敗是由後台判斷打印失敗次數超過最大限制之後改為打印失敗的
*
* @param ids prj的id集合
*/
private
void
updatePrjFailure
(
String
ids
)
{
updatePrjState
(
UpdateBean
.
NO_PRINT
,
ids
);
}
/**
* @param printState 打印狀態 1未打印 2打印中 3已打印
*/
private
void
updatePrjState
(
int
printState
,
String
ids
)
{
Long
time
=
null
;
if
(
printState
==
3
)
{
time
=
TimeUtils
.
getCurrentTimeInLong
();
}
List
<
UpdateBean
>
updateBeans
=
new
ArrayList
<>();
String
[]
idArrays
=
ids
.
split
(
","
);
for
(
String
id
:
idArrays
)
{
updateBeans
.
add
(
new
UpdateBean
(
id
,
printState
,
time
));
}
String
json
=
JsonUtils
.
toJson
(
updateBeans
);
Log
.
e
(
TAG
,
"修改打印狀態:"
+
json
);
RequestBody
requestBody
=
RequestBody
.
create
(
MediaType
.
parse
(
"application/json"
),
json
);
OkHttp3Utils
.
post
(
HttpsConstans
.
ROOT_SERVER_ADDRESS_FORMAL
+
"printerRecording/update"
,
requestBody
)
.
subscribeOn
(
Schedulers
.
io
())
//切换到io线程進行網絡請求
.
subscribe
(
new
Observer
<
String
>()
{
@Override
public
void
onSubscribe
(
Disposable
d
)
{
}
@Override
public
void
onNext
(
String
s
)
{
LoganManager
.
w_printer
(
TAG
,
"修改Prj打印狀態---end----: "
+
json
+
s
);
}
@Override
public
void
onError
(
Throwable
e
)
{
}
@Override
public
void
onComplete
()
{
}
});
}
@Override
public
void
onPtrReceive
(
Printer
printer
,
int
i
,
PrinterStatusInfo
printerStatusInfo
,
String
s
)
{
//針式打印回調
if
(
i
==
0
)
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
//打印成功
updatePrjSuccess
(
s
);
}
else
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"打印失敗"
),
i
);
//打印失敗
updatePrjFailure
(
s
);
}
}
}
component-print/src/main/java/com/joe/print/mvp/print/PrinterRoot.java
View file @
7e27ec13
...
@@ -50,6 +50,7 @@ import com.gingersoft.gsa.cloud.print.PrinterWriter58mm;
...
@@ -50,6 +50,7 @@ import com.gingersoft.gsa.cloud.print.PrinterWriter58mm;
import
com.gingersoft.gsa.cloud.print.bean.PrintContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrintContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrintTakeawayCheckoutContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrintTakeawayCheckoutContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrintTakeawayFormContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrintTakeawayFormContent
;
import
com.gingersoft.gsa.cloud.print.bean.UpdateBean
;
import
com.gingersoft.gsa.cloud.print.bean.base.PrintBillItem
;
import
com.gingersoft.gsa.cloud.print.bean.base.PrintBillItem
;
import
com.gingersoft.gsa.cloud.print.bean.base.PrintFoodItem
;
import
com.gingersoft.gsa.cloud.print.bean.base.PrintFoodItem
;
import
com.gingersoft.gsa.cloud.print.bean.base.PrintPayTypeItem
;
import
com.gingersoft.gsa.cloud.print.bean.base.PrintPayTypeItem
;
...
@@ -283,7 +284,7 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
...
@@ -283,7 +284,7 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
@Override
@Override
public
void
onRaiseException
(
int
code
,
String
msg
)
{
public
void
onRaiseException
(
int
code
,
String
msg
)
{
//接⼝执⾏失败时,返回的异常状态
//接⼝执⾏失败时,返回的异常状态
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ull
,
code
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ew
Exception
(
msg
)
,
code
);
LoganManager
.
w_printer
(
TAG
,
"商米onRaiseException: "
+
code
+
msg
);
LoganManager
.
w_printer
(
TAG
,
"商米onRaiseException: "
+
code
+
msg
);
}
}
...
@@ -308,7 +309,7 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
...
@@ -308,7 +309,7 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
}
else
{
}
else
{
//打印失敗
//打印失敗
listener
.
printFailure
(
"打印失敗"
);
listener
.
printFailure
(
"打印失敗"
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ull
,
i
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ew
Exception
(
UpdateBean
.
getStateByCode
(
i
))
,
i
);
}
}
}
}
...
@@ -370,6 +371,7 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
...
@@ -370,6 +371,7 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
if
(
code
==
SendResultCode
.
SEND_SUCCESS
)
{
if
(
code
==
SendResultCode
.
SEND_SUCCESS
)
{
printSuccess
();
printSuccess
();
}
else
if
(
code
==
SendResultCode
.
SEND_FAILED
)
{
}
else
if
(
code
==
SendResultCode
.
SEND_FAILED
)
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"usb打印失敗"
),
0
);
printFailure
(
"打印失敗"
);
printFailure
(
"打印失敗"
);
}
}
});
});
...
@@ -440,7 +442,6 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
...
@@ -440,7 +442,6 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
@Override
@Override
public
void
onResult
(
int
errorCode
)
{
public
void
onResult
(
int
errorCode
)
{
Log
.
e
(
"eee"
,
"打印結果:"
+
errorCode
);
switch
(
errorCode
)
{
switch
(
errorCode
)
{
case
PrintSocketHolder
.
ERROR_0
:
case
PrintSocketHolder
.
ERROR_0
:
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
...
@@ -448,25 +449,31 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
...
@@ -448,25 +449,31 @@ public abstract class PrinterRoot<T extends PrintContent> implements PrintSocket
return
;
return
;
case
PrintSocketHolder
.
ERROR_6
:
case
PrintSocketHolder
.
ERROR_6
:
LoganManager
.
w_printer
(
TAG
,
"生成打印數據失敗"
);
LoganManager
.
w_printer
(
TAG
,
"生成打印數據失敗"
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"生成打印數據失敗"
));
printFailure
(
"生成打印數據失敗"
);
printFailure
(
"生成打印數據失敗"
);
break
;
break
;
case
PrintSocketHolder
.
ERROR_7
:
case
PrintSocketHolder
.
ERROR_7
:
LoganManager
.
w_printer
(
TAG
,
"連接打印機失敗"
);
LoganManager
.
w_printer
(
TAG
,
"連接打印機失敗"
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"連接打印機失敗"
));
printFailure
(
"連接打印機失敗"
);
printFailure
(
"連接打印機失敗"
);
break
;
break
;
case
PrintSocketHolder
.
ERROR_10
:
case
PrintSocketHolder
.
ERROR_10
:
LoganManager
.
w_printer
(
TAG
,
"連接打印機失敗(写入页面数据失败),Code:"
+
PrintSocketHolder
.
ERROR_10
);
LoganManager
.
w_printer
(
TAG
,
"打印機連接成功,發送數據出現問題"
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
"打印機連接成功,發送數據出現問題"
),
errorCode
);
printFailure
(
"打印失敗,錯誤碼:"
+
errorCode
);
printFailure
(
"打印失敗,錯誤碼:"
+
errorCode
);
break
;
break
;
case
PrintSocketHolder
.
ERROR_9
:
case
PrintSocketHolder
.
ERROR_9
:
LoganManager
.
w_printer
(
TAG
,
"連接打印機失敗(必要参数不能为空)"
);
LoganManager
.
w_printer
(
TAG
,
"IP地址為空"
);
printFailure
(
"連接打印機失敗,沒有ip地址,錯誤碼:"
+
errorCode
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
Exception
(
"IP地址為空"
));
printFailure
(
"IP地址為空"
);
break
;
break
;
case
PrintSocketHolder
.
ERROR_66
:
case
PrintSocketHolder
.
ERROR_66
:
LoganManager
.
w_printer
(
TAG
,
"关闭Socket出错"
);
LoganManager
.
w_printer
(
TAG
,
"關閉Socket出錯"
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
disconnect
(
new
Exception
(
"關閉打印機連接出错"
));
break
;
default
:
break
;
break
;
}
}
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
null
,
errorCode
);
setPrintState
(
errorCode
);
setPrintState
(
errorCode
);
}
}
...
...
component-print/src/main/java/com/joe/print/mvp/print/service/PrjService.java
View file @
7e27ec13
...
@@ -59,6 +59,7 @@ import org.json.JSONObject;
...
@@ -59,6 +59,7 @@ import org.json.JSONObject;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.PrintStream
;
import
java.io.PrintStream
;
import
java.net.ConnectException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.Iterator
;
...
@@ -221,7 +222,6 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -221,7 +222,6 @@ public class PrjService extends Service implements ReceiveListener {
private
int
totalPrj
;
private
int
totalPrj
;
private
int
currentIndex
;
private
int
currentIndex
;
private
String
prjJson
=
"{\"success\":true,\"sysTime\":1613789540248,\"data\":{\"K1\":[{\"id\":71387,\"printerDeviceId\":186,\"status\":2,\"tableName\":\"堂食1\",\"orderNo\":\"0013\",\"orderTime\":2021,\"person\":1,\"number\":1,\"orderDetailsTime\":\"Feb 23, 2021 1:52:06 PM\",\"orderDetailsId\":372,\"productName\":\"N1. Mr.Arita華盛丼>得獎和牛使用定食\",\"productName2\":\"\",\"productName3\":\"\",\"parentId\":0,\"type\":3,\"createTime\":1614059526281,\"productId\":61256,\"requests\":1,\"actualPrinterDeviceId\":186,\"orderType\":1,\"isFirstSendOrder\":1,\"quantity\":21,\"memberName\":\"96761128\"}]}}"
;
private
void
newPrint
(
String
json
)
{
private
void
newPrint
(
String
json
)
{
Map
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
listMap
=
new
HashMap
<>();
Map
<
String
,
List
<
PrjBean
.
DataBean
.
Bean
>>
listMap
=
new
HashMap
<>();
...
@@ -513,10 +513,10 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -513,10 +513,10 @@ public class PrjService extends Service implements ReceiveListener {
//將打印的圖片保存到手機中
//將打印的圖片保存到手機中
hookPrinterBitmap
(
bitmapMaps
,
beans
);
hookPrinterBitmap
(
bitmapMaps
,
beans
);
EpsonPrint
mPrinter
=
EpsonPrint
.
getInstance
();
boolean
initResult
=
EpsonPrint
.
getInstance
().
initializeObject
(
this
,
this
,
errorCode
->
updatePrjState
(
errorCode
,
getPrintIds
(
bitmapMaps
)));
boolean
initResult
=
EpsonPrint
.
getInstance
().
initializeObject
(
this
,
this
,
errorCode
->
updatePrjState
(
errorCode
,
getPrintIds
(
bitmapMaps
)));
if
(!
initResult
)
{
if
(!
initResult
)
{
//初始化打印機失敗
//初始化打印機失敗
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
ConnectException
(
"初始化針式打印機失敗"
));
updatePrjState
(
UpdateBean
.
FAIL_EPSON_INIT
,
getPrintIds
(
bitmapMaps
));
updatePrjState
(
UpdateBean
.
FAIL_EPSON_INIT
,
getPrintIds
(
bitmapMaps
));
return
;
return
;
}
}
...
@@ -524,7 +524,7 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -524,7 +524,7 @@ public class PrjService extends Service implements ReceiveListener {
Log
.
d
(
"eee"
,
"針式打印機本次PRJ數量:"
+
bitmapMaps
.
size
());
Log
.
d
(
"eee"
,
"針式打印機本次PRJ數量:"
+
bitmapMaps
.
size
());
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
bitmapMaps
.
size
();
i
++)
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
mapEntry
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
for
(
Map
.
Entry
<
String
,
Bitmap
>
mapEntry
:
bitmapMaps
.
get
(
i
).
entrySet
())
{
mPrinter
.
putPrintData
(
printerDeviceBean
.
getIp
(),
mapEntry
.
getValue
(),
mapEntry
.
getKey
());
EpsonPrint
.
getInstance
()
.
putPrintData
(
printerDeviceBean
.
getIp
(),
mapEntry
.
getValue
(),
mapEntry
.
getKey
());
}
}
}
}
}
}
...
@@ -568,7 +568,7 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -568,7 +568,7 @@ public class PrjService extends Service implements ReceiveListener {
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
updatePrjSuccess
(
key
);
updatePrjSuccess
(
key
);
}
else
if
(
code
==
SendResultCode
.
SEND_FAILED
)
{
}
else
if
(
code
==
SendResultCode
.
SEND_FAILED
)
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ull
,
code
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ew
Exception
(
"發送打印數據失敗"
)
,
code
);
updatePrjFailure
(
key
);
updatePrjFailure
(
key
);
}
}
});
});
...
@@ -679,7 +679,7 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -679,7 +679,7 @@ public class PrjService extends Service implements ReceiveListener {
@Override
@Override
public
void
onRaiseException
(
int
code
,
String
msg
)
{
public
void
onRaiseException
(
int
code
,
String
msg
)
{
//接⼝执⾏失败时,返回的异常状态
//接⼝执⾏失败时,返回的异常状态
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ull
,
code
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ew
Exception
(
msg
)
,
code
);
LoganManager
.
w_printer
(
TAG
,
"商米onRaiseException: "
+
code
+
msg
);
LoganManager
.
w_printer
(
TAG
,
"商米onRaiseException: "
+
code
+
msg
);
switch
(
code
)
{
switch
(
code
)
{
case
3
:
case
3
:
...
@@ -742,8 +742,8 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -742,8 +742,8 @@ public class PrjService extends Service implements ReceiveListener {
updatePrjSuccess
(
ids
);
updatePrjSuccess
(
ids
);
}
else
{
}
else
{
//打印失敗
//打印失敗
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
UpdateBean
.
getStateByCode
(
i
)),
i
);
updatePrjState
(
i
,
ids
);
updatePrjState
(
i
,
ids
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
null
,
i
);
}
}
}
}
...
@@ -755,6 +755,7 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -755,6 +755,7 @@ public class PrjService extends Service implements ReceiveListener {
});
});
}
catch
(
RemoteException
e
)
{
}
catch
(
RemoteException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
e
,
i
);
LoganManager
.
w_printer
(
TAG
,
"N5 RemoteException :"
+
e
.
getLocalizedMessage
());
LoganManager
.
w_printer
(
TAG
,
"N5 RemoteException :"
+
e
.
getLocalizedMessage
());
updatePrjFailure
(
ids
);
updatePrjFailure
(
ids
);
}
}
...
@@ -904,7 +905,7 @@ public class PrjService extends Service implements ReceiveListener {
...
@@ -904,7 +905,7 @@ public class PrjService extends Service implements ReceiveListener {
//打印成功
//打印成功
updatePrjSuccess
(
s
);
updatePrjSuccess
(
s
);
}
else
{
}
else
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ull
,
i
);
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
n
ew
Exception
(
"打印失敗"
)
,
i
);
//打印失敗
//打印失敗
updatePrjFailure
(
s
);
updatePrjFailure
(
s
);
}
}
...
...
component-print/src/main/java/com/joe/print/mvp/ui/activity/PrintActivity.java
View file @
7e27ec13
package
com
.
joe
.
print
.
mvp
.
ui
.
activity
;
package
com
.
joe
.
print
.
mvp
.
ui
.
activity
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.DialogInterface
;
import
android.content.DialogInterface
;
import
android.content.Intent
;
import
android.content.Intent
;
import
android.graphics.Bitmap
;
import
android.graphics.Bitmap
;
...
@@ -25,12 +27,14 @@ import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
...
@@ -25,12 +27,14 @@ import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
import
com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils
;
import
com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils
;
import
com.gingersoft.gsa.cloud.database.bean.PrintCurrencyBean
;
import
com.gingersoft.gsa.cloud.database.bean.PrintCurrencyBean
;
import
com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean
;
import
com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean
;
import
com.gingersoft.gsa.cloud.database.utils.FoodModifierDaoUtils
;
import
com.gingersoft.gsa.cloud.print.PrintExecutor
;
import
com.gingersoft.gsa.cloud.print.PrintExecutor
;
import
com.gingersoft.gsa.cloud.print.PrintSocketHolder
;
import
com.gingersoft.gsa.cloud.print.PrintSocketHolder
;
import
com.gingersoft.gsa.cloud.print.bean.PrintContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrintContent
;
import
com.gingersoft.gsa.cloud.print.bean.PrjBean
;
import
com.gingersoft.gsa.cloud.print.bean.PrjBean
;
import
com.jess.arms.base.BaseActivity
;
import
com.jess.arms.base.BaseActivity
;
import
com.jess.arms.di.component.AppComponent
;
import
com.jess.arms.di.component.AppComponent
;
import
com.jess.arms.integration.AppManager
;
import
com.jess.arms.utils.ArmsUtils
;
import
com.jess.arms.utils.ArmsUtils
;
import
com.joe.print.di.component.DaggerPrintComponent
;
import
com.joe.print.di.component.DaggerPrintComponent
;
import
com.joe.print.mvp.contract.PrintContract
;
import
com.joe.print.mvp.contract.PrintContract
;
...
@@ -46,9 +50,16 @@ import com.joe.print.mvp.ui.view.PrinterLoadingDialog;
...
@@ -46,9 +50,16 @@ import com.joe.print.mvp.ui.view.PrinterLoadingDialog;
import
com.joe.print.mvp.ui.view.SelectPrintDevicePopup
;
import
com.joe.print.mvp.ui.view.SelectPrintDevicePopup
;
import
com.lxj.xpopup.XPopup
;
import
com.lxj.xpopup.XPopup
;
import
java.net.ConnectException
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
javax.inject.Inject
;
import
io.reactivex.Observable
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.functions.Consumer
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
common
.
constans
.
PrintConstans
.
PRINT_BILL
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
common
.
constans
.
PrintConstans
.
PRINT_BILL
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
common
.
constans
.
PrintConstans
.
PRINT_OTHER_CLOSING
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
common
.
constans
.
PrintConstans
.
PRINT_OTHER_CLOSING
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
common
.
constans
.
PrintConstans
.
PRINT_OTHER_ORDER
;
import
static
com
.
gingersoft
.
gsa
.
cloud
.
common
.
constans
.
PrintConstans
.
PRINT_OTHER_ORDER
;
...
@@ -76,6 +87,10 @@ import static com.jess.arms.utils.Preconditions.checkNotNull;
...
@@ -76,6 +87,10 @@ import static com.jess.arms.utils.Preconditions.checkNotNull;
*/
*/
public
class
PrintActivity
extends
BaseActivity
<
PrintPresenter
>
implements
PrintContract
.
View
,
DialogInterface
.
OnDismissListener
,
PrintListener
,
PrintSocketHolder
.
OnStateChangedListener
,
PrintExecutor
.
OnPrintResultListener
{
public
class
PrintActivity
extends
BaseActivity
<
PrintPresenter
>
implements
PrintContract
.
View
,
DialogInterface
.
OnDismissListener
,
PrintListener
,
PrintSocketHolder
.
OnStateChangedListener
,
PrintExecutor
.
OnPrintResultListener
{
@Inject
AppManager
mAppManager
;
public
final
static
int
ADD_PRINT_CODE
=
1001
;
//添加打印機回調
public
final
static
int
ADD_PRINT_CODE
=
1001
;
//添加打印機回調
public
final
static
int
FINISH
=
1003
;
//關閉頁面
public
final
static
int
FINISH
=
1003
;
//關閉頁面
public
final
static
int
ADD_PRINT_DEVICE
=
1004
;
//添加打印機
public
final
static
int
ADD_PRINT_DEVICE
=
1004
;
//添加打印機
...
@@ -104,6 +119,8 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -104,6 +119,8 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
private
PrinterLoadingDialog
printerLoadingDialog
;
private
PrinterLoadingDialog
printerLoadingDialog
;
private
boolean
printerResult
;
@Override
@Override
public
void
setupActivityComponent
(
@NonNull
AppComponent
appComponent
)
{
public
void
setupActivityComponent
(
@NonNull
AppComponent
appComponent
)
{
DaggerPrintComponent
//如找不到该类,请编译一下项目
DaggerPrintComponent
//如找不到该类,请编译一下项目
...
@@ -115,6 +132,11 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -115,6 +132,11 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
}
}
@Override
@Override
protected
void
attachBaseContext
(
Context
newBase
)
{
super
.
attachBaseContext
(
newBase
);
}
@Override
public
int
initView
(
@Nullable
Bundle
savedInstanceState
)
{
public
int
initView
(
@Nullable
Bundle
savedInstanceState
)
{
getWindow
().
addFlags
(
WindowManager
.
LayoutParams
.
FLAG_NOT_TOUCHABLE
getWindow
().
addFlags
(
WindowManager
.
LayoutParams
.
FLAG_NOT_TOUCHABLE
|
WindowManager
.
LayoutParams
.
FLAG_WATCH_OUTSIDE_TOUCH
);
|
WindowManager
.
LayoutParams
.
FLAG_WATCH_OUTSIDE_TOUCH
);
...
@@ -128,23 +150,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -128,23 +150,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
// .asLoading("加载中...");
// .asLoading("加载中...");
// loadingPopup.show();
// loadingPopup.show();
printerLoadingDialog
=
new
PrinterLoadingDialog
(
mContext
).
build
();
actionPrinter
();
printerLoadingDialog
.
show
();
callId
=
CCUtil
.
getNavigateCallId
(
this
);
//獲取打印類型,根據打印類型生成對應的bitmap
type
=
CCUtil
.
getNavigateParam
(
this
,
PrintConstans
.
PRINT_TYPE
,
PrintConstans
.
PRINT_TEST
);
//獲取打印內容
PrintContent
printContent
=
CCUtil
.
getNavigateParam
(
this
,
PrintConstans
.
PRINT_CONTENT
,
null
);
//訂單編號
mOrderNo
=
CCUtil
.
getNavigateParam
(
this
,
PrintConstans
.
PRINT_ORDER_NO
,
""
);
//根據打印類型獲取對應的執行類
printerInIt
=
PrinterRoot
.
getPrinterByType
(
type
,
printContent
);
if
(
printerInIt
!=
null
)
{
printerInIt
.
setPrintListener
(
this
);
}
//初始化打印配置
initPrintConfig
(
printContent
);
PrinterPlugins
.
setOnPrinterFlowHandler
(
new
PrinterFlowListener
()
{
PrinterPlugins
.
setOnPrinterFlowHandler
(
new
PrinterFlowListener
()
{
...
@@ -155,39 +161,86 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -155,39 +161,86 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
@Override
@Override
public
void
connectionSuccess
()
{
public
void
connectionSuccess
()
{
printerLoadingDialog
.
setStep
(
2
,
PrinterLoadingDialog
.
status_success
);
printerLoadingDialog
.
setStep
(
2
,
PrinterLoadingDialog
.
status_success
,
null
);
}
}
@Override
@Override
public
void
connectionError
(
Exception
e
)
{
public
void
connectionError
(
Exception
e
)
{
printerLoadingDialog
.
setStep
(
2
,
PrinterLoadingDialog
.
status_error
);
printerLoadingDialog
.
setStep
(
2
,
PrinterLoadingDialog
.
status_error
,
e
.
getMessage
()
);
}
}
@Override
@Override
public
void
disconnect
()
{
public
void
disconnect
(
Exception
e
)
{
printerLoadingDialog
.
setStep
(
4
,
PrinterLoadingDialog
.
status_success
);
}
}
@Override
@Override
public
void
onPrinterDataBefore
(
int
orderType
,
int
printType
,
String
printerData
,
String
printerDeviceInfo
)
{
public
void
onPrinterDataBefore
(
int
orderType
,
int
printType
,
String
printerData
,
String
printerDeviceInfo
)
{
printerLoadingDialog
.
setStep
(
1
,
PrinterLoadingDialog
.
status_
default
);
printerLoadingDialog
.
setStep
(
1
,
PrinterLoadingDialog
.
status_
success
,
null
);
}
}
@Override
@Override
public
void
onPrinterBitmapBefore
(
int
orderType
,
int
printType
,
String
directoryName
,
List
<
Bitmap
>
bitmaps
)
{
public
void
onPrinterBitmapBefore
(
int
orderType
,
int
printType
,
String
directoryName
,
List
<
Bitmap
>
bitmaps
)
{
printerLoadingDialog
.
setStep
(
1
,
PrinterLoadingDialog
.
status_success
);
printerLoadingDialog
.
setStep
(
1
,
PrinterLoadingDialog
.
status_success
,
null
);
}
}
@Override
@Override
public
void
onPrintSuccess
()
{
public
void
onPrintSuccess
()
{
printerLoadingDialog
.
setStep
(
3
,
PrinterLoadingDialog
.
status_success
);
printerResult
=
true
;
printerLoadingDialog
.
setStep
(
3
,
PrinterLoadingDialog
.
status_success
,
null
);
}
}
@Override
@Override
public
void
onPrintError
(
Exception
e
,
int
errorCode
)
{
public
void
onPrintError
(
Exception
e
,
int
errorCode
)
{
printerLoadingDialog
.
setStep
(
3
,
PrinterLoadingDialog
.
status_error
);
printerLoadingDialog
.
setStep
(
3
,
PrinterLoadingDialog
.
status_error
,
e
.
getMessage
());
}
});
}
@Override
protected
void
onNewIntent
(
Intent
intent
)
{
super
.
onNewIntent
(
intent
);
actionPrinter
();
}
private
void
actionPrinter
()
{
showPrintLoadingDialog
();
callId
=
CCUtil
.
getNavigateCallId
(
this
);
//獲取打印類型,根據打印類型生成對應的bitmap
type
=
CCUtil
.
getNavigateParam
(
this
,
PrintConstans
.
PRINT_TYPE
,
PrintConstans
.
PRINT_TEST
);
//獲取打印內容
PrintContent
printContent
=
CCUtil
.
getNavigateParam
(
this
,
PrintConstans
.
PRINT_CONTENT
,
null
);
//訂單編號
mOrderNo
=
CCUtil
.
getNavigateParam
(
this
,
PrintConstans
.
PRINT_ORDER_NO
,
""
);
//根據打印類型獲取對應的執行類
printerInIt
=
PrinterRoot
.
getPrinterByType
(
type
,
printContent
);
if
(
printerInIt
!=
null
)
{
printerInIt
.
setPrintListener
(
this
);
}
//初始化打印配置
initPrintConfig
(
printContent
);
}
private
void
showPrintLoadingDialog
()
{
if
(
printerLoadingDialog
!=
null
)
{
printerLoadingDialog
=
printerLoadingDialog
.
build
();
}
else
{
printerLoadingDialog
=
new
PrinterLoadingDialog
(
mContext
).
build
();
}
printerLoadingDialog
.
setOnCancelListener
(
new
DialogInterface
.
OnCancelListener
()
{
@Override
public
void
onCancel
(
DialogInterface
dialog
)
{
finish
();
if
(
printerResult
)
{
CC
.
sendCCResult
(
callId
,
CCResult
.
success
());
}
else
{
CC
.
sendCCResult
(
callId
,
CCResult
.
error
(
"print error"
));
}
}
}
});
});
printerLoadingDialog
.
show
();
}
}
/**
/**
...
@@ -196,6 +249,9 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -196,6 +249,9 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
private
PrinterDeviceBean
defaultPrint
;
private
PrinterDeviceBean
defaultPrint
;
private
void
initPrintConfig
(
PrintContent
printContent
)
{
private
void
initPrintConfig
(
PrintContent
printContent
)
{
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrinterDataBefore
(
type
,
type
,
GsonUtils
.
GsonString
(
printContent
),
GsonUtils
.
GsonString
(
defaultPrint
));
//獲取通用打印配置
//獲取通用打印配置
PrintCurrencyBean
printCurrencyBean
=
getCurrencyConfig
();
PrintCurrencyBean
printCurrencyBean
=
getCurrencyConfig
();
//獲取打印機列表
//獲取打印機列表
...
@@ -209,9 +265,6 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -209,9 +265,6 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
// 如果沒有最近使用的打印機,並且當前餐廳只有一台打印機,就用這一台打印機打印
// 如果沒有最近使用的打印機,並且當前餐廳只有一台打印機,就用這一台打印機打印
defaultPrint
=
mPresenter
.
getDefaultPrintInList
(
printerDeviceBeans
,
(
String
)
SPUtils
.
get
(
"defaultPrint"
,
""
));
defaultPrint
=
mPresenter
.
getDefaultPrintInList
(
printerDeviceBeans
,
(
String
)
SPUtils
.
get
(
"defaultPrint"
,
""
));
}
}
//生成餐檯打印的一些信息
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrinterDataBefore
(
type
,
type
,
GsonUtils
.
GsonString
(
printContent
),
GsonUtils
.
GsonString
(
defaultPrint
));
//如果是打印廚房單
//如果是打印廚房單
if
(
type
==
PrintConstans
.
PRINT_KITCHEN
)
{
if
(
type
==
PrintConstans
.
PRINT_KITCHEN
)
{
//設置廚房單的信息,並且獲取到這個廚房單的打印位置
//設置廚房單的信息,並且獲取到這個廚房單的打印位置
...
@@ -326,6 +379,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -326,6 +379,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
}
}
}
else
{
}
else
{
//獲取打印圖片
//獲取打印圖片
listMap
=
printerInIt
.
getPrintBitmapByCount
(
mContext
,
defaultPrint
);
listMap
=
printerInIt
.
getPrintBitmapByCount
(
mContext
,
defaultPrint
);
if
(
listMap
!=
null
)
{
if
(
listMap
!=
null
)
{
zoomBitmaps
=
listMap
.
get
(
""
);
zoomBitmaps
=
listMap
.
get
(
""
);
...
@@ -367,13 +421,18 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -367,13 +421,18 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
}
}
private
void
addPrintProgress
(
String
printState
)
{
private
void
addPrintProgress
(
String
printState
)
{
runOnUiThread
(
new
Runnable
()
{
@Override
public
void
run
()
{
printerLoadingDialog
.
setTitle
(
printState
);
printerLoadingDialog
.
setTitle
(
printState
);
}
}
});
}
@Override
@Override
public
boolean
dispatchTouchEvent
(
MotionEvent
ev
)
{
public
boolean
dispatchTouchEvent
(
MotionEvent
ev
)
{
//doSomeTing,點擊當前頁面任意地方自動關閉
//doSomeTing,點擊當前頁面任意地方自動關閉
killMyself
();
finish
();
return
true
;
return
true
;
}
}
...
@@ -383,18 +442,38 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -383,18 +442,38 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
switch
(
state
)
{
switch
(
state
)
{
case
PrintSocketHolder
.
ERROR_0
:
case
PrintSocketHolder
.
ERROR_0
:
tip
=
"打印成功"
;
tip
=
"打印成功"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintSuccess
();
break
;
break
;
case
PrintSocketHolder
.
ERROR_6
:
case
PrintSocketHolder
.
ERROR_6
:
tip
=
"生成打印數據失敗"
;
tip
=
"生成打印數據失敗"
;
break
;
break
;
case
PrintSocketHolder
.
ERROR_7
:
case
PrintSocketHolder
.
ERROR_7
:
tip
=
"連接打印機失敗"
;
tip
=
"連接打印機失敗"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
ConnectException
(
tip
));
break
;
break
;
case
PrintSocketHolder
.
ERROR_4
:
case
PrintSocketHolder
.
ERROR_4
:
tip
=
"寫入測試頁面數據失敗"
;
tip
=
"寫入數據失敗"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
tip
),
0
);
break
;
break
;
case
PrintSocketHolder
.
ERROR_9
:
case
PrintSocketHolder
.
ERROR_9
:
tip
=
"ip地址不能為空"
;
tip
=
"ip地址不能為空"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
ConnectException
(
tip
));
break
;
case
PrintSocketHolder
.
ERROR_10
:
tip
=
"打印機連接成功,獲取輸入流失敗或者發送數據出現問題"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
tip
),
0
);
break
;
case
PrintSocketHolder
.
ERROR_11
:
tip
=
"打印機沒紙了"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
tip
),
0
);
break
;
case
PrintSocketHolder
.
ERROR_12
:
tip
=
" 打印機初始化失敗,暫時只有針式打印機有"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
ConnectException
(
tip
));
break
;
case
PrintSocketHolder
.
ERROR_TIMEOUT
:
tip
=
"連接打印機超時"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
connectionError
(
new
ConnectException
(
tip
));
break
;
break
;
case
PrintSocketHolder
.
STATE_0
:
case
PrintSocketHolder
.
STATE_0
:
break
;
break
;
...
@@ -407,7 +486,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -407,7 +486,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
case
PrintSocketHolder
.
STATE_3
:
case
PrintSocketHolder
.
STATE_3
:
tip
=
"開始寫入數據"
;
tip
=
"開始寫入數據"
;
break
;
break
;
case
PrintSocketHolder
.
STATE_4
:
case
PrintSocketHolder
.
STATE_4
:
//关闭输出流
tip
=
"關閉中"
;
tip
=
"關閉中"
;
killMyself
();
killMyself
();
break
;
break
;
...
@@ -421,6 +500,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -421,6 +500,7 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
//缺紙
//缺紙
printFailure
(
"打印機缺紙"
);
printFailure
(
"打印機缺紙"
);
tip
=
"打印機缺紙"
;
tip
=
"打印機缺紙"
;
PrinterPlugins
.
getOnPrinterFlowHandler
().
onPrintError
(
new
Exception
(
tip
),
0
);
break
;
break
;
default
:
default
:
break
;
break
;
...
@@ -447,7 +527,6 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -447,7 +527,6 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
}
else
{
}
else
{
CC
.
sendCCResult
(
callId
,
CCResult
.
error
(
"print error"
));
CC
.
sendCCResult
(
callId
,
CCResult
.
error
(
"print error"
));
}
}
killMyself
();
}
}
@Override
@Override
...
@@ -499,8 +578,10 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
...
@@ -499,8 +578,10 @@ public class PrintActivity extends BaseActivity<PrintPresenter> implements Print
@Override
@Override
public
void
killMyself
()
{
public
void
killMyself
()
{
if
(
printerResult
)
{
finish
();
finish
();
}
}
}
@Override
@Override
public
void
showPrinterList
(
List
<
PrinterDeviceBean
>
deviceBeans
)
{
public
void
showPrinterList
(
List
<
PrinterDeviceBean
>
deviceBeans
)
{
...
...
component-print/src/main/java/com/joe/print/mvp/ui/view/PrinterLoadingDialog.java
View file @
7e27ec13
...
@@ -2,22 +2,31 @@ package com.joe.print.mvp.ui.view;
...
@@ -2,22 +2,31 @@ package com.joe.print.mvp.ui.view;
import
android.animation.ValueAnimator
;
import
android.animation.ValueAnimator
;
import
android.content.Context
;
import
android.content.Context
;
import
android.content.DialogInterface
;
import
android.graphics.drawable.Drawable
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.os.Looper
;
import
android.text.TextUtils
;
import
android.view.View
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.LinearLayout
;
import
android.widget.LinearLayout
;
import
android.widget.TextView
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
import
androidx.core.content.ContextCompat
;
import
com.airbnb.lottie.LottieAnimationView
;
import
com.airbnb.lottie.LottieAnimationView
;
import
com.gingersoft.gsa.cloud.pay.pos.hywebpos.constant.HywebActionStatusCode
;
import
com.gingersoft.gsa.cloud.ui.widget.dialog.BaseRetryDialog
;
import
com.gingersoft.gsa.cloud.ui.widget.dialog.BaseRetryDialog
;
import
com.joe.print.R
;
import
com.joe.print.R
;
import
com.qmuiteam.qmui.layout.QMUILinearLayout
;
import
com.qmuiteam.qmui.layout.QMUILinearLayout
;
import
com.qmuiteam.qmui.util.QMUIDisplayHelper
;
import
com.qmuiteam.qmui.util.QMUIDisplayHelper
;
import
butterknife.BindDrawable
;
import
io.reactivex.Observable
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.functions.Consumer
;
/**
/**
* 作者:ELEGANT_BIN
* 作者:ELEGANT_BIN
* 版本:1.6.0
* 版本:1.6.0
...
@@ -31,14 +40,7 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
...
@@ -31,14 +40,7 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
private
Context
mContext
;
private
Context
mContext
;
private
TextView
tv_generate_print_data
,
tv_connecting
,
tv_printing
,
tv_print_result
;
private
TextView
tv_generate_print_data
,
tv_connecting
,
tv_print_result
,
tv_error_msg
;
// @BindDrawable(R.drawable.print_grey_point)
// Drawable mGreyDrawable;
// @BindDrawable(R.drawable.print_green_point)
// Drawable mGreedDrawable;
// @BindDrawable(R.drawable.print_red_point)
// Drawable mReaDrawable;
public
static
final
byte
status_default
=
0
;
public
static
final
byte
status_default
=
0
;
public
static
final
byte
status_success
=
1
;
public
static
final
byte
status_success
=
1
;
...
@@ -52,10 +54,6 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
...
@@ -52,10 +54,6 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
super
(
context
,
R
.
style
.
MyDialogTheme2
);
super
(
context
,
R
.
style
.
MyDialogTheme2
);
mContext
=
context
;
mContext
=
context
;
mRadius
=
QMUIDisplayHelper
.
dp2px
(
mContext
,
8
);
mRadius
=
QMUIDisplayHelper
.
dp2px
(
mContext
,
8
);
drawables
=
new
Drawable
[
3
];
drawables
[
0
]
=
getDrawableByResId
(
R
.
drawable
.
print_grey_point
);
drawables
[
1
]
=
getDrawableByResId
(
R
.
drawable
.
print_green_point
);
drawables
[
2
]
=
getDrawableByResId
(
R
.
drawable
.
print_red_point
);
}
}
@Override
@Override
...
@@ -77,7 +75,7 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
...
@@ -77,7 +75,7 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
public
PrinterLoadingDialog
build
()
{
public
PrinterLoadingDialog
build
()
{
View
contentView
=
buildViews
();
View
contentView
=
buildViews
();
int
screenWidth
=
(
int
)
(
QMUIDisplayHelper
.
getScreenWidth
(
mContext
)
*
0.
9
);
int
screenWidth
=
(
int
)
(
QMUIDisplayHelper
.
getScreenWidth
(
mContext
)
*
0.
85
);
int
screenHeight
=
(
int
)
(
QMUIDisplayHelper
.
getScreenHeight
(
mContext
)
*
0.5
);
int
screenHeight
=
(
int
)
(
QMUIDisplayHelper
.
getScreenHeight
(
mContext
)
*
0.5
);
setContentView
(
contentView
,
new
LinearLayout
.
LayoutParams
(
screenWidth
,
screenHeight
));
setContentView
(
contentView
,
new
LinearLayout
.
LayoutParams
(
screenWidth
,
screenHeight
));
return
this
;
return
this
;
...
@@ -89,43 +87,117 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
...
@@ -89,43 +87,117 @@ public class PrinterLoadingDialog extends BaseRetryDialog {
LottieAnimationView
printLottieView
=
view
.
findViewById
(
R
.
id
.
lottieAnimationView
);
LottieAnimationView
printLottieView
=
view
.
findViewById
(
R
.
id
.
lottieAnimationView
);
tv_generate_print_data
=
view
.
findViewById
(
R
.
id
.
tv_generate_print_data
);
tv_generate_print_data
=
view
.
findViewById
(
R
.
id
.
tv_generate_print_data
);
tv_connecting
=
view
.
findViewById
(
R
.
id
.
tv_connecting
);
tv_connecting
=
view
.
findViewById
(
R
.
id
.
tv_connecting
);
tv_printing
=
view
.
findViewById
(
R
.
id
.
tv_printing
);
tv_print_result
=
view
.
findViewById
(
R
.
id
.
tv_print_result
);
tv_print_result
=
view
.
findViewById
(
R
.
id
.
tv_print_result
);
tv_error_msg
=
view
.
findViewById
(
R
.
id
.
tv_error_msg
);
textViews
=
new
TextView
[]{
tv_generate_print_data
,
tv_connecting
,
tv_printing
,
tv_print_result
};
ll_container
.
setRadiusAndShadow
(
mRadius
,
QMUIDisplayHelper
.
dp2px
(
mContext
,
mShadowElevationDp
),
mShadowAlpha
);
ll_container
.
setRadiusAndShadow
(
mRadius
,
QMUIDisplayHelper
.
dp2px
(
mContext
,
mShadowElevationDp
),
mShadowAlpha
);
printLottieView
.
setAnimation
(
R
.
raw
.
printer_loading3
);
printLottieView
.
setAnimation
(
R
.
raw
.
printer_loading3
);
printLottieView
.
setRepeatCount
(
ValueAnimator
.
INFINITE
);
printLottieView
.
loop
(
true
);
// printLottieView.addAnimatorUpdateListener((animation) -> {
// printLottieView.addAnimatorUpdateListener((animation) -> {
// // Do something.动画状态监听回调
// // Do something.动画状态监听回调
//
// });
// });
printLottieView
.
playAnimation
();
//播放动画
printLottieView
.
playAnimation
();
//播放动画
// //progress范围0~1f,设置动画进度
// printLottieView.setProgress(0.5f);
// // 自定义动画时长,此处利用ValueAnimator值动画来实时更新AnimationView的进度来达到控制动画时长。
// ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(500);
// animator.start();//启动动画
return
view
;
return
view
;
}
}
private
Drawable
[]
drawables
;
public
void
setStep
(
int
step
,
int
status
,
String
errorMsg
)
{
private
TextView
[]
textViews
;
tv_generate_print_data
.
post
(
new
Runnable
()
{
@Override
public
void
setStep
(
int
step
,
int
status
)
{
public
void
run
()
{
tv_generate_print_data
.
post
(()
->
setCompoundDrawableByStatus
(
status
,
textViews
[
step
-
1
]));
if
(!
TextUtils
.
isEmpty
(
errorMsg
))
{
tv_error_msg
.
setText
(
errorMsg
);
tv_error_msg
.
setVisibility
(
View
.
VISIBLE
);
}
else
{
tv_error_msg
.
setVisibility
(
View
.
GONE
);
}
switch
(
step
)
{
case
1
:
if
(
status
==
PrinterLoadingDialog
.
status_success
)
{
tv_generate_print_data
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_green_point
),
null
,
null
);
}
else
if
(
status
==
PrinterLoadingDialog
.
status_error
)
{
tv_generate_print_data
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_red_point
),
null
,
null
);
}
else
{
tv_generate_print_data
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_grey_point
),
null
,
null
);
}
break
;
case
2
:
tv_generate_print_data
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_green_point
),
null
,
null
);
if
(
status
==
PrinterLoadingDialog
.
status_success
)
{
tv_connecting
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_green_point
),
null
,
null
);
}
else
if
(
status
==
PrinterLoadingDialog
.
status_error
)
{
tv_connecting
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_red_point
),
null
,
null
);
}
else
{
tv_connecting
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_grey_point
),
null
,
null
);
}
break
;
case
3
:
if
(
status
==
PrinterLoadingDialog
.
status_success
)
{
tv_print_result
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_green_point
),
null
,
null
);
}
else
if
(
status
==
PrinterLoadingDialog
.
status_error
)
{
tv_print_result
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_red_point
),
null
,
null
);
}
else
{
tv_print_result
.
setCompoundDrawables
(
null
,
getDrawableByResId
(
R
.
drawable
.
print_grey_point
),
null
,
null
);
}
break
;
default
:
break
;
}
setStatusResult
(
step
,
status
);
}
});
}
}
private
void
setCompoundDrawableByStatus
(
int
status
,
TextView
textView
)
{
private
void
setStatusResult
(
int
step
,
int
status
)
{
textView
.
setCompoundDrawablesWithIntrinsicBounds
(
textView
.
getCompoundDrawables
()[
0
],
drawables
[
status
],
textView
.
getCompoundDrawables
()[
2
],
textView
.
getCompoundDrawables
()[
0
]);
switch
(
step
)
{
case
2
:
tv_generate_print_data
.
setText
(
"生成成功"
);
if
(
status
==
PrinterLoadingDialog
.
status_success
)
{
tv_connecting
.
setText
(
"連接成功"
);
}
else
if
(
status
==
PrinterLoadingDialog
.
status_error
)
{
tv_connecting
.
setText
(
"連接失敗"
);
}
else
{
tv_connecting
.
setText
(
"連接中"
);
}
break
;
case
3
:
if
(
status
==
PrinterLoadingDialog
.
status_success
)
{
tv_connecting
.
setText
(
"打印成功"
);
}
else
if
(
status
==
PrinterLoadingDialog
.
status_error
)
{
tv_connecting
.
setText
(
"打印失敗"
);
}
else
{
tv_connecting
.
setText
(
"打印結果"
);
}
break
;
default
:
break
;
}
}
}
private
Drawable
getDrawableByResId
(
int
resId
)
{
private
Drawable
getDrawableByResId
(
int
resId
)
{
return
ContextCompat
.
getDrawable
(
mContext
,
resId
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
Drawable
drawable
=
mContext
.
getDrawable
(
resId
);
drawable
.
setBounds
(
0
,
0
,
drawable
.
getMinimumWidth
(),
drawable
.
getMinimumHeight
());
return
drawable
;
}
Drawable
drawable
=
mContext
.
getResources
().
getDrawable
(
resId
);
drawable
.
setBounds
(
0
,
0
,
drawable
.
getMinimumWidth
(),
drawable
.
getMinimumHeight
());
return
drawable
;
}
}
protected
int
getContentViewLayoutId
()
{
protected
int
getContentViewLayoutId
()
{
return
R
.
layout
.
print_dialog_loading
;
return
R
.
layout
.
print_dialog_loading
;
}
}
private
OnClickListener
onClickListener
;
public
void
setOnClickListener
(
OnClickListener
onClickListener
)
{
this
.
onClickListener
=
onClickListener
;
}
public
interface
OnClickListener
{
// void onItemClick(FoodReason item, int position, int deleteNumber);
}
}
}
component-print/src/main/res/layout/print_dialog_loading.xml
View file @
7e27ec13
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
<com.airbnb.lottie.LottieAnimationView
<com.airbnb.lottie.LottieAnimationView
android:id=
"@+id/lottieAnimationView"
android:id=
"@+id/lottieAnimationView"
android:layout_width=
"@dimen/dp_1
5
0"
android:layout_width=
"@dimen/dp_1
8
0"
android:layout_height=
"@dimen/dp_1
5
0"
android:layout_height=
"@dimen/dp_1
8
0"
android:layout_gravity=
"center_horizontal"
android:layout_gravity=
"center_horizontal"
app:lottie_autoPlay=
"true"
app:lottie_autoPlay=
"true"
app:lottie_loop=
"true"
/>
app:lottie_loop=
"true"
/>
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
android:id=
"@+id/tv_generate_print_data"
android:id=
"@+id/tv_generate_print_data"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:drawableTop=
"@drawable/print_gre
y
_point"
android:drawableTop=
"@drawable/print_gre
en
_point"
android:text=
"生成打印數據"
android:text=
"生成打印數據"
android:textColor=
"@color/black"
android:textColor=
"@color/black"
android:textSize=
"@dimen/sp_10"
/>
android:textSize=
"@dimen/sp_10"
/>
...
@@ -53,28 +53,23 @@
...
@@ -53,28 +53,23 @@
android:background=
"@color/black"
/>
android:background=
"@color/black"
/>
<TextView
<TextView
android:id=
"@+id/tv_print
ing
"
android:id=
"@+id/tv_print
_result
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:drawableTop=
"@drawable/print_grey_point"
android:drawableTop=
"@drawable/print_grey_point"
android:text=
"
打印中
"
android:text=
"
結果
"
android:textColor=
"@color/black"
android:textColor=
"@color/black"
android:textSize=
"@dimen/sp_10"
/>
android:textSize=
"@dimen/sp_10"
/>
</LinearLayout>
<View
android:layout_width=
"@dimen/dp_50"
android:layout_height=
"1px"
android:background=
"@color/black"
/>
<TextView
<TextView
android:id=
"@+id/tv_print_result
"
android:id=
"@+id/tv_error_msg
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:drawableTop=
"@drawable/print_grey_point"
android:layout_marginTop=
"@dimen/dp_10"
android:text=
"結果"
android:textColor=
"@color/red"
android:textColor=
"@color/black"
android:textSize=
"@dimen/font_small"
android:textSize=
"@dimen/sp_10"
/>
android:text=
"連接打印機超時"
/>
</LinearLayout>
</com.qmuiteam.qmui.layout.QMUILinearLayout>
</com.qmuiteam.qmui.layout.QMUILinearLayout>
\ No newline at end of file
component-print/src/main/res/raw/printer_loading.json
deleted
100644 → 0
View file @
d315d8ac
This source diff could not be displayed because it is too large. You can
view the blob
instead.
component-print/src/main/res/raw/printer_loading2.json
deleted
100644 → 0
View file @
d315d8ac
{
"v"
:
"5.5.7"
,
"meta"
:
{
"g"
:
"LottieFiles AE 0.1.20"
,
"a"
:
""
,
"k"
:
""
,
"d"
:
""
,
"tc"
:
"#FFFFFF"
},
"fr"
:
60
,
"ip"
:
0
,
"op"
:
70
,
"w"
:
1920
,
"h"
:
1080
,
"nm"
:
"Printer1"
,
"ddd"
:
0
,
"assets"
:
[
{
"id"
:
"image_0"
,
"w"
:
971
,
"h"
:
803
,
"u"
:
""
,
"p"
:
"data:image/png;base64,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"
,
"e"
:
1
},
{
"id"
:
"image_1"
,
"w"
:
511
,
"h"
:
330
,
"u"
:
""
,
"p"
:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAf8AAAFKCAYAAAAT9lZ4AAAPIklEQVR4Xu3YsVVbSxhG0Rk1ArlxbByBm8Ch3QmiHKkKE0mOJdczXhKE6uDs18G3/7k65s39v79/hv8IECBAgACBhMDLl2/Pc38+rsRaIwkQIECAAIHx8vA4xd9DIECAAAECIQHxDx3bVAIECBAgcBEQf++AAAECBAjEBMQ/dnBzCRAgQICA+HsDBAgQIEAgJiD+sYObS4AAAQIExN8bIECAAAECMQHxjx3cXAIECBAgIP7eAAECBAgQiAmIf+zg5hIgQIAAAfH3BggQIECAQExA/GMHN5cAAQIECIi/N0CAAAECBGIC4h87uLkECBAgQED8vQECBAgQIBATEP/Ywc0lQIAAAQLi7w0QIECAAIGYgPjHDm4uAQIECBAQf2+AAAECBAjEBMQ/dnBzCRAgQICA+HsDBAgQIEAgJiD+sYObS4AAAQIExN8bIECAAAECMQHxjx3cXAIECBAgIP7eAAECBAgQiAmIf+zg5hIgQIAAAfH3BggQIECAQExA/GMHN5cAAQIECIi/N0CAAAECBGIC4h87uLkECBAgQED8vQECBAgQIBATEP/Ywc0lQIAAAQLi7w0QIECAAIGYgPjHDm4uAQIECBAQf2+AAAECBAjEBMQ/dnBzCRAgQICA+HsDBAgQIEAgJiD+sYObS4AAAQIExN8bIECAAAECMQHxjx3cXAIECBAgIP7eAAECBAgQiAmIf+zg5hIgQIAAAfH3BggQIECAQExA/GMHN5cAAQIECIi/N0CAAAECBGIC4h87uLkECBAgQED8vQECBAgQIBATEP/Ywc0lQIAAAQLi7w0QIECAAIGYgPjHDm4uAQIECBAQf2+AAAECBAjEBMQ/dnBzCRAgQICA+HsDBAgQIEAgJiD+sYObS4AAAQIExN8bIECAAAECMQHxjx3cXAIECBAgIP7eAAECBAgQiAmIf+zg5hIgQIAAAfH3BggQIECAQExA/GMHN5cAAQIECIi/N0CAAAECBGIC4h87uLkECBAgQKAd/znfPQECBAgQCAmsdT/GuAstvjk1Hf/L+PoDsJ8AAQIlgd3psJ1zvpY239oq/vUXYD8BAgRCAuL/cWzxDz16UwkQIFAXEH/xv/7Lp/4h2E+AAIGSgPiLv/iXvnhbCRAgMMYQf/EXfz8FBAgQiAmIv/iLf+yjN5cAAQLiL/7i73eAAAECMQHxF3/xj3305hIgQED8xV/8/Q4QIEAgJiD+4i/+sY/eXAIECIi/+Iu/3wECBAjEBMRf/MU/9tGbS4AAAfEXf/H3O0CAAIGYgPiLv/jHPnpzCRAgIP7iL/5+BwgQIBATEH/xF//YR28uAQIExF/8xd/vAAECBGIC4i/+4h/76M0lQICA+Iu/+PsdIECAQExA/MVf/GMfvbkECBAQf/EXf78DBAgQiAmIv/iLf+yjN5cAAQLiL/6+AgIECBAgkBR4eXicc38+ruR6owkQIECAQFBA/INHN5kAAQIE2gLi376/9QQIECAQFBD/4NFNJkCAAIG2gPi37289AQIECAQFxD94dJMJECBAoC0g/u37W0+AAAECQQHxDx7dZAIECBBoC4h/+/7WEyBAgEBQQPyDRzeZAAECBNoC4t++v/UECBAgEBQQ/+DRTSZAgACBtoD4t+9vPQECBAgEBcQ/eHSTCRAgQKAtIP7t+1tPgAABAkEB8Q8e3WQCBAgQaAuIf/v+1hMgQIBAUED8g0c3mQABAgTaAuLfvr/1BAgQIBAUEP/g0U0mQIAAgbaA+Lfvbz0BAgQIBAXEP3h0kwkQIECgLSD+7ftbT4AAAQJBAfEPHt1kAgQIEGgLiH/7/tYTIECAQFBA/INHN5kAAQIE2gLi376/9QQIECAQFBD/4NFNJkCAAIG2gPi37289AQIECAQFxD94dJMJECBAoC0g/u37W0+AAAECQQHxDx7dZAIECBBoC4h/+/7WEyBAgEBQQPyDRzeZAAECBNoC4t++v/UECBAgEBQQ/+DRTSZAgACBtoD4t+9vPQECBAgEBcQ/eHSTCRAgQKAtIP7t+1tPgAABAkEB8Q8e3WQCBAgQaAuIf/v+1hMgQIBAUED8g0c3mQABAgTaAuLfvr/1BAgQIBAUEP/g0U0mQIAAgbaA+Lfvbz0BAgQIBAXEP3h0kwkQIECgLSD+7ftbT4AAAQJBAfEPHt1kAgQIEGgLiH/7/tYTIECAQFCgHf8534M3N5kAAQJdgbXuxxh3XYCP5en4X8bXH4D9BAgQKAnsToftnPO1tPnWVvGvvwD7CRAgEBIQf3/5X/+3R+jNm0qAAIG8gPiLv/jnfwYAECBQExB/8Rf/2ldvLwECeQHxF3/xz/8MACBAoCYg/uIv/rWv3l4CBPIC4i/+4p//GQBAgEBNQPzFX/xrX729BAjkBcRf/MU//zMAgACBmoD4i7/41756ewkQyAuIv/iLf/5nAAABAjUB8Rd/8a999fYSIJAXEH/xF//8zwAAAgRqAuIv/uJf++rtJUAgLyD+4i/++Z8BAAQI1ATEX/zFv/bV20uAQF5A/MVf/PM/AwAIEKgJiL/4i3/tq7eXAIG8gPiLv/jnfwYAECBQExB/8Rf/2ldvLwECeQHxF3/xz/8MACBAoCYg/uI/5lo/ag/fXgIECKQF5vi9xvyVNhjj+sfv3J+Pqw5hPwECBAgQqAiIf+XSdhIgQIAAgU8B8fcUCBAgQIBATED8Ywc3lwABAgQIiL83QIAAAQIEYgLiHzu4uQQIECBAQPy9AQIECBAgEBMQ/9jBzSVAgAABAuLvDRAgQIAAgZiA+McObi4BAgQIEBB/b4AAAQIECMQExD92cHMJECBAgID4ewMECBAgQCAmIP6xg5tLgAABAgTE3xsgQIAAAQIxAfGPHdxcAgQIECAg/t4AAQIECBCICYh/7ODmEiBAgAAB8fcGCBAgQIBATED8Ywc3lwABAgQIiL83QIAAAQIEYgLiHzu4uQQIECBAQPy9AQIECBAgEBMQ/9jBzSVAgAABAuLvDRAgQIAAgZiA+McObi4BAgQIEBB/b4AAAQIECMQExD92cHMJECBAgID4ewMECBAgQCAmIP6xg5tLgAABAgTE3xsgQIAAAQIxAfGPHdxcAgQIECAg/t4AAQIECBCICYh/7ODmEiBAgAAB8fcGCBAgQIBATED8Ywc3lwABAgQIiL83QIAAAQIEYgLiHzu4uQQIECBAQPy9AQIECBAgEBMQ/9jBzSVAgAABAuLvDRAgQIAAgZiA+McObi4BAgQIEBB/b4AAAQIECMQExD92cHMJECBAgID4ewMECBAgQCAmIP6xg5tLgAABAgTE3xsgQIAAAQIxAfGPHdxcAgQIECAg/t4AAQIECBCICYh/7ODmEiBAgACBdPzXWm+eAAECBAh0BOZm8zzWeuosvr00Hf/L+PoDsJ8AAQIlgd3psJ1zvpY239oq/vUXYD8BAgRCAuL/cWzxDz16UwkQIFAXEH/xv/7Lp/4h2E+AAIGSgPiLv/iXvnhbCRAgMMYQf/EXfz8FBAgQiAmIv/iLf+yjN5cAAQLiL/7i73eAAAECMQHxF3/xj3305hIgQED8xV/8/Q4QIEAgJiD+4i/+sY/eXAIECIi/+Iu/3wECBAjEBMRf/MU/9tGbS4AAAfEXf/H3O0CAAIGYgPiLv/jHPnpzCRAgIP7iL/5+BwgQIBATEH/xF//YR28uAQIExF/8xd/vAAECBGIC4i/+4h/76M0lQICA+Iu/+PsdIECAQExA/MVf/GMfvbkECBAQf/EXf78DBAgQiAmIv/iPtdZb7N2bS4AAgbTA3Gyex1pPaYQxrn/8zv35uOoQ9hMgQIAAgYqA+FcubScBAgQIEPgUEH9PgQABAgQIxATEP3ZwcwkQIECAgPh7AwQIECBAICYg/rGDm0uAAAECBMTfGyBAgAABAjEB8Y8d3FwCBAgQICD+3gABAgQIEIgJiH/s4OYSIECAAAHx9wYIECBAgEBMQPxjBzeXAAECBAiIvzdAgAABAgRiAuIfO7i5BAgQIEBA/L0BAgQIECAQExD/2MHNJUCAAAEC4u8NECBAgACBmID4xw5uLgECBAgQEH9vgAABAgQIxATEP3ZwcwkQIECAgPh7AwQIECBAICYg/rGDm0uAAAECBMTfGyBAgAABAjEB8Y8d3FwCBAgQICD+3gABAgQIEIgJiH/s4OYSIECAAAHx9wYIECBAgEBMQPxjBzeXAAECBAiIvzdAgAABAgRiAuIfO7i5BAgQIEBA/L0BAgQIECAQExD/2MHNJUCAAAEC4u8NECBAgACBmID4xw5uLgECBAgQEH9vgAABAgQIxATEP3ZwcwkQIECAgPh7AwQIECBAICYg/rGDm0uAAAECBMTfGyBAgAABAjEB8Y8d3FwCBAgQICD+3gABAgQIEIgJiH/s4OYSIECAAAHx9wYIECBAgEBMQPxjBzeXAAECBAiIvzdAgAABAgRiAuIfO7i5BAgQIEBA/L0BAgQIECAQExD/2MHNJUCAAAEC4u8NECBAgACBmID4xw5uLgECBAgQEH9vgAABAgQIxATEP3ZwcwkQIECAgPh7AwQIECBAICYg/rGDm0uAAAECBMTfGyBAgAABAjEB8Y8d3FwCBAgQICD+3gABAgQIEIgJiH/s4OYSIECAAAHx9wYIECBAgEBMQPxjBzeXAAECBAiIvzdAgAABAgRiAuIfO7i5BAgQIEBA/L0BAgQIECAQExD/2MHNJUCAAAEC4u8NECBAgACBmID4xw5uLgECBAgQEH9vgAABAgQIxATEP3ZwcwkQIECAgPh7AwQIECBAICYg/rGDm0uAAAECBMTfGyBAgAABAjEB8Y8d3FwCBAgQICD+3gABAgQIEIgJiH/s4OYSIECAAAHx9wYIECBAgEBMQPxjBzeXAAECBAiIvzdAgAABAgRiAuIfO7i5BAgQIEBA/L0BAgQIECAQExD/2MHNJUCAAAEC4u8NECBAgACBmID4xw5uLgECBAgQEH9vgAABAgQIxATEP3ZwcwkQIECAgPh7AwQIECBAICYg/rGDm0uAAAECBMTfGyBAgAABAjEB8Y8d3FwCBAgQICD+3gABAgQIEIgJiH/s4OYSIECAAAHx9wYIECBAgEBMQPxjBzeXAAECBAiIvzdAgAABAgRiAtf4706HbWy3uQQIECBAICvw8+v37X/26Uult6gX6wAAAABJRU5ErkJggg=="
,
"e"
:
1
},
{
"id"
:
"image_2"
,
"w"
:
511
,
"h"
:
260
,
"u"
:
""
,
"p"
:
"data:image/png;base64,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"
,
"e"
:
1
},
{
"id"
:
"comp_0"
,
"layers"
:
[
{
"ddd"
:
0
,
"ind"
:
1
,
"ty"
:
4
,
"nm"
:
"Layer 2 Outlines"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
0
,
"k"
:
[
982.613
,
813.599
,
0
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
27.446
,
27.451
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"shapes"
:
[
{
"ty"
:
"gr"
,
"it"
:
[
{
"ind"
:
0
,
"ty"
:
"sh"
,
"ix"
:
1
,
"ks"
:
{
"a"
:
0
,
"k"
:
{
"i"
:
[
[
0
,
-15.021
],
[
-15.021
,
0
],
[
0
,
15.024
],
[
15.019
,
0
]
],
"o"
:
[
[
0
,
15.024
],
[
15.019
,
0
],
[
0
,
-15.021
],
[
-15.021
,
0
]
],
"v"
:
[
[
-27.196
,
-0.014
],
[
-0.016
,
27.201
],
[
27.196
,
-0.014
],
[
-0.016
,
-27.201
]
],
"c"
:
true
},
"ix"
:
2
},
"nm"
:
"Path 1"
,
"mn"
:
"ADBE Vector Shape - Group"
,
"hd"
:
false
},
{
"ty"
:
"fl"
,
"c"
:
{
"a"
:
1
,
"k"
:
[
{
"i"
:
{
"x"
:
[
0.667
],
"y"
:
[
1
]
},
"o"
:
{
"x"
:
[
0.333
],
"y"
:
[
0
]
},
"t"
:
0
,
"s"
:
[
0.239215686275
,
0.901960784314
,
0.713725490196
,
1
]
},
{
"i"
:
{
"x"
:
[
0.667
],
"y"
:
[
1
]
},
"o"
:
{
"x"
:
[
0.333
],
"y"
:
[
0
]
},
"t"
:
30
,
"s"
:
[
1
,
1
,
1
,
1
]
},
{
"t"
:
60
,
"s"
:
[
0.239215686917
,
0.901960790157
,
0.713725507259
,
1
]
}
],
"ix"
:
4
},
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
5
},
"r"
:
1
,
"bm"
:
0
,
"nm"
:
"Fill 1"
,
"mn"
:
"ADBE Vector Graphic - Fill"
,
"hd"
:
false
},
{
"ty"
:
"tr"
,
"p"
:
{
"a"
:
0
,
"k"
:
[
27.446
,
27.451
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
0
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
],
"ix"
:
3
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
6
},
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
7
},
"sk"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
4
},
"sa"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
5
},
"nm"
:
"Transform"
}
],
"nm"
:
"Group 1"
,
"np"
:
2
,
"cix"
:
2
,
"bm"
:
0
,
"ix"
:
1
,
"mn"
:
"ADBE Vector Group"
,
"hd"
:
false
}
],
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
},
{
"ddd"
:
0
,
"ind"
:
2
,
"ty"
:
4
,
"nm"
:
"Layer 3 Outlines"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
0
,
"k"
:
[
982.613
,
737.809
,
0
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
27.446
,
27.455
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"shapes"
:
[
{
"ty"
:
"gr"
,
"it"
:
[
{
"ind"
:
0
,
"ty"
:
"sh"
,
"ix"
:
1
,
"ks"
:
{
"a"
:
0
,
"k"
:
{
"i"
:
[
[
0
,
-15.037
],
[
-15.021
,
0
],
[
0
,
15.008
],
[
15.019
,
0
]
],
"o"
:
[
[
0
,
15.008
],
[
15.019
,
0
],
[
0
,
-15.037
],
[
-15.021
,
0
]
],
"v"
:
[
[
-27.196
,
0.013
],
[
-0.016
,
27.205
],
[
27.196
,
0.013
],
[
-0.016
,
-27.205
]
],
"c"
:
true
},
"ix"
:
2
},
"nm"
:
"Path 1"
,
"mn"
:
"ADBE Vector Shape - Group"
,
"hd"
:
false
},
{
"ty"
:
"fl"
,
"c"
:
{
"a"
:
1
,
"k"
:
[
{
"i"
:
{
"x"
:
[
0.667
],
"y"
:
[
1
]
},
"o"
:
{
"x"
:
[
0.333
],
"y"
:
[
0
]
},
"t"
:
0
,
"s"
:
[
1
,
1
,
1
,
1
]
},
{
"i"
:
{
"x"
:
[
0.667
],
"y"
:
[
1
]
},
"o"
:
{
"x"
:
[
0.333
],
"y"
:
[
0
]
},
"t"
:
30
,
"s"
:
[
0.241020619869
,
0.901176571846
,
0.712560653687
,
1
]
},
{
"t"
:
60
,
"s"
:
[
1
,
1
,
1
,
1
]
}
],
"ix"
:
4
},
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
5
},
"r"
:
1
,
"bm"
:
0
,
"nm"
:
"Fill 1"
,
"mn"
:
"ADBE Vector Graphic - Fill"
,
"hd"
:
false
},
{
"ty"
:
"tr"
,
"p"
:
{
"a"
:
0
,
"k"
:
[
27.446
,
27.455
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
0
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
],
"ix"
:
3
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
6
},
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
7
},
"sk"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
4
},
"sa"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
5
},
"nm"
:
"Transform"
}
],
"nm"
:
"Group 1"
,
"np"
:
2
,
"cix"
:
2
,
"bm"
:
0
,
"ix"
:
1
,
"mn"
:
"ADBE Vector Group"
,
"hd"
:
false
}
],
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
},
{
"ddd"
:
0
,
"ind"
:
3
,
"ty"
:
2
,
"nm"
:
"MainPRinter"
,
"refId"
:
"image_0"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
0
,
"k"
:
[
561
,
529.497
,
0
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
485.229
,
401.141
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
},
{
"ddd"
:
0
,
"ind"
:
4
,
"ty"
:
2
,
"nm"
:
"Layer 5"
,
"refId"
:
"image_1"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
1
,
"k"
:
[
{
"i"
:
{
"x"
:
0.833
,
"y"
:
0.833
},
"o"
:
{
"x"
:
0.167
,
"y"
:
0.167
},
"t"
:
25
,
"s"
:
[
560.992
,
555.489
,
0
],
"to"
:
[
0
,
51
,
0
],
"ti"
:
[
0
,
-51
,
0
]
},
{
"t"
:
55
,
"s"
:
[
560.992
,
861.489
,
0
]
}
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
255.107
,
164.761
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"ef"
:
[
{
"ty"
:
21
,
"nm"
:
"Fill"
,
"np"
:
9
,
"mn"
:
"ADBE Fill"
,
"ix"
:
1
,
"en"
:
1
,
"ef"
:
[
{
"ty"
:
10
,
"nm"
:
"Fill Mask"
,
"mn"
:
"ADBE Fill-0001"
,
"ix"
:
1
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
1
}
},
{
"ty"
:
7
,
"nm"
:
"All Masks"
,
"mn"
:
"ADBE Fill-0007"
,
"ix"
:
2
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
2
}
},
{
"ty"
:
2
,
"nm"
:
"Color"
,
"mn"
:
"ADBE Fill-0002"
,
"ix"
:
3
,
"v"
:
{
"a"
:
0
,
"k"
:
[
0.239215686917
,
0.901960790157
,
0.713725507259
,
1
],
"ix"
:
3
}
},
{
"ty"
:
7
,
"nm"
:
"Invert"
,
"mn"
:
"ADBE Fill-0006"
,
"ix"
:
4
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
4
}
},
{
"ty"
:
0
,
"nm"
:
"Horizontal Feather"
,
"mn"
:
"ADBE Fill-0003"
,
"ix"
:
5
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
5
}
},
{
"ty"
:
0
,
"nm"
:
"Vertical Feather"
,
"mn"
:
"ADBE Fill-0004"
,
"ix"
:
6
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
6
}
},
{
"ty"
:
0
,
"nm"
:
"Opacity"
,
"mn"
:
"ADBE Fill-0005"
,
"ix"
:
7
,
"v"
:
{
"a"
:
0
,
"k"
:
1
,
"ix"
:
7
}
}
]
}
],
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
},
{
"ddd"
:
0
,
"ind"
:
5
,
"ty"
:
2
,
"nm"
:
"Layer 6"
,
"refId"
:
"image_2"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
1
,
"k"
:
[
{
"i"
:
{
"x"
:
0.667
,
"y"
:
1
},
"o"
:
{
"x"
:
0.333
,
"y"
:
0
},
"t"
:
0
,
"s"
:
[
560.991
,
-72.462
,
0
],
"to"
:
[
0
,
45.667
,
0
],
"ti"
:
[
0
,
-45.667
,
0
]
},
{
"t"
:
31
,
"s"
:
[
560.991
,
201.538
,
0
]
}
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
255.107
,
129.788
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"ef"
:
[
{
"ty"
:
21
,
"nm"
:
"Fill"
,
"np"
:
9
,
"mn"
:
"ADBE Fill"
,
"ix"
:
1
,
"en"
:
1
,
"ef"
:
[
{
"ty"
:
10
,
"nm"
:
"Fill Mask"
,
"mn"
:
"ADBE Fill-0001"
,
"ix"
:
1
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
1
}
},
{
"ty"
:
7
,
"nm"
:
"All Masks"
,
"mn"
:
"ADBE Fill-0007"
,
"ix"
:
2
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
2
}
},
{
"ty"
:
2
,
"nm"
:
"Color"
,
"mn"
:
"ADBE Fill-0002"
,
"ix"
:
3
,
"v"
:
{
"a"
:
0
,
"k"
:
[
0.239215686917
,
0.901960790157
,
0.713725507259
,
1
],
"ix"
:
3
}
},
{
"ty"
:
7
,
"nm"
:
"Invert"
,
"mn"
:
"ADBE Fill-0006"
,
"ix"
:
4
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
4
}
},
{
"ty"
:
0
,
"nm"
:
"Horizontal Feather"
,
"mn"
:
"ADBE Fill-0003"
,
"ix"
:
5
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
5
}
},
{
"ty"
:
0
,
"nm"
:
"Vertical Feather"
,
"mn"
:
"ADBE Fill-0004"
,
"ix"
:
6
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
6
}
},
{
"ty"
:
0
,
"nm"
:
"Opacity"
,
"mn"
:
"ADBE Fill-0005"
,
"ix"
:
7
,
"v"
:
{
"a"
:
0
,
"k"
:
1
,
"ix"
:
7
}
}
]
}
],
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
},
{
"ddd"
:
0
,
"ind"
:
6
,
"ty"
:
2
,
"nm"
:
"Layer 4"
,
"refId"
:
"image_2"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
1
,
"k"
:
[
{
"i"
:
{
"x"
:
0.667
,
"y"
:
1
},
"o"
:
{
"x"
:
0.333
,
"y"
:
0
},
"t"
:
0
,
"s"
:
[
560.991
,
201.538
,
0
],
"to"
:
[
0
,
48.833
,
0
],
"ti"
:
[
0
,
-48.833
,
0
]
},
{
"t"
:
31
,
"s"
:
[
560.991
,
494.538
,
0
]
}
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
255.107
,
129.788
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"ef"
:
[
{
"ty"
:
21
,
"nm"
:
"Fill"
,
"np"
:
9
,
"mn"
:
"ADBE Fill"
,
"ix"
:
1
,
"en"
:
1
,
"ef"
:
[
{
"ty"
:
10
,
"nm"
:
"Fill Mask"
,
"mn"
:
"ADBE Fill-0001"
,
"ix"
:
1
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
1
}
},
{
"ty"
:
7
,
"nm"
:
"All Masks"
,
"mn"
:
"ADBE Fill-0007"
,
"ix"
:
2
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
2
}
},
{
"ty"
:
2
,
"nm"
:
"Color"
,
"mn"
:
"ADBE Fill-0002"
,
"ix"
:
3
,
"v"
:
{
"a"
:
0
,
"k"
:
[
0.239215686917
,
0.901960790157
,
0.713725507259
,
1
],
"ix"
:
3
}
},
{
"ty"
:
7
,
"nm"
:
"Invert"
,
"mn"
:
"ADBE Fill-0006"
,
"ix"
:
4
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
4
}
},
{
"ty"
:
0
,
"nm"
:
"Horizontal Feather"
,
"mn"
:
"ADBE Fill-0003"
,
"ix"
:
5
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
5
}
},
{
"ty"
:
0
,
"nm"
:
"Vertical Feather"
,
"mn"
:
"ADBE Fill-0004"
,
"ix"
:
6
,
"v"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
6
}
},
{
"ty"
:
0
,
"nm"
:
"Opacity"
,
"mn"
:
"ADBE Fill-0005"
,
"ix"
:
7
,
"v"
:
{
"a"
:
0
,
"k"
:
1
,
"ix"
:
7
}
}
]
}
],
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
}
]
}
],
"layers"
:
[
{
"ddd"
:
0
,
"ind"
:
1
,
"ty"
:
0
,
"nm"
:
"5572 [Converted]"
,
"refId"
:
"comp_0"
,
"sr"
:
1
,
"ks"
:
{
"o"
:
{
"a"
:
0
,
"k"
:
100
,
"ix"
:
11
},
"r"
:
{
"a"
:
0
,
"k"
:
0
,
"ix"
:
10
},
"p"
:
{
"a"
:
0
,
"k"
:
[
960
,
540
,
0
],
"ix"
:
2
},
"a"
:
{
"a"
:
0
,
"k"
:
[
561
,
561
,
0
],
"ix"
:
1
},
"s"
:
{
"a"
:
0
,
"k"
:
[
100
,
100
,
100
],
"ix"
:
6
}
},
"ao"
:
0
,
"w"
:
1122
,
"h"
:
1122
,
"ip"
:
0
,
"op"
:
90
,
"st"
:
0
,
"bm"
:
0
}
],
"markers"
:
[]
}
\ No newline at end of file
library-common/src/main/AndroidManifest.xml
View file @
7e27ec13
...
@@ -33,7 +33,10 @@
...
@@ -33,7 +33,10 @@
android:name=
"design_height_in_dp"
android:name=
"design_height_in_dp"
android:value=
"640"
/>
android:value=
"640"
/>
<service
<service
android:name=
"com.gingersoft.gsa.cloud.common.service.GetInfoUpdateService"
android:name=
"com.gingersoft.gsa.cloud.common.service.DataNotificationService"
android:enabled=
"true"
/>
<service
android:name=
"com.gingersoft.gsa.cloud.common.service.DataNotificationService2"
android:enabled=
"true"
/>
android:enabled=
"true"
/>
</application>
</application>
</manifest>
</manifest>
library-common/src/main/java/com/gingersoft/gsa/cloud/app/GsaCloudApplication.java
View file @
7e27ec13
...
@@ -181,6 +181,11 @@ public class GsaCloudApplication extends BaseApplication {
...
@@ -181,6 +181,11 @@ public class GsaCloudApplication extends BaseApplication {
* 初始化美團日誌框架
* 初始化美團日誌框架
*/
*/
private
void
initLogan
()
{
private
void
initLogan
()
{
if
(
BuildConfig
.
DEBUG
)
{
LoganConfig
.
UPLOAD_LOG_URL
=
"http://192.168.1.131:8080/logan-web/logan/upload.json"
;
}
else
{
LoganConfig
.
UPLOAD_LOG_URL
=
HttpsConstans
.
HTTP_ADDRESS_URL_HK
+
"/logan-web/logan/upload.json"
;
}
com
.
dianping
.
logan
.
LoganConfig
config
=
new
com
.
dianping
.
logan
.
LoganConfig
.
Builder
()
com
.
dianping
.
logan
.
LoganConfig
config
=
new
com
.
dianping
.
logan
.
LoganConfig
.
Builder
()
.
setCachePath
(
getFilesDir
().
getAbsolutePath
())
.
setCachePath
(
getFilesDir
().
getAbsolutePath
())
.
setPath
(
getExternalFilesDir
(
null
).
getAbsolutePath
()
.
setPath
(
getExternalFilesDir
(
null
).
getAbsolutePath
()
...
@@ -392,9 +397,13 @@ public class GsaCloudApplication extends BaseApplication {
...
@@ -392,9 +397,13 @@ public class GsaCloudApplication extends BaseApplication {
}
}
@Override
@Override
public
void
disconnect
()
{
public
void
disconnect
(
Exception
e
)
{
if
(
e
!=
null
)
{
LoganManager
.
w_printer
(
TAG
,
e
.
getMessage
());
}
else
{
LoganManager
.
w_printer
(
TAG
,
"斷開打印機連接"
);
LoganManager
.
w_printer
(
TAG
,
"斷開打印機連接"
);
}
}
}
});
});
}
}
...
...
library-common/src/main/java/com/gingersoft/gsa/cloud/common/config/LoganConfig.java
View file @
7e27ec13
...
@@ -15,7 +15,7 @@ public class LoganConfig {
...
@@ -15,7 +15,7 @@ public class LoganConfig {
public
static
final
String
EncryptIV16
=
"0123456789012345"
;
public
static
final
String
EncryptIV16
=
"0123456789012345"
;
public
static
final
String
APP_ID
=
"gingersoft1008611"
;
public
static
final
String
APP_ID
=
"gingersoft1008611"
;
// public static final String UPLOAD_LOG_URL = HttpsConstans.HTTP_ADDRESS_URL_HK+ "/logan-web/logan/upload.json";
// public static final String UPLOAD_LOG_URL = HttpsConstans.HTTP_ADDRESS_URL_HK+ "/logan-web/logan/upload.json";
public
static
final
String
UPLOAD_LOG_URL
=
"http://192.168.1.131:8080/logan-web/logan/upload.json"
;
public
static
String
UPLOAD_LOG_URL
=
"http://192.168.1.131:8080/logan-web/logan/upload.json"
;
/**
/**
* 日誌保留天數
* 日誌保留天數
...
...
library-common/src/main/java/com/gingersoft/gsa/cloud/common/printer/plugins/ExternalPrinterConnection.java
View file @
7e27ec13
...
@@ -14,5 +14,5 @@ public interface ExternalPrinterConnection {
...
@@ -14,5 +14,5 @@ public interface ExternalPrinterConnection {
void
connectionError
(
Exception
e
);
void
connectionError
(
Exception
e
);
void
disconnect
();
void
disconnect
(
Exception
e
);
}
}
library-common/src/main/java/com/gingersoft/gsa/cloud/common/service/
GetInfoUpdate
Service.kt
→
library-common/src/main/java/com/gingersoft/gsa/cloud/common/service/
DataNotification
Service.kt
View file @
7e27ec13
...
@@ -15,18 +15,23 @@ import android.os.Build
...
@@ -15,18 +15,23 @@ import android.os.Build
import
android.os.IBinder
import
android.os.IBinder
import
android.os.PowerManager
import
android.os.PowerManager
import
android.util.Log
import
android.util.Log
import
android.view.View
import
android.widget.RemoteViews
import
android.widget.RemoteViews
import
androidx.annotation.RequiresApi
import
androidx.annotation.RequiresApi
import
androidx.core.app.NotificationCompat
import
androidx.core.app.NotificationCompat
import
com.billy.cc.core.component.CC
import
com.billy.cc.core.component.CCResult
import
com.gingersoft.gsa.cloud.common.R
import
com.gingersoft.gsa.cloud.common.R
import
com.gingersoft.gsa.cloud.common.constans.AppConstans
import
com.gingersoft.gsa.cloud.common.constans.AppConstans
import
com.gingersoft.gsa.cloud.common.constans.HttpsConstans
import
com.gingersoft.gsa.cloud.common.constans.HttpsConstans
import
com.gingersoft.gsa.cloud.common.constans.PrintConstans
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
import
com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager
import
com.gingersoft.gsa.cloud.common.core.user.UserContext
import
com.gingersoft.gsa.cloud.common.core.user.UserContext
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
import
com.gingersoft.gsa.cloud.common.logan.LoganManager
import
com.gingersoft.gsa.cloud.common.utils.SoundPoolUtils
import
com.gingersoft.gsa.cloud.common.utils.SoundPoolUtils
import
com.gingersoft.gsa.cloud.common.utils.okhttpUtils.OkHttp3Utils
import
com.gingersoft.gsa.cloud.common.utils.okhttpUtils.OkHttp3Utils
import
com.gingersoft.gsa.cloud.common.utils.time.TimeUtils
import
com.gingersoft.gsa.cloud.common.utils.time.TimeUtils
import
com.gingersoft.gsa.cloud.component.ComponentName
import
com.google.gson.Gson
import
com.google.gson.Gson
import
io.reactivex.Observable
import
io.reactivex.Observable
import
io.reactivex.Observer
import
io.reactivex.Observer
...
@@ -39,7 +44,7 @@ import org.json.JSONObject
...
@@ -39,7 +44,7 @@ import org.json.JSONObject
import
java.util.*
import
java.util.*
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.TimeUnit
class
GetInfoUpdate
Service
:
Service
()
{
class
DataNotification
Service
:
Service
()
{
private
val
TAG
=
"heart"
private
val
TAG
=
"heart"
...
@@ -61,13 +66,45 @@ class GetInfoUpdateService : Service() {
...
@@ -61,13 +66,45 @@ class GetInfoUpdateService : Service() {
private
val
CHANNEL_ID
=
"cloud_gsa"
private
val
CHANNEL_ID
=
"cloud_gsa"
private
var
isCreate
=
false
/**
* prj數據
*/
private
var
PRJ_DATA
=
10
/**
* prj數據
*/
private
var
TABLE_DATA
=
11
companion
object
{
companion
object
{
@kotlin
.
jvm
.
JvmField
@kotlin
.
jvm
.
JvmField
var
loginfo
=
StringBuffer
()
var
loginfo
=
StringBuffer
()
}
val
restaurantId
by
lazy
{
RestaurantInfoManager
.
newInstance
().
getRestaurantId
()
@kotlin
.
jvm
.
JvmField
var
CONNECTION_TYPE
=
"connection_type"
/**
* 开启外送接单长连
*/
@kotlin
.
jvm
.
JvmField
var
OPEN_DELIVET_ORDER_CONNECTION
=
2
/**
* 开启外送其他数据接收长连(prj,餐台数据)
*/
@kotlin
.
jvm
.
JvmField
var
OPEN_OTHER_CONNECTION
=
1
/**
* 当前连接类型
*/
@kotlin
.
jvm
.
JvmField
var
mCurrConnectionType
=
OPEN_OTHER_CONNECTION
}
}
override
fun
onBind
(
intent
:
Intent
?):
IBinder
?
{
override
fun
onBind
(
intent
:
Intent
?):
IBinder
?
{
...
@@ -88,12 +125,23 @@ class GetInfoUpdateService : Service() {
...
@@ -88,12 +125,23 @@ class GetInfoUpdateService : Service() {
}
}
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
//获取当前长连类型
mCurrConnectionType
=
intent
!!
.
getIntExtra
(
CONNECTION_TYPE
,
OPEN_DELIVET_ORDER_CONNECTION
)
if
(
mCurrConnectionType
==
OPEN_DELIVET_ORDER_CONNECTION
)
{
// 在API11之后构建Notification的方式
// 在API11之后构建Notification的方式
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
createNotificationChannel
()
createNotificationChannel
()
}
else
{
}
else
{
startNotification
()
startNotification
()
}
}
}
if
(
isCreate
)
{
send
(
mCurrConnectionType
)
}
isCreate
=
true
putTimeLog
(
"啟動服務onStartCommand"
)
putTimeLog
(
"啟動服務onStartCommand"
)
return
super
.
onStartCommand
(
intent
,
flags
,
startId
)
return
super
.
onStartCommand
(
intent
,
flags
,
startId
)
}
}
...
@@ -150,6 +198,14 @@ class GetInfoUpdateService : Service() {
...
@@ -150,6 +198,14 @@ class GetInfoUpdateService : Service() {
startForeground
(
123
,
builder
.
build
())
startForeground
(
123
,
builder
.
build
())
}
}
fun
cleanNotification
()
{
// val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// notificationManager.cancelAll()
// notificationManager.cancel(123)
// //停止前台服務
// stopForeground(true)
}
inner
class
MyBind
:
Binder
()
{
inner
class
MyBind
:
Binder
()
{
lateinit
var
block
:
(
isShow
:
Boolean
)
->
Unit
lateinit
var
block
:
(
isShow
:
Boolean
)
->
Unit
var
jumpActivity
:
Class
<*>?
=
null
var
jumpActivity
:
Class
<*>?
=
null
...
@@ -163,7 +219,7 @@ class GetInfoUpdateService : Service() {
...
@@ -163,7 +219,7 @@ class GetInfoUpdateService : Service() {
}
}
fun
setOnPostCallBack
(
postCallBack
:
PostCallBack
?)
{
fun
setOnPostCallBack
(
postCallBack
:
PostCallBack
?)
{
this
@
GetInfoUpdate
Service
.
postCallBack
=
postCallBack
this
@
DataNotification
Service
.
postCallBack
=
postCallBack
}
}
fun
execute
(
block
:
(
isShow
:
Boolean
)
->
Unit
)
{
fun
execute
(
block
:
(
isShow
:
Boolean
)
->
Unit
)
{
...
@@ -202,10 +258,9 @@ class GetInfoUpdateService : Service() {
...
@@ -202,10 +258,9 @@ class GetInfoUpdateService : Service() {
it
.
newWebSocket
(
request
,
object
:
WebSocketListener
()
{
it
.
newWebSocket
(
request
,
object
:
WebSocketListener
()
{
override
fun
onOpen
(
webSocket
:
WebSocket
,
response
:
Response
)
{
//开启长连接成功的回调
override
fun
onOpen
(
webSocket
:
WebSocket
,
response
:
Response
)
{
//开启长连接成功的回调
super
.
onOpen
(
webSocket
,
response
)
super
.
onOpen
(
webSocket
,
response
)
if
(!
this
@
GetInfoUpdate
Service
.
isDestroy
)
{
if
(!
this
@
DataNotification
Service
.
isDestroy
)
{
mWebSocket
=
webSocket
mWebSocket
=
webSocket
val
token
=
"weixin_"
+
restaurantId
+
"_"
+
getRandomString
(
24
)
send
(
mCurrConnectionType
)
webSocket
.
send
(
Gson
().
toJson
(
MsgBean
(
1
,
token
)))
putTimeLog
(
"連接成功"
)
putTimeLog
(
"連接成功"
)
cancelTimerDisposable
()
cancelTimerDisposable
()
myBind
?.
block
?.
invoke
(
false
)
myBind
?.
block
?.
invoke
(
false
)
...
@@ -232,11 +287,20 @@ class GetInfoUpdateService : Service() {
...
@@ -232,11 +287,20 @@ class GetInfoUpdateService : Service() {
// \n5:歷史訂單通知,
// \n5:歷史訂單通知,
// \n6:修改訂單狀態通知,
// \n6:修改訂單狀態通知,
// \n7:支付成功通知"
// \n7:支付成功通知"
// 10:prj数据
// 11:餐台数据
if
(
type
==
3
||
type
==
4
||
type
==
5
||
type
==
7
)
{
if
(
type
==
3
||
type
==
4
||
type
==
5
||
type
==
7
)
{
//播放提示音
//播放提示音
initSoundPool
(
R
.
raw
.
newordervocal
)
initSoundPool
(
R
.
raw
.
newordervocal
)
}
else
if
(
type
==
8
)
{
}
else
if
(
type
==
8
)
{
initSoundPool
(
R
.
raw
.
raw_logistics_cancel
)
initSoundPool
(
R
.
raw
.
raw_logistics_cancel
)
}
else
if
(
type
==
PRJ_DATA
)
{
CC
.
obtainBuilder
(
ComponentName
.
COMPONENT_PRINT
)
.
setActionName
(
"getPrjData"
)
.
build
()
.
call
()
}
else
if
(
type
==
TABLE_DATA
)
{
}
}
//收到服务器端传过来的消息text
//收到服务器端传过来的消息text
Log
.
e
(
TAG
,
"onMessage:$text"
)
Log
.
e
(
TAG
,
"onMessage:$text"
)
...
@@ -270,7 +334,8 @@ class GetInfoUpdateService : Service() {
...
@@ -270,7 +334,8 @@ class GetInfoUpdateService : Service() {
override
fun
onFailure
(
webSocket
:
WebSocket
,
t
:
Throwable
,
response
:
Response
?)
{
//长连接连接失败的回调
override
fun
onFailure
(
webSocket
:
WebSocket
,
t
:
Throwable
,
response
:
Response
?)
{
//长连接连接失败的回调
super
.
onFailure
(
webSocket
,
t
,
response
)
super
.
onFailure
(
webSocket
,
t
,
response
)
Log
.
e
(
TAG
,
"onFailure "
+
t
.
message
)
Log
.
e
(
TAG
,
"onFailure "
+
t
.
message
)
if
(!
this
@GetInfoUpdateService
.
isDestroy
)
{
if
(!
this
@DataNotificationService
.
isDestroy
)
{
//連接斷開,定時五秒,如果未重連,播放提示音
//連接斷開,定時五秒,如果未重連,播放提示音
delayFun
({
delayFun
({
initSoundPool
(
R
.
raw
.
raw_disconnect
)
initSoundPool
(
R
.
raw
.
raw_disconnect
)
...
@@ -283,6 +348,7 @@ class GetInfoUpdateService : Service() {
...
@@ -283,6 +348,7 @@ class GetInfoUpdateService : Service() {
webSocket
.
cancel
()
webSocket
.
cancel
()
it
.
dispatcher
().
cancelAll
()
it
.
dispatcher
().
cancelAll
()
}
}
}
}
})
})
it
.
dispatcher
().
executorService
().
shutdown
()
it
.
dispatcher
().
executorService
().
shutdown
()
...
@@ -290,6 +356,21 @@ class GetInfoUpdateService : Service() {
...
@@ -290,6 +356,21 @@ class GetInfoUpdateService : Service() {
},
HEART_BEAT_RATE
)
},
HEART_BEAT_RATE
)
}
}
fun
send
(
currConnectionType
:
Int
)
{
val
token
=
"weixin_"
+
RestaurantInfoManager
.
newInstance
().
restaurantId
+
"_"
+
UserContext
.
newInstance
().
memberId
+
"_"
+
getRandomString
(
24
)
if
(
mWebSocket
!=
null
)
{
mWebSocket
?.
send
(
Gson
().
toJson
(
MsgBean
(
1
,
getConnectiontype
(),
token
)))
}
}
private
fun
getConnectiontype
():
String
{
var
connectiontype
=
"$OPEN_OTHER_CONNECTION"
if
(
mCurrConnectionType
==
OPEN_DELIVET_ORDER_CONNECTION
)
{
connectiontype
=
"$OPEN_OTHER_CONNECTION , $OPEN_DELIVET_ORDER_CONNECTION"
}
return
connectiontype
}
private
var
lastSoundTime
:
Long
=
0L
private
var
lastSoundTime
:
Long
=
0L
fun
initSoundPool
(
resId
:
Int
)
{
fun
initSoundPool
(
resId
:
Int
)
{
val
nowTime
=
System
.
currentTimeMillis
()
//當前時間減去上次播放的時間,如果超過五秒,那麼才會再次播放提示聲
val
nowTime
=
System
.
currentTimeMillis
()
//當前時間減去上次播放的時間,如果超過五秒,那麼才會再次播放提示聲
...
@@ -346,7 +427,7 @@ class GetInfoUpdateService : Service() {
...
@@ -346,7 +427,7 @@ class GetInfoUpdateService : Service() {
private
fun
clearHeart
()
{
private
fun
clearHeart
()
{
val
requestBody
=
FormBody
.
Builder
()
val
requestBody
=
FormBody
.
Builder
()
.
add
(
"restaurantId"
,
restaurantId
.
toString
())
.
add
(
"restaurantId"
,
RestaurantInfoManager
.
newInstance
().
restaurantId
.
toString
())
.
build
()
.
build
()
OkHttp3Utils
.
post
(
HttpsConstans
.
ROOT_URL
+
"/member-web/api/restaurant/clearHeartbeat"
,
requestBody
)
OkHttp3Utils
.
post
(
HttpsConstans
.
ROOT_URL
+
"/member-web/api/restaurant/clearHeartbeat"
,
requestBody
)
.
subscribeOn
(
Schedulers
.
io
()).
subscribe
()
.
subscribeOn
(
Schedulers
.
io
()).
subscribe
()
...
@@ -355,7 +436,10 @@ class GetInfoUpdateService : Service() {
...
@@ -355,7 +436,10 @@ class GetInfoUpdateService : Service() {
inner
class
ClearHeartBroadcastReceiver
:
BroadcastReceiver
()
{
inner
class
ClearHeartBroadcastReceiver
:
BroadcastReceiver
()
{
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
//關閉service,會調用service的onDestroy
//關閉service,會調用service的onDestroy
stopSelf
()
// stopSelf()
cleanNotification
()
mCurrConnectionType
=
OPEN_OTHER_CONNECTION
;
send
(
mCurrConnectionType
)
}
}
}
}
...
@@ -428,6 +512,6 @@ class GetInfoUpdateService : Service() {
...
@@ -428,6 +512,6 @@ class GetInfoUpdateService : Service() {
})
})
}
}
class
MsgBean
(
var
type
:
Int
,
var
token
:
String
)
class
MsgBean
(
var
type
:
Int
,
var
data
:
String
,
var
token
:
String
)
}
}
\ No newline at end of file
library-print/src/main/java/com/gingersoft/gsa/cloud/print/PrintSocketHolder.java
View file @
7e27ec13
...
@@ -182,7 +182,7 @@ public class PrintSocketHolder {
...
@@ -182,7 +182,7 @@ public class PrintSocketHolder {
socket
=
null
;
socket
=
null
;
error
=
true
;
error
=
true
;
}
}
PrinterPlugins
.
getOnPrinterFlowHandler
().
disconnect
();
PrinterPlugins
.
getOnPrinterFlowHandler
().
disconnect
(
null
);
return
error
?
ERROR_66
:
ERROR_0
;
return
error
?
ERROR_66
:
ERROR_0
;
}
}
...
...
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