Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
GingerSoftLANInterconnection
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
王宇航
GingerSoftLANInterconnection
Commits
2bf648c3
Commit
2bf648c3
authored
May 24, 2024
by
王宇航
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
可以通過調用GingerSoftConnect.connect連接服務器並發送數據
parent
941f086c
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
948 additions
and
6 deletions
+948
-6
.idea/deploymentTargetDropDown.xml
+14
-1
app/build.gradle.kts
+2
-1
app/src/main/AndroidManifest.xml
+21
-1
app/src/main/java/com/example/demo/MainActivity.kt
+82
-0
app/src/main/res/layout/activity_main.xml
+68
-0
app/src/main/res/xml/network_security_config.xml
+9
-0
mylibrary/build.gradle.kts
+7
-3
mylibrary/src/main/AndroidManifest.xml
+2
-0
mylibrary/src/main/java/com/gingersoft/connect/SendCallback.kt
+6
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/Action.kt
+6
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/FoodInfoBean.java
+122
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/MessageBean.kt
+11
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/MessageBuilder.kt
+27
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/MessageSender.kt
+70
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/OrderInfoBean.java
+163
-0
mylibrary/src/main/java/com/gingersoft/connect/bean/SendMsgType.kt
+7
-0
mylibrary/src/main/java/com/gingersoft/connect/utils/DeviceDiscovery.kt
+87
-0
mylibrary/src/main/java/com/gingersoft/connect/utils/GingerSoftConnect.kt
+31
-0
mylibrary/src/main/java/com/gingersoft/connect/utils/GsonUtils.java
+137
-0
mylibrary/src/main/java/com/gingersoft/connect/utils/MyWebSocketClient.kt
+67
-0
mylibrary/src/main/res/xml/network_security_config.xml
+9
-0
No files found.
.idea/deploymentTargetDropDown.xml
View file @
2bf648c3
...
@@ -3,7 +3,20 @@
...
@@ -3,7 +3,20 @@
<component
name=
"deploymentTargetDropDown"
>
<component
name=
"deploymentTargetDropDown"
>
<value>
<value>
<entry
key=
"app"
>
<entry
key=
"app"
>
<State
/>
<State>
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type
value=
"RUNNING_DEVICE_TARGET"
/>
<deviceKey>
<Key>
<type
value=
"SERIAL_NUMBER"
/>
<value
value=
"9X4TRG5PSCEYZHZX"
/>
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown
value=
"2024-05-24T09:32:50.146130200Z"
/>
</State>
</entry>
</entry>
</value>
</value>
</component>
</component>
...
...
app/build.gradle.kts
View file @
2bf648c3
...
@@ -36,10 +36,11 @@ android {
...
@@ -36,10 +36,11 @@ android {
}
}
dependencies {
dependencies {
implementation("com.squareup.okhttp3:okhttp:3.14.9")
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("com.google.android.material:material:1.9.0")
implementation(project(":mylibrary"))
testImplementation("junit:junit:4.13.2")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
...
...
app/src/main/AndroidManifest.xml
View file @
2bf648c3
...
@@ -2,15 +2,34 @@
...
@@ -2,15 +2,34 @@
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
xmlns:tools=
"http://schemas.android.com/tools"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.CHANGE_WIFI_MULTICAST_STATE"
/>
<uses-permission
android:name=
"android.permission.ACCESS_WIFI_STATE"
/>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<application
<application
android:allowBackup=
"true"
android:allowBackup=
"true"
android:dataExtractionRules=
"@xml/data_extraction_rules"
android:dataExtractionRules=
"@xml/data_extraction_rules"
android:fullBackupContent=
"@xml/backup_rules"
android:fullBackupContent=
"@xml/backup_rules"
android:icon=
"@mipmap/ic_launcher"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:label=
"@string/app_name"
android:networkSecurityConfig=
"@xml/network_security_config"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
android:supportsRtl=
"true"
android:theme=
"@style/Theme.GingersoftConnect"
android:theme=
"@style/Theme.GingersoftConnect"
tools:targetApi=
"31"
/>
tools:targetApi=
"31"
>
<activity
android:name=
"com.example.demo.MainActivity"
android:exported=
"true"
>
<intent-filter>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<action
android:name=
"android.intent.action.MAIN"
/>
</intent-filter>
</activity>
</application>
</manifest>
</manifest>
\ No newline at end of file
app/src/main/java/com/example/demo/MainActivity.kt
0 → 100644
View file @
2bf648c3
package
com.example.demo
import
android.app.Activity
import
android.os.Bundle
import
android.util.Log
import
android.widget.TextView
import
com.example.gingersoft_connect.R
import
com.gingersoft.connect.SendCallback
import
com.gingersoft.connect.bean.Action
import
com.gingersoft.connect.bean.MessageBuilder
import
com.gingersoft.connect.bean.MessageSender
import
com.gingersoft.connect.bean.OrderInfoBean
import
com.gingersoft.connect.utils.GingerSoftConnect
class
MainActivity
:
Activity
()
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_main
)
var
msgSender
:
MessageBuilder
?
=
null
var
connect
:
GingerSoftConnect
?
=
null
val
tvConnect
=
findViewById
<
TextView
>(
R
.
id
.
tv_connect
)
val
tvDisconnect
=
findViewById
<
TextView
>(
R
.
id
.
tv_disconnect
)
val
tvSendMsg
=
findViewById
<
TextView
>(
R
.
id
.
tv_send_msg
)
val
tvSendValue
=
findViewById
<
TextView
>(
R
.
id
.
tv_send_value
)
tvConnect
.
setOnClickListener
{
tvConnect
.
isClickable
=
false
connect
=
GingerSoftConnect
()
msgSender
=
connect
!!
.
connect
(
"192.168.1.151"
,
12581
,
object
:
GingerSoftConnect
.
SocketStateListener
{
override
fun
onOpen
()
{
super
.
onOpen
()
runOnUiThread
{
tvConnect
.
text
=
"已連接"
tvConnect
.
isClickable
=
true
}
}
override
fun
onClose
(
code
:
Int
,
reason
:
String
?,
remote
:
Boolean
)
{
super
.
onClose
(
code
,
reason
,
remote
)
runOnUiThread
{
tvConnect
.
text
=
"已斷開:$code,$reason"
tvConnect
.
isClickable
=
true
}
}
override
fun
onError
(
ex
:
Exception
?)
{
super
.
onError
(
ex
)
runOnUiThread
{
tvConnect
.
isClickable
=
true
tvConnect
.
text
=
"發生錯誤:${ex?.message}"
}
}
})
}
tvDisconnect
.
setOnClickListener
{
connect
?.
disconnect
()
}
tvSendMsg
.
setOnClickListener
{
msgSender
?.
initSendData
(
Action
.
KitchenInfo
,
OrderInfoBean
())
?.
asyncSend
(
object
:
SendCallback
{
override
fun
callback
(
status
:
Boolean
,
errorCode
:
Int
)
{
runOnUiThread
{
tvSendValue
.
text
=
if
(
status
)
"發送成功"
else
when
(
errorCode
)
{
MessageBuilder
.
ERROR_CODE_SEND_TIMEOUT
->
"發送消息超時"
MessageBuilder
.
ERROR_CODE_NOT_CONNECT
->
"未連接到服務器"
MessageBuilder
.
ERROR_CODE_CONNECT_TIMEOUT
->
"連接服務器超時"
else
->
"發生錯誤:$errorCode"
}
}
}
})
}
}
}
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
0 → 100644
View file @
2bf648c3
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/white"
android:gravity=
"center"
android:orientation=
"vertical"
>
<TextView
android:id=
"@+id/tv_connect"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"@color/purple_700"
android:paddingHorizontal=
"20dp"
android:paddingVertical=
"15dp"
android:text=
"連接服務器"
android:textColor=
"@color/white"
android:textSize=
"18dp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
<TextView
android:id=
"@+id/tv_disconnect"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"20dp"
android:background=
"@color/purple_700"
android:paddingHorizontal=
"20dp"
android:paddingVertical=
"15dp"
android:text=
"斷開服務器"
android:textColor=
"@color/white"
android:textSize=
"18dp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
<TextView
android:id=
"@+id/tv_send_msg"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"20dp"
android:background=
"@color/purple_700"
android:paddingHorizontal=
"20dp"
android:paddingVertical=
"15dp"
android:text=
"發送 消息"
android:textColor=
"@color/white"
android:textSize=
"18dp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
<TextView
android:id=
"@+id/tv_send_value"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"20dp"
android:paddingHorizontal=
"20dp"
android:paddingVertical=
"15dp"
android:textColor=
"@color/black"
android:textSize=
"18dp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/xml/network_security_config.xml
0 → 100644
View file @
2bf648c3
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config
cleartextTrafficPermitted=
"true"
>
<trust-anchors>
<certificates
src=
"system"
/>
</trust-anchors>
</base-config>
</network-security-config>
\ No newline at end of file
mylibrary/build.gradle.kts
View file @
2bf648c3
...
@@ -34,13 +34,17 @@ android {
...
@@ -34,13 +34,17 @@ android {
}
}
dependencies {
dependencies {
implementation("org.jmdns:jmdns:3.5.5")
implementation("androidx.core:core-ktx:1.10.1")
implementation("org.java-websocket:Java-WebSocket:1.5.2")
implementation("org.nanohttpd:nanohttpd-websocket:2.3.1")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("com.google.android.material:material:1.12.0")
implementation("com.squareup.okhttp3:okhttp:3.14.9")
testImplementation("junit:junit:4.13.2")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("com.google.code.gson:gson:2.10.1")
}
}
afterEvaluate {
afterEvaluate {
...
...
mylibrary/src/main/AndroidManifest.xml
View file @
2bf648c3
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<application
android:networkSecurityConfig=
"@xml/network_security_config"
/>
</manifest>
</manifest>
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/SendCallback.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect
interface
SendCallback
{
fun
callback
(
status
:
Boolean
,
errorCode
:
Int
)
}
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/bean/Action.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.bean
enum
class
Action
{
KitchenInfo
,
SoldOutInfo
}
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/bean/FoodInfoBean.java
0 → 100644
View file @
2bf648c3
package
com
.
gingersoft
.
connect
.
bean
;
public
class
FoodInfoBean
{
private
Long
id
;
/**
* 食品id
*/
private
String
FoodId
;
/**
* 打印用的id(RicePOS的prjId)
*/
private
String
PrintId
;
/**
* 訂單ID
*/
private
Long
orderId
;
/**
* 食品名稱
*/
private
String
FoodName
;
/**
* 食品數量
*/
private
String
quantity
;
/**
* 食品金額
*/
private
double
price
;
/**
* 食品類型
*/
private
int
type
;
/**
* 父級食品id
*/
private
String
parentId
;
/**
* 食品是否打印紅色字
* true 首頁也會顯示紅色 false 首頁顯示設置頁面的顏色
*/
private
boolean
isPrintRedLetter
;
public
Long
getId
()
{
return
this
.
id
;
}
public
void
setId
(
Long
id
)
{
this
.
id
=
id
;
}
public
String
getFoodId
()
{
return
this
.
FoodId
;
}
public
void
setFoodId
(
String
FoodId
)
{
this
.
FoodId
=
FoodId
;
}
public
String
getPrintId
()
{
return
this
.
PrintId
;
}
public
void
setPrintId
(
String
PrintId
)
{
this
.
PrintId
=
PrintId
;
}
public
Long
getOrderId
()
{
return
this
.
orderId
;
}
public
void
setOrderId
(
Long
orderId
)
{
this
.
orderId
=
orderId
;
}
public
String
getFoodName
()
{
return
this
.
FoodName
;
}
public
void
setFoodName
(
String
FoodName
)
{
this
.
FoodName
=
FoodName
;
}
public
String
getQuantity
()
{
return
this
.
quantity
;
}
public
void
setQuantity
(
String
quantity
)
{
this
.
quantity
=
quantity
;
}
public
double
getPrice
()
{
return
this
.
price
;
}
public
void
setPrice
(
double
price
)
{
this
.
price
=
price
;
}
public
int
getType
()
{
return
this
.
type
;
}
public
void
setType
(
int
type
)
{
this
.
type
=
type
;
}
public
String
getParentId
()
{
return
this
.
parentId
;
}
public
void
setParentId
(
String
parentId
)
{
this
.
parentId
=
parentId
;
}
public
boolean
getIsPrintRedLetter
()
{
return
this
.
isPrintRedLetter
;
}
public
void
setIsPrintRedLetter
(
boolean
isPrintRedLetter
)
{
this
.
isPrintRedLetter
=
isPrintRedLetter
;
}
}
mylibrary/src/main/java/com/gingersoft/connect/bean/MessageBean.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.bean
class
MessageBean
<
T
>(
/**
* 消息唯一ID,發送消息過去,服務端收到後會發送一條成功接收消息,通過這個code來區分是哪條消息
*/
var
code
:
Int
=
0
,
var
action
:
String
?
=
null
,
var
data
:
T
?
=
null
)
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/bean/MessageBuilder.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.bean
import
com.gingersoft.connect.utils.GingerSoftConnect
import
com.gingersoft.connect.utils.MyWebSocketClient
import
java.util.concurrent.atomic.AtomicInteger
class
MessageBuilder
(
private
val
connect
:
GingerSoftConnect
,
private
val
webSocketClient
:
MyWebSocketClient
)
{
companion
object
{
private
val
msgCode
=
AtomicInteger
(
0
)
const
val
ERROR_CODE_SEND_TIMEOUT
=
100
const
val
ERROR_CODE_NOT_CONNECT
=
101
const
val
ERROR_CODE_CONNECT_TIMEOUT
=
102
}
fun
initSendData
(
action
:
Action
,
sendData
:
SendMsgType
):
MessageSender
{
val
currentMsgCode
=
msgCode
.
incrementAndGet
()
val
msg
=
MessageBean
(
currentMsgCode
,
action
.
toString
(),
sendData
)
return
MessageSender
(
connect
,
webSocketClient
,
msg
)
}
}
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/bean/MessageSender.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.bean
import
android.os.Build.VERSION_CODES.P
import
android.util.Log
import
com.gingersoft.connect.SendCallback
import
com.gingersoft.connect.utils.GingerSoftConnect
import
com.gingersoft.connect.utils.GsonUtils
import
com.gingersoft.connect.utils.MyWebSocketClient
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.runBlocking
class
MessageSender
(
private
val
connect
:
GingerSoftConnect
,
private
val
webSocketClient
:
MyWebSocketClient
,
private
val
msg
:
MessageBean
<*>
)
{
fun
send
():
GingerSoftConnect
{
asyncSend
(
null
)
return
connect
}
/**
* 發送數據到服務器
* @param callback Function1<Boolean, Unit> 回調,只能保證是否發送,不能保證對方是否接收到
* @return GingerSoftConnect
*/
fun
send
(
callback
:
(
Boolean
)
->
Unit
):
GingerSoftConnect
{
if
(
webSocketClient
.
isOpen
)
{
asyncSend
(
null
)
callback
.
invoke
(
true
)
}
else
{
callback
.
invoke
(
false
)
}
return
connect
}
/**
* 發送到服務器,對方正常接收到數據會通知過來
* @return GingerSoftConnect
*/
fun
asyncSend
(
callback
:
SendCallback
?):
GingerSoftConnect
{
val
currentTimeMillis
=
System
.
currentTimeMillis
()
runBlocking
{
launch
(
Dispatchers
.
IO
)
{
while
(
webSocketClient
.
getStatus
()
==
0
&&
System
.
currentTimeMillis
()
-
currentTimeMillis
<
10000
)
{
delay
(
500
)
}
if
(
webSocketClient
.
getStatus
()
!=
0
)
{
send
(
callback
)
}
else
{
// 超時
callback
?.
callback
(
false
,
MessageBuilder
.
ERROR_CODE_CONNECT_TIMEOUT
)
}
}
}
return
connect
}
private
fun
send
(
callback
:
SendCallback
?)
{
if
(
webSocketClient
.
isClosed
||
webSocketClient
.
isClosing
||
!
webSocketClient
.
isOpen
)
{
callback
?.
callback
(
false
,
MessageBuilder
.
ERROR_CODE_NOT_CONNECT
)
}
else
{
webSocketClient
.
sendMsg
(
msg
.
code
.
toString
(),
GsonUtils
.
GsonString
(
msg
),
callback
)
}
}
}
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/bean/OrderInfoBean.java
0 → 100644
View file @
2bf648c3
package
com
.
gingersoft
.
connect
.
bean
;
import
java.util.List
;
public
class
OrderInfoBean
implements
SendMsgType
{
private
Long
id
;
/**
* 訂單ID
*/
private
Long
orderId
;
/**
* 訂單類型
*/
private
int
orderType
;
/**
* 用餐人數
*/
private
int
pax
;
/**
* 送單人id
*/
private
String
senderId
;
/**
* 送單人名稱
*/
private
String
senderName
;
/**
* 送單時間
*/
private
String
sendTime
;
/**
* 發送數據的設備id
*/
private
String
sendDeviceId
;
/**
* 發送數據的設備名稱
*/
private
String
sendDeviceName
;
/**
* 送單次數
*/
private
int
sendOrderCount
;
/**
* 是否首次送單
*/
private
boolean
isFirstSendOrder
;
/**
* 飛單描述,例如本機為k2,POS機從k1打印失敗,轉到K2打印,可以在此字段中寫K1->K2
*/
private
String
flyPrintInfo
;
/**
* 打印狀態
*/
private
int
printStatus
;
/**
* 食品信息
*/
private
List
<
FoodInfoBean
>
foodInfoBeanList
;
public
Long
getId
()
{
return
this
.
id
;
}
public
void
setId
(
Long
id
)
{
this
.
id
=
id
;
}
public
Long
getOrderId
()
{
return
this
.
orderId
;
}
public
void
setOrderId
(
Long
orderId
)
{
this
.
orderId
=
orderId
;
}
public
int
getOrderType
()
{
return
this
.
orderType
;
}
public
void
setOrderType
(
int
orderType
)
{
this
.
orderType
=
orderType
;
}
public
int
getPax
()
{
return
this
.
pax
;
}
public
void
setPax
(
int
pax
)
{
this
.
pax
=
pax
;
}
public
String
getSenderId
()
{
return
this
.
senderId
;
}
public
void
setSenderId
(
String
senderId
)
{
this
.
senderId
=
senderId
;
}
public
String
getSenderName
()
{
return
this
.
senderName
;
}
public
void
setSenderName
(
String
senderName
)
{
this
.
senderName
=
senderName
;
}
public
String
getSendTime
()
{
return
this
.
sendTime
;
}
public
void
setSendTime
(
String
sendTime
)
{
this
.
sendTime
=
sendTime
;
}
public
String
getSendDeviceId
()
{
return
this
.
sendDeviceId
;
}
public
void
setSendDeviceId
(
String
sendDeviceId
)
{
this
.
sendDeviceId
=
sendDeviceId
;
}
public
String
getSendDeviceName
()
{
return
this
.
sendDeviceName
;
}
public
void
setSendDeviceName
(
String
sendDeviceName
)
{
this
.
sendDeviceName
=
sendDeviceName
;
}
public
int
getSendOrderCount
()
{
return
this
.
sendOrderCount
;
}
public
void
setSendOrderCount
(
int
sendOrderCount
)
{
this
.
sendOrderCount
=
sendOrderCount
;
}
public
boolean
getIsFirstSendOrder
()
{
return
this
.
isFirstSendOrder
;
}
public
void
setIsFirstSendOrder
(
boolean
isFirstSendOrder
)
{
this
.
isFirstSendOrder
=
isFirstSendOrder
;
}
public
String
getFlyPrintInfo
()
{
return
this
.
flyPrintInfo
;
}
public
void
setFlyPrintInfo
(
String
flyPrintInfo
)
{
this
.
flyPrintInfo
=
flyPrintInfo
;
}
public
int
getPrintStatus
()
{
return
this
.
printStatus
;
}
public
void
setPrintStatus
(
int
printStatus
)
{
this
.
printStatus
=
printStatus
;
}
}
mylibrary/src/main/java/com/gingersoft/connect/bean/SendMsgType.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.bean
/**
* 只是用來限制,可以傳什麼類型的參數
*/
interface
SendMsgType
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/utils/DeviceDiscovery.kt
0 → 100644
View file @
2bf648c3
//package com.gingersoft.connect.utils
//
//import android.content.Context
//import android.net.wifi.WifiManager
//import android.util.Log
//import java.io.IOException
//import java.net.InetAddress
//import javax.jmdns.JmDNS
//import javax.jmdns.ServiceEvent
//import javax.jmdns.ServiceInfo
//import javax.jmdns.ServiceListener
//
//object DeviceDiscovery {
//
// var jmdns: JmDNS? = null
// fun discoverDevices(context: Context, port: Int, callback: (String, Int) -> Unit) {
// try {
// val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
// val multicastLock = wifiManager.createMulticastLock("myMulticastLock")
// multicastLock.setReferenceCounted(true)
// multicastLock.acquire() // 開啟多播鎖可以快速接收消息,但是會增加耗電量
// val address = getLocalIpAddress(context)
// if (address != null) {
// jmdns = JmDNS.create(address)
// val serviceInfo =
// ServiceInfo.create("_ws._tcp.local.", "gingersoft", port, "path=index.html")
// jmdns?.registerService(serviceInfo)
// jmdns?.addServiceListener("_ws._tcp.local.", object : ServiceListener {
// override fun serviceAdded(event: ServiceEvent) {
// Log.e("eeeaaa", "Service added:${event.info}}")
// }
//
// override fun serviceRemoved(event: ServiceEvent) {
// Log.e("eeeaaa", "Service removed: ${event.info}")
// }
//
// override fun serviceResolved(event: ServiceEvent) {
// val hostAddress = event.info.hostAddresses[0]
// val port = event.info.port
// Log.e("eeeaaa", "serviceResolved: ${event.info}---${hostAddress}---${address.hostAddress}")
// if (event.info.name.contains("gingersoft") && hostAddress != null && hostAddress != address.hostAddress) {
// Log.e("eeeaaa", "Service resolved: ${event.info} at $hostAddress:$port")
// callback(hostAddress, port)
// }
// // 超過多久搜索不到,關閉多播鎖
//// multicastLock.release()
// }
// })
// } else {
// Log.e("eeeaaa", "Failed to get local IP address")
// }
// } catch (e: IOException) {
// e.printStackTrace()
// }
// }
//
// private fun getLocalIpAddress(context: Context): InetAddress? {
// try {
// val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
// val wifiInfo = wifiManager.connectionInfo
// val ipAddress = wifiInfo.ipAddress
// val ipByteArray = byteArrayOf(
// (ipAddress and 0xff).toByte(),
// (ipAddress shr 8 and 0xff).toByte(),
// (ipAddress shr 16 and 0xff).toByte(),
// (ipAddress shr 24 and 0xff).toByte()
// )
// return InetAddress.getByAddress(ipByteArray)
// } catch (e: Exception) {
// e.printStackTrace()
// }
// return null
// }
//
//
// fun stopService() {
// if (jmdns != null) {
// jmdns!!.unregisterAllServices()
// try {
// jmdns!!.close()
// } catch (e: IOException) {
// e.printStackTrace()
// }
// }
// }
//}
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/utils/GingerSoftConnect.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.utils
import
com.gingersoft.connect.bean.MessageBuilder
import
java.net.URI
class
GingerSoftConnect
{
private
var
webSocketClient
:
MyWebSocketClient
?
=
null
fun
connect
(
ip
:
String
,
port
:
Int
,
listener
:
SocketStateListener
?):
MessageBuilder
{
val
uri
=
URI
(
"ws://$ip:$port"
)
webSocketClient
=
MyWebSocketClient
(
uri
,
listener
)
webSocketClient
?.
connect
()
// 連接成功後獲得發送類
return
MessageBuilder
(
this
,
webSocketClient
!!
)
}
fun
disconnect
()
{
webSocketClient
?.
close
()
}
interface
SocketStateListener
{
fun
onOpen
()
{}
fun
onClose
(
code
:
Int
,
reason
:
String
?,
remote
:
Boolean
)
{}
fun
onError
(
ex
:
Exception
?)
{}
}
}
\ No newline at end of file
mylibrary/src/main/java/com/gingersoft/connect/utils/GsonUtils.java
0 → 100644
View file @
2bf648c3
package
com
.
gingersoft
.
connect
.
utils
;
import
com.google.gson.Gson
;
import
com.google.gson.JsonArray
;
import
com.google.gson.JsonElement
;
import
com.google.gson.JsonParser
;
import
com.google.gson.reflect.TypeToken
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
public
class
GsonUtils
{
private
static
volatile
Gson
gson
;
public
static
Gson
getGson
()
{
if
(
gson
==
null
)
{
synchronized
(
GsonUtils
.
class
)
{
if
(
gson
==
null
)
{
gson
=
new
Gson
();
}
}
}
return
gson
;
}
public
static
void
init
(
Gson
gson
)
{
GsonUtils
.
gson
=
gson
;
}
private
GsonUtils
()
{
}
/**
* 轉成json
*
* @param object
* @return
*/
public
static
String
GsonString
(
Object
object
)
{
String
gsonString
=
null
;
try
{
gsonString
=
getGson
().
toJson
(
object
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
gsonString
;
}
/**
* 轉成bean
*
* @param gsonString
* @param cls
* @return
*/
public
static
<
T
>
T
GsonToBean
(
String
gsonString
,
Class
<
T
>
cls
)
{
T
t
=
null
;
try
{
t
=
getGson
().
fromJson
(
gsonString
,
cls
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
t
;
}
/**
* 轉成bean
*
* @param gsonString
* @param cls
* @return
*/
public
static
<
T
>
T
GsonToBean
(
Object
gsonString
,
Class
<
T
>
cls
)
{
return
GsonToBean
(
GsonString
(
gsonString
),
cls
);
}
/**
* json字符串轉成list
*
* @param cls
* @return
*/
public
static
<
T
>
ArrayList
<
T
>
jsonToList
(
Object
object
,
Class
<
T
>
cls
)
{
return
jsonToList
(
GsonString
(
object
),
cls
);
}
/**
* json字符串轉成list
*
* @param cls
* @return
*/
public
static
<
T
>
ArrayList
<
T
>
jsonToList
(
String
json
,
Class
<
T
>
cls
)
{
ArrayList
<
T
>
mList
=
new
ArrayList
<>();
if
(
json
==
null
||
json
.
isEmpty
())
{
return
null
;
}
try
{
JsonArray
array
=
new
JsonParser
().
parse
(
json
).
getAsJsonArray
();
for
(
final
JsonElement
elem
:
array
)
{
mList
.
add
(
getGson
().
fromJson
(
elem
,
cls
));
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
mList
;
}
/**
* 轉成list中有map的
*
* @param gsonString
* @return
*/
public
static
<
T
>
List
<
Map
<
String
,
T
>>
GsonToListMaps
(
String
gsonString
)
{
List
<
Map
<
String
,
T
>>
list
=
null
;
list
=
getGson
().
fromJson
(
gsonString
,
new
TypeToken
<
List
<
Map
<
String
,
T
>>>()
{
}.
getType
());
return
list
;
}
/**
* 轉成map的
*
* @param gsonString
* @return
*/
public
static
<
T
>
Map
<
String
,
T
>
GsonToMaps
(
String
gsonString
)
{
Map
<
String
,
T
>
map
=
null
;
map
=
getGson
().
fromJson
(
gsonString
,
new
TypeToken
<
Map
<
String
,
T
>>()
{
}.
getType
());
return
map
;
}
}
mylibrary/src/main/java/com/gingersoft/connect/utils/MyWebSocketClient.kt
0 → 100644
View file @
2bf648c3
package
com.gingersoft.connect.utils
import
android.util.Log
import
com.gingersoft.connect.SendCallback
import
com.gingersoft.connect.bean.MessageBuilder
import
kotlinx.coroutines.channels.Channel
import
org.java_websocket.client.WebSocketClient
import
org.java_websocket.handshake.ServerHandshake
import
java.net.URI
import
java.util.Timer
import
java.util.TimerTask
class
MyWebSocketClient
(
serverUri
:
URI
,
private
val
listener
:
GingerSoftConnect
.
SocketStateListener
?
)
:
WebSocketClient
(
serverUri
)
{
private
val
map
by
lazy
{
HashMap
<
String
,
SendCallback
>()
}
private
val
timerMap
by
lazy
{
HashMap
<
String
,
Timer
>()
}
private
var
status
=
0
override
fun
onOpen
(
handshakedata
:
ServerHandshake
?)
{
listener
?.
onOpen
()
status
=
1
}
override
fun
onMessage
(
message
:
String
?)
{
Log
.
e
(
"eeeaaa"
,
"客戶端收到消息:$message"
)
if
(
message
!=
null
&&
map
.
containsKey
(
message
))
{
map
[
message
]
?.
callback
(
true
,
200
)
timerMap
[
message
]
?.
cancel
()
}
}
override
fun
onClose
(
code
:
Int
,
reason
:
String
?,
remote
:
Boolean
)
{
listener
?.
onClose
(
code
,
reason
,
remote
)
status
=
2
}
override
fun
onError
(
ex
:
Exception
?)
{
listener
?.
onError
(
ex
)
status
=
3
}
fun
sendMsg
(
msgCode
:
String
,
text
:
String
,
callback
:
SendCallback
?)
{
if
(
callback
!=
null
)
{
// 保存code和callback的關係,服務器返回收到後,需要調用回調
// 使用map是為了應對多線程情況
map
[
msgCode
]
=
callback
// 增加十秒倒計時,超時情況
timerMap
[
msgCode
]
=
Timer
()
timerMap
[
msgCode
]
?.
schedule
(
object
:
TimerTask
()
{
override
fun
run
()
{
callback
.
callback
(
false
,
MessageBuilder
.
ERROR_CODE_SEND_TIMEOUT
)
}
},
10000
)
}
// 發送數據到服務器
send
(
text
)
}
fun
getStatus
()
=
status
}
\ No newline at end of file
mylibrary/src/main/res/xml/network_security_config.xml
0 → 100644
View file @
2bf648c3
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config
cleartextTrafficPermitted=
"true"
>
<trust-anchors>
<certificates
src=
"system"
/>
</trust-anchors>
</base-config>
</network-security-config>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment