Mercurial > libervia-backend
comparison sat/plugins/plugin_misc_android.py @ 2887:9aadf11b315b
plugin android: check connectivity
use Android API to retrieve connectivity informations (connection availability + kind of connection).
Register to connectivity change broadcast, new client.networkEnabled/client.networkDisabled are called when suitable.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 06 Apr 2019 19:05:58 +0200 |
parents | 0c54970d8e6e |
children | 758bee45612b |
comparison
equal
deleted
inserted
replaced
2886:b06cb71079fa | 2887:9aadf11b315b |
---|---|
47 if sys.platform != "android": | 47 if sys.platform != "android": |
48 raise exceptions.CancelError(u"this module is not needed on this platform") | 48 raise exceptions.CancelError(u"this module is not needed on this platform") |
49 | 49 |
50 | 50 |
51 from plyer import notification, vibrator | 51 from plyer import notification, vibrator |
52 from plyer.platforms.android import activity | |
53 from jnius import autoclass | |
54 from android.broadcast import BroadcastReceiver | |
52 | 55 |
53 #: delay between a pause event and sending the inactive indication to server, in seconds | 56 #: delay between a pause event and sending the inactive indication to server, in seconds |
54 #: we don't send the indication immediately because user can be just checking something | 57 #: we don't send the indication immediately because user can be just checking something |
55 #: quickly on an other app. | 58 #: quickly on an other app. |
56 CSI_DELAY = 30 | 59 CSI_DELAY = 30 |
62 SOCKET_FILE = ".socket" | 65 SOCKET_FILE = ".socket" |
63 STATE_RUNNING = "running" | 66 STATE_RUNNING = "running" |
64 STATE_PAUSED = "paused" | 67 STATE_PAUSED = "paused" |
65 STATE_STOPPED = "stopped" | 68 STATE_STOPPED = "stopped" |
66 STATES = (STATE_RUNNING, STATE_PAUSED, STATE_STOPPED) | 69 STATES = (STATE_RUNNING, STATE_PAUSED, STATE_STOPPED) |
70 NET_TYPE_NONE = "no network" | |
71 NET_TYPE_WIFI = "wifi" | |
72 NET_TYPE_MOBILE = "mobile" | |
73 NET_TYPE_OTHER = "other" | |
74 | |
75 | |
76 Context = autoclass('android.content.Context') | |
77 ConnectivityManager = autoclass('android.net.ConnectivityManager') | |
67 | 78 |
68 | 79 |
69 def determineLength_workaround(self, fObj): | 80 def determineLength_workaround(self, fObj): |
70 """Method working around seek() bug on Android""" | 81 """Method working around seek() bug on Android""" |
71 try: | 82 try: |
165 raise e | 176 raise e |
166 # we set a low priority because we want the notification to be sent after all | 177 # we set a low priority because we want the notification to be sent after all |
167 # plugins have done their job | 178 # plugins have done their job |
168 host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=-1000) | 179 host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=-1000) |
169 | 180 |
181 # Connectivity handling | |
182 self.cm = activity.getSystemService(Context.CONNECTIVITY_SERVICE) | |
183 self._net_type = None | |
184 self._checkConnectivity() | |
185 # XXX: we need to keep a reference to BroadcastReceiver to avoid | |
186 # "XXX has no attribute 'invoke'" error (looks like the same issue as | |
187 # https://github.com/kivy/pyjnius/issues/59) | |
188 self.br = BroadcastReceiver( | |
189 callback=lambda *args, **kwargs: reactor.callLater(0, | |
190 self.onConnectivityChange), | |
191 actions=[u"android.net.conn.CONNECTIVITY_CHANGE"]) | |
192 self.br.start() | |
193 | |
194 | |
170 @property | 195 @property |
171 def state(self): | 196 def state(self): |
172 return self._state | 197 return self._state |
173 | 198 |
174 @state.setter | 199 @state.setter |
246 if self._csi_timer is not None: | 271 if self._csi_timer is not None: |
247 self._csi_timer.cancel() | 272 self._csi_timer.cancel() |
248 self._csi_timer = None | 273 self._csi_timer = None |
249 for client in self.host.getClients(C.PROF_KEY_ALL): | 274 for client in self.host.getClients(C.PROF_KEY_ALL): |
250 self._csi.setActive(client) | 275 self._csi.setActive(client) |
276 | |
277 # Connectivity | |
278 | |
279 def _handleNetworkChange(self, previous, new): | |
280 """Notify the clients about network changes. | |
281 | |
282 This way the client can disconnect/reconnect transport, or change delays | |
283 """ | |
284 if new == NET_TYPE_NONE: | |
285 for client in self.host.getClients(C.PROF_KEY_ALL): | |
286 client.networkDisabled() | |
287 elif previous == NET_TYPE_NONE: | |
288 for client in self.host.getClients(C.PROF_KEY_ALL): | |
289 client.networkEnabled() | |
290 | |
291 def _checkConnectivity(self): | |
292 active_network = self.cm.getActiveNetworkInfo() | |
293 if active_network is None: | |
294 net_type = NET_TYPE_NONE | |
295 else: | |
296 net_type_android = active_network.getType() | |
297 if net_type_android == ConnectivityManager.TYPE_WIFI: | |
298 net_type = NET_TYPE_WIFI | |
299 elif net_type_android == ConnectivityManager.TYPE_MOBILE: | |
300 net_type = NET_TYPE_MOBILE | |
301 else: | |
302 net_type = NET_TYPE_OTHER | |
303 if net_type != self._net_type: | |
304 log.info(u"connectivity has changed") | |
305 previous = self._net_type | |
306 self._net_type = net_type | |
307 if net_type == NET_TYPE_NONE: | |
308 log.info(u"no network active") | |
309 elif net_type == NET_TYPE_WIFI: | |
310 log.info(u"WIFI activated") | |
311 elif net_type == NET_TYPE_MOBILE: | |
312 log.info(u"mobile data activated") | |
313 else: | |
314 log.info(u"network activated (type={net_type_android})" | |
315 .format(net_type_android=net_type_android)) | |
316 self._handleNetworkChange(previous, net_type) | |
317 else: | |
318 log.debug(u"_checkConnectivity called without network change ({net_type})" | |
319 .format(net_type = net_type)) | |
320 | |
321 | |
322 def onConnectivityChange(self): | |
323 log.debug(u"onConnectivityChange called") | |
324 self._checkConnectivity() |