Skip to content

Commit

Permalink
add service_advertise example #27
Browse files Browse the repository at this point in the history
  • Loading branch information
b3b committed Aug 15, 2021
1 parent 895f3c6 commit ee37a6c
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 17 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Changelog
=========

1.0.8
-----

* Added support to use `able` in Android services
* Added decorators:

- `able.require_bluetooth_enabled`: to call `BluetoothDispatcher` method when bluetooth adapter becomes ready
- `able.require_runtime_permissions`: to call `BluetoothDispatcher` method when location runtime permission is granted


1.0.7
-----

Expand Down
20 changes: 18 additions & 2 deletions docs/example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,28 @@ BLE devices scanning service

**main.py**

.. literalinclude:: ./examples/service_main.py
.. literalinclude:: ./examples/service_scan_main.py
:language: python

**service.py**

.. literalinclude:: ./examples/service_service.py
.. literalinclude:: ./examples/service_scan_service.py
:language: python

Full example code: `service_scan <https://github.com/b3b/able/blob/master/examples/service_scan/>`_


Adverising service
^^^^^^^^^^^^^^^^^^

**main.py**

.. literalinclude:: ./examples/service_advertise_main.py
:language: python

**service.py**

.. literalinclude:: ./examples/service_advertise_service.py
:language: python

Full example code: `service_advertice <https://github.com/b3b/able/blob/master/examples/service_advertise/>`_
15 changes: 15 additions & 0 deletions examples/service_advertise/buildozer.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[app]
title = BLE service
version = 1.0
package.name = service
package.domain = test.able
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
android.permissions = BLUETOOTH,BLUETOOTH_ADMIN,ACCESS_FINE_LOCATION,FOREGROUND_SERVICE
requirements = kivy==2.0.0,plyer==2.0.0,python3,able_recipe
services = Able:service.py:foreground

[buildozer]
warn_on_root = 1
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2
51 changes: 51 additions & 0 deletions examples/service_advertise/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Start advertising service."""
from able import BluetoothDispatcher, require_bluetooth_enabled
from jnius import autoclass
from kivy.app import App
from kivy.lang import Builder


kv = """
BoxLayout:
Button:
text: 'Start service'
on_press: app.ble_dispatcher.start_service()
Button:
text: 'Stop service'
on_press: app.ble_dispatcher.stop_service()
"""


class Dispatcher(BluetoothDispatcher):

@property
def service(self):
return autoclass("test.able.service.ServiceAble")

@property
def activity(self):
return autoclass("org.kivy.android.PythonActivity").mActivity

# Need to turn on the adapter, before service is started
@require_bluetooth_enabled
def start_service(self):
self.service.start(
self.activity,
# Pass UUID to advertise
"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
)
App.get_running_app().stop() # Can close the app, service will continue running

def stop_service(self):
self.service.stop(self.activity)


class ServiceApp(App):

def build(self):
self.ble_dispatcher = Dispatcher()
return Builder.load_string(kv)


if __name__ == "__main__":
ServiceApp().run()
28 changes: 28 additions & 0 deletions examples/service_advertise/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Service to advertise data, while not stopped."""
import time
from os import environ

from able import BluetoothDispatcher
from able.advertising import (
Advertiser,
AdvertiseData,
ServiceUUID,
)


def main():
uuid = environ.get(
"PYTHON_SERVICE_ARGUMENT",
"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
)
advertiser = Advertiser(
ble=BluetoothDispatcher(),
data=AdvertiseData(ServiceUUID(uuid)),
)
advertiser.start()
while True:
time.sleep(0xDEAD)


if __name__ == "__main__":
main()
15 changes: 15 additions & 0 deletions examples/service_advertise/service_scan/buildozer.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[app]
title = BLE service
version = 1.0
package.name = service
package.domain = test.able
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
android.permissions = BLUETOOTH,BLUETOOTH_ADMIN,ACCESS_FINE_LOCATION,FOREGROUND_SERVICE
requirements = kivy==2.0.0,plyer==2.0.0,python3,http://herethere.me:8080/able.zip
services = Able:service.py:foreground

