Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
R
ReactNative Ubal Simulator
Project
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OPEN-SHARING
ReactNative Ubal Simulator
Commits
fca91b54
Commit
fca91b54
authored
Mar 27, 2025
by
Gandha Ryanto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update library
parent
dc92304d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
249 additions
and
55 deletions
+249
-55
App.tsx
App.tsx
+112
-18
build.gradle
android/app/build.gradle
+1
-1
MyModuleMdd.kt
...oid/app/src/main/java/com/rn_mdd_simulator/MyModuleMdd.kt
+136
-36
No files found.
App.tsx
View file @
fca91b54
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
View
,
Button
,
Text
,
NativeModules
,
Platform
,
NativeEventEmitter
,
StyleSheet
,
TouchableOpacity
,
ActivityIndicator
,
}
from
'react-native'
;
const
MyModuleMdd
=
NativeModules
.
MyModuleMdd
;
...
...
@@ -13,7 +15,7 @@ const MyCustomEventEmitter = new NativeEventEmitter(MyModuleMdd);
const
App
=
()
=>
{
const
[
balance
,
setBalance
]
=
useState
(
0
);
const
[
nfcInitialized
]
=
useState
(
false
);
const
[
nfcInitialized
,
setNfcInitialized
]
=
useState
(
false
);
useEffect
(()
=>
{
if
(
Platform
.
OS
===
'android'
)
{
...
...
@@ -21,40 +23,132 @@ const App = () => {
if
(
MyModuleMdd
)
{
// Initialize MyNFCModuleMdd
MyModuleMdd
.
initNfc
();
setNfcInitialized
(
true
);
}
else
{
console
.
error
(
'MyNFCModuleMdd is not available.'
);
}
}
},
[]);
MyCustomEventEmitter
.
addListener
(
'MyEvent'
,
event
=>
{
console
.
log
(
event
.
message
);
});
useEffect
(()
=>
{
const
eventListener
=
MyCustomEventEmitter
.
addListener
(
'MyEvent'
,
event
=>
{
console
.
log
(
'Received event:'
,
event
.
message
);
try
{
// Try to parse the message as JSON
const
data
=
JSON
.
parse
(
event
.
message
);
// Check if this is a card info response
if
(
data
.
balance
!==
undefined
)
{
setBalance
(
data
.
balance
);
console
.
log
(
'Balance updated:'
,
data
.
balance
);
}
}
catch
(
error
)
{
// If it's not JSON, it's probably just a status message
console
.
log
(
'Status message:'
,
event
.
message
);
}
});
// Cleanup listener on component unmount
return
()
=>
{
eventListener
.
remove
();
};
},
[]);
const
handleUpdateBalance
=
()
=>
{
const
newBalance
=
100
;
// Example new balance
console
.
warn
(
nfcInitialized
);
const
newBalance
=
5000
;
// Setting to 5000 to clearly see the change
console
.
log
(
'Attempting to update balance to:'
,
newBalance
);
// Always reinitialize NFC before update to ensure fresh state
MyModuleMdd
.
initNfc
();
MyModuleMdd
.
updateBalance
(
newBalance
);
// You can also call a method to retrieve the updated balance here if needed
setNfcInitialized
(
true
);
// Short delay to ensure NFC is ready
setTimeout
(()
=>
{
MyModuleMdd
.
updateBalance
(
newBalance
);
},
500
);
};
const
handleGetBalance
=
()
=>
{
MyModuleMdd
.
initNfc
();
if
(
!
nfcInitialized
)
{
MyModuleMdd
.
initNfc
();
setNfcInitialized
(
true
);
}
MyModuleMdd
.
getBalance
();
};
return
(
<
View
style=
{
{
flex
:
1
,
justifyContent
:
'center'
,
alignItems
:
'center'
}
}
>
<
Text
>
Current Balance:
{
balance
}
</
Text
>
{
Platform
.
OS
===
'android'
&&
(
<
Button
title=
"Update Balance"
onPress=
{
handleUpdateBalance
}
/>
const
[
loading
,
_setLoading
]
=
useState
(
false
);
interface
CustomButtonProps
{
title
:
string
;
onPress
:
()
=>
void
;
disabled
?:
boolean
;
}
const
CustomButton
=
({
title
,
onPress
,
disabled
=
false
,
}:
CustomButtonProps
)
=>
(
<
TouchableOpacity
style=
{
[
styles
.
button
,
disabled
&&
styles
.
disabledButton
]
}
onPress=
{
onPress
}
disabled=
{
disabled
}
>
{
loading
?
(
<
ActivityIndicator
color=
"#fff"
/>
)
:
(
<
Text
style=
{
styles
.
buttonText
}
>
{
title
}
</
Text
>
)
}
<
Button
title=
"Get Balance"
onPress=
{
handleGetBalance
}
/>
</
TouchableOpacity
>
);
return
(
<
View
style=
{
styles
.
container
}
>
<
Text
style=
{
styles
.
balanceText
}
>
Current Balance:
{
balance
}
</
Text
>
<
View
style=
{
styles
.
buttonContainer
}
>
{
Platform
.
OS
===
'android'
&&
(
<
CustomButton
title=
"Update Balance"
onPress=
{
handleUpdateBalance
}
disabled=
{
loading
}
/>
)
}
<
CustomButton
title=
"Get Balance"
onPress=
{
handleGetBalance
}
disabled=
{
loading
}
/>
</
View
>
</
View
>
);
};
const
styles
=
StyleSheet
.
create
({
container
:
{
flex
:
1
,
justifyContent
:
'center'
,
alignItems
:
'center'
,
padding
:
20
,
},
balanceText
:
{
fontSize
:
18
,
marginBottom
:
20
,
},
buttonContainer
:
{
width
:
'100%'
,
maxWidth
:
300
,
},
button
:
{
backgroundColor
:
'#007bff'
,
padding
:
15
,
borderRadius
:
5
,
alignItems
:
'center'
,
marginVertical
:
10
,
},
disabledButton
:
{
backgroundColor
:
'#6c757d'
,
},
buttonText
:
{
color
:
'#fff'
,
fontSize
:
16
,
fontWeight
:
'bold'
,
},
});
export
default
App
;
android/app/build.gradle
View file @
fca91b54
...
...
@@ -116,7 +116,7 @@ repositories {
dependencies
{
// The version of react-native is set by the React Native Gradle Plugin
implementation
(
group:
'com.mdd.topup'
,
name:
'mdd_nfc_manager_android-release'
,
version:
'1.0.
4
'
,
ext:
'aar'
)
implementation
(
group:
'com.mdd.topup'
,
name:
'mdd_nfc_manager_android-release'
,
version:
'1.0.
12
'
,
ext:
'aar'
)
//retrofit
implementation
(
"io.reactivex.rxjava2:rxjava:2.2.19"
)
...
...
android/app/src/main/java/com/rn_mdd_simulator/MyModuleMdd.kt
View file @
fca91b54
...
...
@@ -18,6 +18,7 @@ import id.mdd.mdd_nfc_manager_android.models.CardInfoObject
class
MyModuleMdd
(
private
val
reactContext
:
ReactApplicationContext
)
:
ReactContextBaseJavaModule
(
reactContext
),
ActivityEventListener
,
LifecycleEventListener
{
private
var
currentState
=
MddNfcManager
.
NfcState
.
CARD_INFO
private
var
pendingBalance
:
Double
?
=
null
private
val
TAG
:
String
=
"MyModuleMdd"
private
var
nfcManager
:
MddNfcManager
?
=
null
private
var
eventEmitter
:
DeviceEventManagerModule
.
RCTDeviceEventEmitter
?
=
null
...
...
@@ -29,20 +30,25 @@ class MyModuleMdd(private val reactContext: ReactApplicationContext) :
override
fun
initialize
()
{
super
.
initialize
()
reactContext
.
addActivityEventListener
(
this
)
;
reactContext
.
addLifecycleEventListener
(
this
)
;
reactContext
.
addActivityEventListener
(
this
)
reactContext
.
addLifecycleEventListener
(
this
)
eventEmitter
=
reactApplicationContext
.
getJSModule
(
DeviceEventManagerModule
.
RCTDeviceEventEmitter
::
class
.
java
)
nfcManager
=
MddNfcManager
(
reactApplicationContext
,
currentActivity
,
"1234567abc"
,
"165eea86947a4e9483d1902f93495fc6"
,
"355933093746314"
,
0
)
try
{
nfcManager
=
MddNfcManager
(
reactApplicationContext
,
currentActivity
,
"1234567abc"
,
"165eea86947a4e9483d1902f93495fc6"
,
"355933093746314"
,
1
)
println
(
"NFC Manager initialized successfully"
)
}
catch
(
e
:
Exception
)
{
println
(
"Error initializing NFC Manager: ${e.message}"
)
}
}
override
fun
onCatalystInstanceDestroy
()
{
...
...
@@ -53,31 +59,55 @@ class MyModuleMdd(private val reactContext: ReactApplicationContext) :
@ReactMethod
fun
initNfc
()
{
println
(
"initNfc called"
)
nfcManager
?.
startNfc
()
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"initNfc triggered from Kotlin!"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
try
{
if
(
nfcManager
==
null
)
{
println
(
"Reinitializing NFC Manager"
)
nfcManager
=
MddNfcManager
(
reactApplicationContext
,
currentActivity
,
"1234567abc"
,
"165eea86947a4e9483d1902f93495fc6"
,
"355933093746314"
,
1
)
}
nfcManager
?.
startNfc
()
println
(
"NFC started successfully"
)
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"NFC initialized and started"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
}
catch
(
e
:
Exception
)
{
println
(
"Error in initNfc: ${e.message}"
)
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"Error initializing NFC: ${e.message}"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
}
}
@ReactMethod
fun
updateBalance
(
newBalance
:
Double
)
{
// Update balance code
p
rintln
(
"update balance called"
)
println
(
"update balance called with: $newBalance"
)
p
endingBalance
=
newBalance
currentState
=
MddNfcManager
.
NfcState
.
UPDATE
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"
update balance triggered from Kotlin!
"
)
params
.
putString
(
"message"
,
"
Please tap your card to update balance
"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
// Ensure NFC is started
nfcManager
?.
startNfc
()
}
@ReactMethod
fun
getBalance
()
{
// Get balance code
println
(
"get balance called"
)
currentState
=
MddNfcManager
.
NfcState
.
CARD_INFO
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"
get balance triggered from Kotlin!
"
)
params
.
putString
(
"message"
,
"
Please tap your card to read balance
"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
// Ensure NFC is started
nfcManager
?.
startNfc
()
}
override
fun
onActivityResult
(
p0
:
Activity
?,
p1
:
Int
,
p2
:
Int
,
p3
:
Intent
?)
{
...
...
@@ -85,36 +115,106 @@ class MyModuleMdd(private val reactContext: ReactApplicationContext) :
}
override
fun
onNewIntent
(
intent
:
Intent
)
{
Log
.
d
(
TAG
,
"onNewIntent"
)
Log
.
d
(
TAG
,
"onNewIntent received"
)
println
(
"Current NFC State: $currentState"
)
if
(
currentState
==
MddNfcManager
.
NfcState
.
CARD_INFO
)
{
nfcManager
?.
getCardInfo
(
intent
,
object
:
MddNfcManager
.
LibraryCallback
{
override
fun
onResult
(
result
:
CardInfoObject
)
{
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
Gson
().
toJson
(
result
))
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
}
})
}
else
if
(
currentState
==
MddNfcManager
.
NfcState
.
UPDATE
)
{
nfcManager
?.
update
(
intent
,
"081518012374"
,
"developer@gmail.com"
,
object
:
MddNfcManager
.
LibraryCallback
{
override
fun
onResult
(
result
:
CardInfoObject
)
{
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
Gson
().
toJson
(
result
))
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
try
{
println
(
"Starting to read card info..."
)
println
(
"NFC Manager instance: $nfcManager"
)
nfcManager
?.
getCardInfo
(
intent
,
object
:
MddNfcManager
.
LibraryCallback
{
override
fun
onResult
(
result
:
CardInfoObject
)
{
println
(
"Card info received: ${Gson().toJson(result)}"
)
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
Gson
().
toJson
(
result
))
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
}
})
}
catch
(
e
:
Exception
)
{
println
(
"Error reading card: ${e.message}"
)
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"Error reading card: ${e.message}"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
}
}
else
if
(
currentState
==
MddNfcManager
.
NfcState
.
UPDATE
&&
pendingBalance
!=
null
)
{
try
{
println
(
"Starting balance update with value: $pendingBalance"
)
println
(
"NFC Manager instance: $nfcManager"
)
println
(
"Current state before update: $currentState"
)
if
(
nfcManager
==
null
)
{
throw
Exception
(
"NFC Manager is null"
)
}
})
val
balanceToUpdate
=
pendingBalance
// Store for verification
nfcManager
?.
update
(
intent
,
balanceToUpdate
.
toString
(),
"081518012374"
,
object
:
MddNfcManager
.
LibraryCallback
{
override
fun
onResult
(
result
:
CardInfoObject
)
{
println
(
"Update callback received with result: ${Gson().toJson(result)}"
)
// Verify the update
println
(
"Expected balance: $balanceToUpdate"
)
println
(
"Actual balance in result: ${result.balance}"
)
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
Gson
().
toJson
(
result
))
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
// Reset state after successful update
currentState
=
MddNfcManager
.
NfcState
.
CARD_INFO
pendingBalance
=
null
}
}
)
println
(
"Update method called successfully"
)
}
catch
(
e
:
Exception
)
{
println
(
"Error in update method: ${e.message}"
)
println
(
"Stack trace: ${e.stackTrace.joinToString("
\
n
")}"
)
val
params
=
WritableNativeMap
()
params
.
putString
(
"message"
,
"Error updating balance: ${e.message}"
)
eventEmitter
?.
emit
(
"MyEvent"
,
params
)
// Reset state on error
currentState
=
MddNfcManager
.
NfcState
.
CARD_INFO
pendingBalance
=
null
}
}
}
override
fun
onHostResume
()
{
Log
.
d
(
TAG
,
"onHostResume"
)
try
{
// Reinitialize NFC when app resumes if needed
if
(
nfcManager
==
null
)
{
println
(
"Reinitializing NFC Manager on resume"
)
nfcManager
=
MddNfcManager
(
reactApplicationContext
,
currentActivity
,
"1234567abc"
,
"165eea86947a4e9483d1902f93495fc6"
,
"355933093746314"
,
1
)
}
nfcManager
?.
startNfc
()
println
(
"NFC restarted on resume"
)
}
catch
(
e
:
Exception
)
{
println
(
"Error restarting NFC on resume: ${e.message}"
)
}
}
override
fun
onHostPause
()
{
Log
.
d
(
TAG
,
"onHostPause"
)
// Keep track of current state
println
(
"App paused with NFC state: $currentState"
)
}
override
fun
onHostDestroy
()
{
Log
.
d
(
TAG
,
"onHostDestroy"
)
// Clean up resources
nfcManager
=
null
eventEmitter
=
null
}
}
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