diff --git a/doc/source/apis.rst b/doc/source/apis.rst index 21af814db9..4ad1e97adc 100644 --- a/doc/source/apis.rst +++ b/doc/source/apis.rst @@ -342,18 +342,28 @@ or categories filters. The callback will be called in another thread than the main thread. In that thread, be careful not to access OpenGL or something like that. - .. method:: __init__(callback, actions=None, categories=None) + .. method:: __init__(callback, actions=None, categories=None, exported=False) :param callback: function or method that will receive the event. Will receive the context and intent as argument. :param actions: list of strings that represent an action. :param categories: list of strings that represent a category. + :param exported: if `True`, other applications are allowed to send + broadcasts to this receiver. Defaults to `False`. For actions and categories, the string must be in lower case, without the prefix:: # In java: Intent.ACTION_HEADSET_PLUG # In python: 'headset_plug' + .. note:: + + Since Android 14 (API 34), receivers must be registered with + ``RECEIVER_EXPORTED`` or ``RECEIVER_NOT_EXPORTED``. The default + (``exported=False``) uses ``RECEIVER_NOT_EXPORTED``, so only your + own application and the system can send broadcasts to this + receiver. + .. method:: start() Register the receiver with all the actions and categories, and start diff --git a/pythonforandroid/recipes/android/src/android/broadcast.py b/pythonforandroid/recipes/android/src/android/broadcast.py index cc8e06aee4..99c9723e09 100644 --- a/pythonforandroid/recipes/android/src/android/broadcast.py +++ b/pythonforandroid/recipes/android/src/android/broadcast.py @@ -22,10 +22,11 @@ def __init__(self, callback, *args, **kwargs): def onReceive(self, context, intent): self.callback(context, intent) - def __init__(self, callback, actions=None, categories=None): + def __init__(self, callback, actions=None, categories=None, exported=False): super().__init__() self.callback = callback self._is_registered = False + self.exported = exported if not actions and not categories: raise Exception('You need to define at least actions or categories') @@ -77,10 +78,23 @@ def start(self): Handler = autoclass('android.os.Handler') self.handler = Handler(self.handlerthread.getLooper()) - self.context.registerReceiver( - self.receiver, self.receiver_filter, None, self.handler) + self._register_receiver() self._is_registered = True + def _register_receiver(self): + if autoclass('android.os.Build$VERSION').SDK_INT >= 33: + # API 34+ requires RECEIVER_EXPORTED / RECEIVER_NOT_EXPORTED + Context = autoclass('android.content.Context') + if self.exported: + flags = Context.RECEIVER_EXPORTED + else: + flags = Context.RECEIVER_NOT_EXPORTED + self.context.registerReceiver( + self.receiver, self.receiver_filter, None, self.handler, flags) + else: + self.context.registerReceiver( + self.receiver, self.receiver_filter, None, self.handler) + def stop(self): try: self.context.unregisterReceiver(self.receiver)