[buildozer]
warn_on_root = 1
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2
51 changes: 51 additions & 0 deletions examples/service_advertise/service_scan/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Start advertising service."""
from able import BluetoothDispatcher, require_bluetooth_enabled
from jnius import autoclass
from kivy.app import App
from kivy.lang import Builder


kv = """
BoxLayout:
Button:
text: 'Start service'
on_press: app.ble_dispatcher.start_service()
Button:
text: 'Stop service'
on_press: app.ble_dispatcher.stop_service()
"""


class Dispatcher(BluetoothDispatcher):

@property
def service(self):
return autoclass("test.able.service.ServiceAble")

@property
def activity(self):
return autoclass("org.kivy.android.PythonActivity").mActivity

# Need to turn on the adapter, before service is started
@require_bluetooth_enabled
def start_service(self):
self.service.start(
self.activity,
# Pass UUID to advertise
"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
)
App.get_running_app().stop() # Can close the app, service will continue running

def stop_service(self):
self.service.stop(self.activity)


class ServiceApp(App):

def build(self):
self.ble_dispatcher = Dispatcher()
return Builder.load_string(kv)


if __name__ == "__main__":
ServiceApp().run()
28 changes: 28 additions & 0 deletions examples/service_advertise/service_scan/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Service to advertise data, while not stopped."""
import time
from os import environ

from able import BluetoothDispatcher
from able.advertising import (
Advertiser,
AdvertiseData,
ServiceUUID,
)


def main():
uuid = environ.get(
"PYTHON_SERVICE_ARGUMENT",
"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
)
advertiser = Advertiser(
ble=BluetoothDispatcher(),
data=AdvertiseData(ServiceUUID(uuid)),
)
advertiser.start()
while True:
time.sleep(0xDEAD)


if __name__ == "__main__":
main()
8 changes: 4 additions & 4 deletions examples/service_scan/buildozer.spec
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[app]
title = BLE scan service
title = BLE service
version = 1.0
package.name = service_scan
package.name = service
package.domain = test.able
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
android.permissions = BLUETOOTH,BLUETOOTH_ADMIN,ACCESS_FINE_LOCATION,FOREGROUND_SERVICE
requirements = kivy==2.0.0,plyer==2.0.0,python3,http://herethere.me:8080/able.zip
services = Scan:service.py:foreground
requirements = kivy==2.0.0,plyer==2.0.0,python3,able_recipe
services = Able:service.py:foreground

[buildozer]
warn_on_root = 1
Expand Down
19 changes: 8 additions & 11 deletions examples/service_scan/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
BoxLayout:
Button:
text: 'Start service'
on_press: app.scanner.start_service()
on_press: app.ble_dispatcher.start_service()
Button:
text: 'Stop service'
on_press: app.scanner.stop_service()
on_press: app.ble_dispatcher.stop_service()
"""


class Scanner(BluetoothDispatcher):
class Dispatcher(BluetoothDispatcher):

@property
def service(self):
return autoclass("test.able.service_scan.ServiceScan")
return autoclass("test.able.service.ServiceAble")

@property
def activity(self):
Expand All @@ -31,21 +31,18 @@ def activity(self):
@require_runtime_permissions
def start_service(self):
self.service.start(self.activity, "")
self.stop() # Can close the app, service will continue running
App.get_running_app().stop() # Can close the app, service will continue to run

def stop_service(self):
self.service.stop(self.activity)


class ScannerApp(App):
class ServiceApp(App):

def build(self):
self.scanner = Scanner()
self.ble_dispatcher = Dispatcher()
return Builder.load_string(kv)

def start_service(self, *args, **kwargs):
Scanner().start_service()


if __name__ == "__main__":
ScannerApp().run()
ServiceApp().run()

0 comments on commit ee37a6c

Please sign in to comment.