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.
This commit is contained in:
Goffi 2019-04-06 19:05:58 +02:00
commit 30bf1362bb

View file

@ -49,6 +49,9 @@ if sys.platform != "android":
from plyer import notification, vibrator
from plyer.platforms.android import activity
from jnius import autoclass
from android.broadcast import BroadcastReceiver
#: delay between a pause event and sending the inactive indication to server, in seconds
#: we don't send the indication immediately because user can be just checking something
@ -64,6 +67,14 @@ STATE_RUNNING = "running"
STATE_PAUSED = "paused"
STATE_STOPPED = "stopped"
STATES = (STATE_RUNNING, STATE_PAUSED, STATE_STOPPED)
NET_TYPE_NONE = "no network"
NET_TYPE_WIFI = "wifi"
NET_TYPE_MOBILE = "mobile"
NET_TYPE_OTHER = "other"
Context = autoclass('android.content.Context')
ConnectivityManager = autoclass('android.net.ConnectivityManager')
def determineLength_workaround(self, fObj):
@ -167,6 +178,20 @@ class AndroidPlugin(object):
# plugins have done their job
host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=-1000)
# Connectivity handling
self.cm = activity.getSystemService(Context.CONNECTIVITY_SERVICE)
self._net_type = None
self._checkConnectivity()
# XXX: we need to keep a reference to BroadcastReceiver to avoid
# "XXX has no attribute 'invoke'" error (looks like the same issue as
# https://github.com/kivy/pyjnius/issues/59)
self.br = BroadcastReceiver(
callback=lambda *args, **kwargs: reactor.callLater(0,
self.onConnectivityChange),
actions=[u"android.net.conn.CONNECTIVITY_CHANGE"])
self.br.start()
@property
def state(self):
return self._state
@ -248,3 +273,52 @@ class AndroidPlugin(object):
self._csi_timer = None
for client in self.host.getClients(C.PROF_KEY_ALL):
self._csi.setActive(client)
# Connectivity
def _handleNetworkChange(self, previous, new):
"""Notify the clients about network changes.
This way the client can disconnect/reconnect transport, or change delays
"""
if new == NET_TYPE_NONE:
for client in self.host.getClients(C.PROF_KEY_ALL):
client.networkDisabled()
elif previous == NET_TYPE_NONE:
for client in self.host.getClients(C.PROF_KEY_ALL):
client.networkEnabled()
def _checkConnectivity(self):
active_network = self.cm.getActiveNetworkInfo()
if active_network is None:
net_type = NET_TYPE_NONE
else:
net_type_android = active_network.getType()
if net_type_android == ConnectivityManager.TYPE_WIFI:
net_type = NET_TYPE_WIFI
elif net_type_android == ConnectivityManager.TYPE_MOBILE:
net_type = NET_TYPE_MOBILE
else:
net_type = NET_TYPE_OTHER
if net_type != self._net_type:
log.info(u"connectivity has changed")
previous = self._net_type
self._net_type = net_type
if net_type == NET_TYPE_NONE:
log.info(u"no network active")
elif net_type == NET_TYPE_WIFI:
log.info(u"WIFI activated")
elif net_type == NET_TYPE_MOBILE:
log.info(u"mobile data activated")
else:
log.info(u"network activated (type={net_type_android})"
.format(net_type_android=net_type_android))
self._handleNetworkChange(previous, net_type)
else:
log.debug(u"_checkConnectivity called without network change ({net_type})"
.format(net_type = net_type))
def onConnectivityChange(self):
log.debug(u"onConnectivityChange called")
self._checkConnectivity()