-
Notifications
You must be signed in to change notification settings - Fork 2
/
nfc.py
138 lines (107 loc) · 4.01 KB
/
nfc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from random import randint, choice
from time import sleep
from kivy.clock import Clock
from kivy.utils import platform
from toast import toast
nfc_instance = None
class NFC:
def __init__(self):
self._action = None
self.j_context = context = PythonActivity.mActivity
self.nfc_adapter = NfcAdapter.getDefaultAdapter(context)
self.nfc_pending_intent = PendingIntent.getActivity(
context, 0,
Intent(context, context.getClass()).addFlags(
Intent.FLAG_ACTIVITY_SINGLE_TOP
),
0
)
self.on_new_intenting = False
self.resuming = False
self.dispatched = False
self.nfc_enable_ndef_exchange()
activity.bind(on_new_intent=self.on_new_intent)
def register_action(self, action):
self._action = action
def remove_action(self, action):
if self._action == action:
self._action = None
self.nfc_disable_ndef_exchange()
else:
# raise ValueError('Action isn\' defined')
toast('Action isn\' defined')
def on_new_intent(self, intent):
self.on_new_intenting = True
sleep(0.25)
while self.resuming:
sleep(0.1)
if intent.getAction() != NfcAdapter.ACTION_TAG_DISCOVERED:
toast('unknow action, avoid.')
return
tag_id = ''
for i in intent.getByteArrayExtra(NfcAdapter.EXTRA_ID).tolist():
tag_id += hex(i & 0xff)[2:]
if self._action:
self._action(tag_id)
self.on_new_intenting = False
# @run_on_ui_thread
def nfc_enable_ndef_exchange(self):
if self.on_new_intenting: # let it run, don't bother about initialising to saved
return
self.resuming = True
print 'Resume'
inten = Intent(self.j_context, self.j_context.getClass())
inten.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
pending_intent = PendingIntent.getActivity(self.j_context, 0, inten, 0)
intent_filter = IntentFilter()
intent_filter.addAction(NfcAdapter.ACTION_TAG_DISCOVERED)
intent_filter.addCategory(Intent.CATEGORY_DEFAULT)
intent_filter.addDataType("text/plain")
try:
if not self.dispatched:
self.nfc_adapter.enableForegroundDispatch(
self.j_context,
pending_intent,
[intent_filter],
[[]]
)
except JavaException as e:
print 'Java Error', e
self.dispatched = True
self.resuming = False
# @run_on_ui_thread
def nfc_disable_ndef_exchange(self):
self.nfc_adapter.disableForegroundDispatch(self.j_context)
self.dispatched = False
class FakeNFC:
def __init__(self):
self._action = None
def register_action(self, action):
self._action = action
Clock.schedule_once(self.on_new_intent, 0)
def remove_action(self, action):
if self._action == action:
self._action = None
Clock.unschedule(self.on_new_intent)
else:
# raise ValueError('Action isn\' defined')
toast('Action isn\' defined')
def on_new_intent(self, *args):
tag_id = ''.join([chr(randint(65, 90)) for i in range(6)])
tag_id = choice(['xllpoj', 'aymoqf'])
if self._action:
self._action(tag_id.lower())
Clock.schedule_interval(self.on_new_intent, 10)
if not nfc_instance:
if platform == 'android':
from jnius import autoclass
from jnius.jnius import JavaException
from android import activity
NfcAdapter = autoclass('android.nfc.NfcAdapter')
PythonActivity = autoclass('org.renpy.android.PythonActivity')
Intent = autoclass('android.content.Intent')
IntentFilter = autoclass('android.content.IntentFilter')
PendingIntent = autoclass('android.app.PendingIntent')
nfc_instance = NFC()
else:
nfc_instance = FakeNFC()