Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geolocator #3179

Merged
merged 18 commits into from
May 24, 2024
Merged

Geolocator #3179

merged 18 commits into from
May 24, 2024

Conversation

lekshmanmj
Copy link
Contributor

@lekshmanmj lekshmanmj commented May 3, 2024

PR on GPS Location Feature
@FeodorFitsner @ndonkoHenri

As Stream function provided in Geolocator dart package just stops streaming when app is minimized, Initially I planned to implement location streaming using Background Service... But while trying that in a clean/pure flutter project itself I got stuck with some Kotlin version related error(which I couldn't solve). Therefore I finally decided to just have a normal function to get location in dart side and decided to call it explicitly in a loop in flet app using run_task/run_thread method to implement stream(to leave it to user's/developer's side) as implemented in the code.

playground/main.py

import flet as ft
import asyncio


def main(page: ft.Page):
    page.scroll = ft.ScrollMode.ADAPTIVE
    page.add(ft.SafeArea(ft.Text("Geolocator test")))
    gl = ft.Geolocator()
    page.overlay.append(gl)
    page.update()
    position = gl.get_location()
    page.add(
        ft.SafeArea(
            ft.Text(
                "latitude: {}, longitude: {}".format(
                    position.latitude, position.longitude
                )
            )
        )
    )
    page.add(ft.SafeArea(ft.Text("Geolocation Stream using Thread/AsyncTask")))

    async def loop():
        while True:
            position = await gl.get_location_async()
            page.add(
                ft.SafeArea(
                    ft.Text(
                        "latitude: {}, longitude: {}".format(
                            position.latitude, position.longitude
                        )
                    )
                )
            )
            await asyncio.sleep(1)

    page.run_task(loop)
    page.update()


ft.app(main)

@FeodorFitsner
Copy link
Contributor

Thank you! Useful control - great PR! 👍

I'm looking at the example for Geolocator widget: https://pub.dev/packages/geolocator#example

I think we need to implement methods to check/request permissions:

  • isLocationServiceEnabled()
  • checkPermission()
  • requestPermission()
  • LocationPermission enum.

We obviously can't rely on an assumption the location service is allowed/enabled on user's device, right?
What do you think?

@lekshmanmj
Copy link
Contributor Author

lekshmanmj commented May 4, 2024

Thank you! Useful control - great PR! 👍

I'm looking at the example for Geolocator widget: https://pub.dev/packages/geolocator#example

I think we need to implement methods to check/request permissions:

  • isLocationServiceEnabled()
  • checkPermission()
  • requestPermission()
  • LocationPermission enum.

We obviously can't rely on an assumption the location service is allowed/enabled on user's device, right? What do you think?

Permission.location.request().isGranted This line does the job..
way 1 - if Permission is not given : It prompts the user for both permission and to enable location service --> waits infinitely to get users response --> return true/false
way 2- If Permission is already granted: It just directly return true/false.
I have witnessed the above scenario while test in clean flutter project in my android device.

In dart side waiting event(to get response from permission and service prompt) happens for infinite amount of time, but in python side invoke_method was waiting only for 5 seconds. Within this time limit as we can't expect the end user to respond to permission and service prompt, ...have increased the waiting time passed to invoke_method from geolocator to 25 seconds.

I've ignorned package(geolocator) provided permission related function in current implementation, as I have better understanding about common PermissionHandler dart package.

Planned to add check_permission and request_permission functions to common flet_permission_handler feature(...will be submitting a PR on it shortly).

@ndonkoHenri
Copy link
Contributor

I've ignorned package(geolocator) provided permission related function in current implementation, as I have better understanding about common PermissionHandler dart package.

Seems like the permissions_handler package is limited to mobile only? 😯

In any case, I suggest we go for independence: expose all the possible methods provided by the geolocator package as they might be optimised for its specific use-case.
By the way, seems like geolocator does not depend on permissions_handler.

permission_handler package you implemented, will of course still be useful - perhaps not that much for the location-related checks, but for all others. (thanks for working on it!)

@lekshmanmj
Copy link
Contributor Author

lekshmanmj commented May 6, 2024

I've ignorned package(geolocator) provided permission related function in current implementation, as I have better understanding about common PermissionHandler dart package.

Seems like the permissions_handler package is limited to mobile only? 😯

In any case, I suggest we go for independence: expose all the possible methods provided by the geolocator package as they might be optimised for its specific use-case. By the way, seems like geolocator does not depend on permissions_handler.

permission_handler package you implemented, will of course still be useful - perhaps not that much for the location-related checks, but for all others. (thanks for working on it!)

image

yes... will expose all other functions of that package.
and please let me know what other functions do you expect to be present in flet implementation.

Geolocator is directly dependent on permission_handler.dart rather than on permission_handler which is recently implemented in flet.

permission_handler is intended to be used in rare scenarios only... like if user wish to check/get multiple permission on opening app.

@ndonkoHenri
Copy link
Contributor

ndonkoHenri commented May 7, 2024

So, I went on and added/updated some more stuffs such as permissions, utils and the exposed methods as suggested by Feodor.
I think your PR is now ready for it's v1. Additionally, if you have desire and time, you can pick up from here and expose more stuffs... (no problem when you can't - I could do that some other day).
Awesome work on this PR! 👏🏾

I tested simultaneously on 4 platforms and it worked: android, mac, web and ios - only windows is left out now.

XX

Updated Test Code

import flet as ft


async def main(page: ft.Page):
    page.window_always_on_top = True
    page.on_error = lambda e: print(f"Page Error: {e.data}")
    page.scroll = ft.ScrollMode.ADAPTIVE
    page.appbar = ft.AppBar(title=ft.Text("Geolocator Tests"))
    gl = ft.Geolocator()
    page.overlay.append(gl)

    settings_dlg = lambda handler: ft.AlertDialog(
        adaptive=True,
        title=ft.Text("Opening Location Settings..."),
        content=ft.Text(
            "You are about to be redirected to the location/app settings. "
            "Please locate this app and grant it location permissions."
        ),
        actions=[
            ft.TextButton(
                text="OK",
                on_click=handler,
            ),
        ],
        actions_alignment=ft.MainAxisAlignment.CENTER,
    )

    def handle_permission_request(e):
        page.add(ft.Text(f"request_permission: {gl.request_permission()}"))

    def handle_has_permission(e):
        page.add(ft.Text(f"has_permission: {gl.has_permission()}"))

    def handle_get_current_position(e):
        p = gl.get_current_position()
        page.add(ft.Text(f"get_current_position: ({p.latitude}, {p.longitude})"))

    def handle_get_last_known_position(e):
        p = gl.get_last_known_position()
        page.add(ft.Text(f"get_last_known_position: ({p.latitude}, {p.longitude})"))

    def handle_location_service_enabled(e):
        page.add(
            ft.Text(f"is_location_service_enabled: {gl.is_location_service_enabled()}")
        )

    def handle_open_location_settings(e):
        page.close_dialog()
        page.add(ft.Text(f"open_location_settings: {gl.open_location_settings()}"))

    def handle_open_app_settings(e):
        page.close_dialog()
        page.add(ft.Text(f"open_app_settings: {gl.open_app_settings()}"))

    page.add(
        ft.Row(
            [
                ft.OutlinedButton(
                    "request_permission",
                    on_click=handle_permission_request,
                ),
                ft.OutlinedButton(
                    "has_permission",
                    on_click=handle_has_permission,
                ),
                ft.OutlinedButton(
                    "get_current_position",
                    on_click=handle_get_current_position,
                ),
                ft.OutlinedButton(
                    "get_last_known_position",
                    visible=False if page.web else True,
                    on_click=handle_get_last_known_position,
                ),
                ft.OutlinedButton(
                    "is_location_service_enabled",
                    on_click=handle_location_service_enabled,
                ),
                ft.OutlinedButton(
                    "open_location_settings",
                    visible=False if page.web else True,
                    on_click=lambda e: page.show_dialog(
                        settings_dlg(handle_open_location_settings)
                    ),
                ),
                ft.OutlinedButton(
                    "open_app_settings",
                    visible=False if page.web else True,
                    on_click=lambda e: page.show_dialog(
                        settings_dlg(handle_open_app_settings)
                    ),
                ),
            ],
            wrap=True,
        )
    )


ft.app(main)

@ndonkoHenri ndonkoHenri linked an issue May 8, 2024 that may be closed by this pull request
@lekshmanmj lekshmanmj force-pushed the geolocator branch 2 times, most recently from 3daa556 to 6e7137e Compare May 11, 2024 16:05
@FeodorFitsner FeodorFitsner merged commit 776f357 into flet-dev:main May 24, 2024
2 checks passed
@Saidjony
Copy link

Saidjony commented Jun 9, 2024

image

help

@kacper-the-programmer
Copy link
Contributor

image

help

pip install flet --upgrade --pre

zrr1999 pushed a commit to zrr1999/flet that referenced this pull request Jul 17, 2024
* geolocator backup

* Geolocator Feature v1

* Geolocator Feature v1.1 (Junks removed)

* Geolocator: Junks cleanup

* Geolocator: Exception handled with clear message in geolocator.py, first 4 suggestions implemented

* add Android, macOS and iOS permissions

* refactor parseLocationAccuracy util

* create positionToJson util

* create new cases/methods and update old ones

* Cleanup

* Gelocator: Unused package removal

---------

Co-authored-by: ndonkoHenri <[email protected]>
Co-authored-by: TheEthicalBoy <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Location control
5 participants