Forums

OverviewFelgo 2 Support (Qt 5) › Android positioning problems

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #19661

    Łukasz

    Hi guys,

    I was trying to get actual device position via PositionSource {} type in this way:

       PositionSource {
            id: positionSource
            updateInterval: 3000
            active: true
    
            onPositionChanged: {
                var coord = positionSource.position.coordinate;
                console.log("Coordinate:", coord.longitude, coord.latitude);
            }
    
            onSourceErrorChanged: {
                if (sourceError == PositionSource.NoError)
                    return
    
                console.log("Source error: " + sourceError)
                stop()
            }

    During first application loading, just before splash screen appearance , there was permission dialog and even after confirmation PositionSource logs were:

    I/QtPositioning(25628): Unknown positioningMethod
    I/QtPositioning(25628): Unknown positioningMethod
    I/QtPositioning(25628): Unknown positioningMethod
    W/System.err(25628): java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
    W/System.err(25628): 	at android.os.Parcel.readException(Parcel.java:1602)
    W/System.err(25628): 	at android.os.Parcel.readException(Parcel.java:1555)
    W/System.err(25628): 	at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:717)
    W/System.err(25628): 	at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1200)
    W/System.err(25628): 	at org.qtproject.qt5.android.positioning.QtPositioning.lastKnownPosition(QtPositioning.java:141)
    D/Buddy in Tour(25628): assets:/qml/Main.qml:158 (onPositionChanged): qml: Coordinate: NaN NaN
    D/QtPositioning(27179): Regular updates using GPS 3000
    D/QtPositioning(27179): Looper Thread startup time in ms: 7
    D/QtPositioning(27179): Regular updates using network 3000
    D/QtPositioning(27179): Disabled provider: gps
    

    and sourceEreor was 3 – UnknownSourceError.

    I added this permissions to AndroidManifest.xml:

        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>

    But it still doesn’t work. Probably Android permissions policy since SDK 23 6.0 os version is the reason, but I tried solve that problem in c++ according to this post.

        QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(0);
        source->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods);
    
        Permissions pozwolenia;
        pozwolenia.requestFineLocationPermission();
        if(pozwolenia.getPermissionResult()) {
    
             if (source) {
                 qDebug() << source->availableSources();
                 source->setUpdateInterval(1000);
                 source->startUpdates();
                 qDebug() << source->sourceName() << " source " << source->error() << " error";
                 qDebug() << source->lastKnownPosition().coordinate().latitude() << " - " << source->lastKnownPosition().coordinate().isValid();
             }
    
        }
    
    

     

    Where reguestFineLocationPermission() looks like that:

    void Permissions::requestFineLocationPermission() {
        #if defined(Q_OS_ANDROID)
    
            QtAndroid::PermissionResult request = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION");
            if (request == QtAndroid::PermissionResult::Denied)
            {
                QtAndroid::requestPermissionsSync(QStringList() <<  "android.permission.ACCESS_FINE_LOCATION");
                request = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION");
    
                if (request == QtAndroid::PermissionResult::Denied)
                {
                    this->permissionResult = false;
                }
                else { this->permissionResult = true; }
            }
            else { this->permissionResult = true; }
    }

    and getPermissionResult() return false if denied and true otherwise.

    Debugging result was similar but without permission error:

    I/QtPositioning(27179): Unknown positioningMethod
    I/QtPositioning(27179): Unknown positioningMethod
    D/libbuddyInTour.so(27179): ..\buddyInTour\main.cpp:50 (int main(int, char**)): ("android")
    D/QtPositioning(27179): Regular updates using network 1000
    D/QtPositioning(27179): Looper Thread startup time in ms: 6
    D/libbuddyInTour.so(27179): ..\buddyInTour\main.cpp:53 (int main(int, char**)): "android"  source  3  error
    D/libbuddyInTour.so(27179): ..\buddyInTour\main.cpp:54 (int main(int, char**)): nan  -  false

     

    Have you any ideas? I count on you 🙂 Cheers

    #19668

    Günther
    Felgo Team

    Hi Lukasz,

    I didn’t run into these issues during a short test – which Android SDK version are you using for building and which device are you testing on?

    VP apps use target SDK of 26 per default, which requires to do runtime permission checks.
    You can also try to change the Android targetSdkVersion in AndroidManifest.xml to e.g. version 16, which should disable runtime permission checks.

    Best,
    Günther from Felgo

    #19674

    Łukasz

    Hi Günther,

    I use Huawei Honor 5X based on Android 6.0 SDK 23.

    I can’t decrease targetSdkVersion, because Google Play requires to set the newest SDK version as target.

    I need current position to center Google Map displayed using WebView. I noticed that, I can use javascript navigator.geolocation in html file which is set as WebView’s url, when I request for fine location via QtAndroid::requestPermissionSYnc() in cpp. It’s impossible without that.

    So currenty it is enough for me, but this matter  is still interesting to me.

     

     

    #19678

    Günther
    Felgo Team

    Hi Lukasz,

    thanks for sharing your solution with QtAndroid::requestPermissionSync() – seems like a good way to request android permissions at runtime. However, it’s strange the permission does not work, after you granted it initially.

    Did you also try to remove the Android app from your device, then deploy a fresh and clean build? This makes sure the app is fully redeployed with all changes in manifest and permissions are reset on the device.

    It’s also possible that PositionSource requires a second start() call to correctly run in case the permission is required initially. We’ve seen similar behavior when using other device features, like the QML Camera. The first call triggers the permission dialog, but a second start call then runs the camera after the permission was given.

    Best,
    Günther

    #19937

    Didier

    I have a similar problem, on android, when I use v-play live, the gps does not work or it does not detect the current position, if it works… I’m using the “showcase” app

    #19938

    Didier

    already detect mi configuration, but the app stops suddenly without knowing why:
    <div></div>
    <div>

    W PersistentConnection: pc_0 – Using an unspecified index. Consider adding ‘”.indexOn”: “timestamp”‘ at public/userlocations/MhmZ1VHubSTCuFyOVu9L5hYz1Dn2 to your security and Firebase Database rules for better performance

    W PersistentConnection: pc_0 – Using an unspecified index. Consider adding ‘”.indexOn”: “timestamp”‘ at public/userlocations/a14ugxEJ8GMy2yziBwju9JfXG5x2 to your security and Firebase Database rules for better performance

    W PersistentConnection: pc_0 – Using an unspecified index. Consider adding ‘”.indexOn”: “timestamp”‘ at public/userlocations/enlinea to your security and Firebase Database rules for better performance

    W PersistentConnection: pc_0 – Using an unspecified index. Consider adding ‘”.indexOn”: “timestamp”‘ at public/userlocations/tqJ1TRzCdwRxhrLjf205QhifJmY2 to your security and Firebase Database rules for better performance

    D FirebaseDatabaseItem: FB DB query params: {}

    D FirebaseDatabaseItem: FB DB query params: {orderByChild=timestamp, limitToLast=20}

    D FirebaseDatabaseItem: FB DB query params: {orderByChild=timestamp, limitToLast=20}

    D FirebaseDatabaseItem: FB DB query params: {orderByChild=timestamp, limitToLast=20}

    D FirebaseDatabaseItem: FB DB query params: {orderByChild=timestamp, limitToLast=20}

    W Firebase Plugin: Firebase Database: Query returned nothing!

    F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 10862 (qtMainLoopThrea)

    </div>

    #19957

    Günther
    Felgo Team

    Hi Didier,

    maybe the log output: W Firebase Plugin: Firebase Database: Query returned nothing! is related to the issue.
    In case you can narrow the crash down to a certain Firebase call, please make sure that the feature is used correctly.

    In any case: To fix some crashes when using Firebase in certain cases., we’ve recently improved on the stability of the Firebase Plugin – the changes will come with next Felgo update. This might also help in case you experience crashes once in a while, without a certain call or action being responsible.

    Best,
    Günther

    #20079

    Didier

    Hi, my code saves the position of the user (gps) that logs in firebase, but in android the application stops, if I comment my code where I keep the position the application does not stop, and I do not understand what is the error, in IOS it works well,Could you help me to see where the fault is? this is my code:

    import Felgo 3.0
    import QtQuick 2.0
    import QtQuick.XmlListModel 2.0
    import QtLocation 5.5
    import QtPositioning 5.5
    import Qt.labs.settings 1.0
    import Felgo 3.0
    import "."
    
    Page {
        // Custom colors
        readonly property color blueLightColor: Qt.rgba(0, 147/256.0, 201/256.0, 1)
        // Generic text blue color
        readonly property color blueDarkColor: Qt.rgba(69/256.0, 85/256.0, 105/256.0, 1)
        // Background grey
        readonly property color greyBackgroundColor: Qt.rgba(238/256.0, 238/256.0, 238/256.0, 1)
        // Grey line color
        readonly property color greyLineColor: Qt.rgba(221/256.0, 221/256.0, 221/256.0, 1)
    
    
      property var coord: []
         signal logoutClicked()
         signal loginSucceeded
       property var usuarios: []
        property var  uids: []
         property var maps:[]
        readonly property int maxListEntries: 20
          property int numListEntries
          property bool loading: false
    
        //properties location
       property var location: []
      property  var email: []
      property  var timestamp: []
       property var userId: []
       property var enlinea: []
      property  var latitude: []
      property  var longitude: []
       property var devicemodel:[]
        property var mac:[]
        title: "Maps"
        LoginPage{
    
    
        }
        // Settings
        Settings {
          id: settings
    
          property var favorites
          onFavoritesChanged: {
            console.debug("Updated favorites", JSON.stringify(favorites))
            favsModel.update()
          }
    
          Component.onCompleted: {
            if (favorites === undefined) {
              // Add a first favorite for demonstration purposes
              favorites = [ 1021 ]
            }
          }
        }
        ListModel {
          id: favsModel
    
          function update() {
            clear()
    
            // Nearest from GPS coords
            updateNearest()
    
            // Add favs
            for (var i = 0; i < model.count; i++) {
              var station = model.get(i)
              if (settings.favorites.indexOf(station.internalId) !== -1) {
                append({
                         userId: station.userId,
                         email: station.email,
                         devicemodel:station.devicemodel,
                          // mac:station.mac,
                         //freeBoxes: station.freeBoxes,
                         //freeBikes: station.freeBikes,
                         favorited: settings.favorites.indexOf(station.userId) !== -1
                       })
              }
            }
          }
          function updateNearest() {
            if (!map.userPositionAvailable)
              return
    
            // Compare current user location with all other stations
            var currentDistance = -1
            var currentIndex = -1
    
            for (var i = 0; i < model.count; i++) {
              var station = model.get(i)
    
              var distance = map.userPosition.coordinate.distanceTo(QtPositioning.coordinate(station.latitude, station.longitude))
              if (currentDistance === -1 || distance < currentDistance) {
                currentDistance = distance
                currentIndex = i
              }
            }
    
            // Get station
            if (currentIndex !== -1) {
              var station = model.get(currentIndex)
    
              set(0, {
                    userId: station.userId,
                    email: station.email,
                      devicemodel:station.devicemodel,
                       // mac:station.mac,
                   // location: station.freeBoxes,
                    //freeBikes: station.freeBikes,
                    favorited: settings.favorites.indexOf(station.userId) !== -1
                  })
            }
          }
        }
    
    
        Component.onCompleted: {
    
          // saveLocation()
      // loginPage.loggedIn()
        //    loginPage.loginUser()
          //  loginSucceeded()
           // aiTimeOut.start()
    
            //loadUsers()
    
    
        }
        Timer {
            id: aiTimeOut
            interval: 20000;
            repeat: true
            triggeredOnStart: true
            onTriggered: {
                saveLocation();
    
               /* if(!firebaseAuth.authenticated){
                    console.log("No autenticado");
                }
                else{
                 saveLocation();
                }*/
    
    
            }
          }
    
    
    
        Connections {
              target: firebaseDb
    
    
    
            // we store the read values in those properties to display them in our text items
            property var location: []
            property string realtimeTestValue: ""
             // realtimeValueKeys: ["public/userlocations/"+firebaseAuth.userId+"/location"]
    
            // update our local realtimeTestValue property if database value changed
            //onRealtimeValueChanged: if(success && key === "location") location = value
            //property string realtimeTestValue: ""
    
    
            // update our local realtimeTestValue property if database value changed
            onRealtimeValueChanged: {
              if(success && key === "location") {
                location = value
              }
            }
    
    
            // update our local testValue property if read from database was successful
            onReadCompleted: {
              if(success) {
                console.debug("Read value " +  value + " for key " + key)
                location = value
              } else {
                console.debug("Error: "  + value)
              }
            }
    
            // add some debug output to check if write was successful
            onWriteCompleted: {
              if(success) {
                console.debug("Successfully wrote to DB")
              } else {
                console.debug("Write failed with error: " + message)
              }
            }
         //onPluginLoaded:aiTimeOut.start();
          }
    
        NavigationStack {
          splitView: false
            Page {
                 id: page
              title: "User Position"
             navigationBarHidden: true
             property int selectedIndex: -1
    
    
             onSelectedIndexChanged: {
               var selectedStation = model.get(selectedIndex)
               if (selectedStation) {
                 currentStationView.userName = selectedStation.email
                   currentStationView.devicemodel=selectedStation.devicemodel
                   currentStationView.userId=selectedStation.userId
                 //currentStationView.stationBikes = selectedStation.freeBikes
                 //currentStationView.stationBoxes = selectedStation.freeBoxes
                 currentStationView.userFavorited = settings.favorites.indexOf(selectedStation.userId) !== -1
               }
             }
    
             // Header
             Rectangle {
               id: header
    
               width: parent.width
               height: dp(210)
               // Bring in front of map
               z: 2
    
               color: greyBackgroundColor
    
               PageControl {
                 id: pageControl
    
                 anchors.horizontalCenter: parent.horizontalCenter
                 anchors.top: parent.top
                 anchors.topMargin: Theme.statusBarHeight + dp(10)
    
                 opacity: page.selectedIndex >= 0 ? 0 : 1
    
                 pageIcons: map.userPositionAvailable ? ({ 0: IconType.locationarrow }) : ({})
    
                 tintColor: greyLineColor
                 activeTintColor: blueLightColor
    
                 onPageSelected: {
                   innerList.scrollToPage(index)
                 }
    
                 pages: favsModel.count
               }
    
               ListView {
                 id: innerList
    
                 onContentXChanged: {
                   currentIndex = Math.round(contentX / width)
                   pageControl.currentPage = currentIndex
                 }
    
                 anchors.fill: parent
                 anchors.topMargin: pageControl.y + pageControl.height + dp(10)
    
                 visible: !currentStationView.visible
    
                 model: favsModel
                 orientation: ListView.Horizontal
                 snapMode: ListView.SnapOneItem
                 highlightFollowsCurrentItem: true
    
                 delegate: PerfilView {
                   width: innerList.width
                   height: innerList.height
    
                   userName: email
                   devicemodel: devicemodel
                   userId: userId
                  // stationBikes: freeBikes
                   //stationBoxes: freeBoxes
                   userFavorited: userId
    
                   // We don't use the property signal change handler as this one is also emitted when
                   // changing the property in code
                   onFavoritedPressed: {
                     if (settings.favorites.indexOf(userId) === -1) {
                       settings.favorites.push(userId)
                     }
                     else {
                       settings.favorites.splice(settings.favorites.indexOf(userId), 1)
                     }
    
                     settings.favoritesChanged()
                   }
                 }
    
                 function scrollToPage(index) {
                   // TODO: Animate
                   innerList.positionViewAtIndex(index, ListView.SnapPosition)
                 }
    
               }
    
               PerfilView {
                 id: currentStationView
                 anchors.fill: innerList
    
                 visible: page.selectedIndex >= 0
    
                 backVisible: true
    
                 onBackPressed: {
                   page.selectedIndex = -1
                 }
    
                 // We don't use the property signal change handler as this one is also emitted when
                 // changing the property in code
                 onFavoritedPressed: {
                   var internalId = model.get(page.selectedIndex).userId
    
                   if (settings.favorites.indexOf(internalId) === -1) {
                     settings.favorites.push(internalId)
                   }
                   else {
                     settings.favorites.splice(settings.favorites.indexOf(internalId), 1)
                   }
    
                   settings.favoritesChanged()
                 }
               }
              Rectangle {
                anchors.top: parent.bottom
                width: parent.width
                height: dp(5)
    
                gradient: Gradient {
                  GradientStop { position: 0.0; color: "#33000000" }
                  GradientStop { position: 1.0; color: "transparent" }
                }
    
              }
             }
    
            ListModel {
                 id: model
                 Component.onCompleted: {
    
                 }
    
                }
    
    
    
              // show the map
              AppMap {
                  id:map
                anchors.fill: parent
                plugin: Plugin {
                  name: "mapbox"
                  // configure your own map_id and access_token here
                  parameters: [  PluginParameter {
                      name: "mapbox.mapping.map_id"
                      value: "mapbox.streets"
                    },
                    PluginParameter {
                      name: "mapbox.access_token"
                      value: "pk.eyJ1IjoiZGlyZXN0cmVwb2JyIiwiYSI6ImNqanZxYjI3ODlzazEza3Axcmh0b3N5NHMifQ.BCHtMCaong-P2FD0Ld5cZg"
                    },
                    PluginParameter {
                      name: "mapbox.mapping.highdpi_tiles"
                      value: true
    
    
                    }]
                }
    
                // configure the map to try to display the user's position
                showUserPosition: true
                zoomLevel: 13
                center: QtPositioning.coordinate(2.93121222406898, -75.26168910793518)
                // check for user position initially when component is created
                Component.onCompleted: {
                  if(userPositionAvailable)
                      center: QtPositioning.coordinate(2.93121222406898, -75.26168910793518)
    
                    //center = userPosition.coordinate
                  console.log("Coordinates "+center)
    
    
                }
                onMapClicked: {
                  // Clicked on map, remove current selection
                  page.selectedIndex = -1
                }
    
                // once we successfully received the location, we zoom to the user position
                onUserPositionAvailableChanged: {
                 // if(userPositionAvailable)
                   // zoomToUserPosition()
                  //saveLocation(center)
                }
                onUserPositionChanged: {
                    //center = userPosition.coordinate
                favsModel.updateNearest()
                   // PositionSource.
                     coord = src.position.coordinate;
    
                saveLocation(coord)
                    //loadUsers()
                }
                PositionSource {
                    id: src
                    updateInterval: 1000
                    active: true
    
                    onPositionChanged: {
                         coord = src.position.coordinate;
    
                       // console.log("Coordinate:", coord.longitude, coord.latitude);
                    }
                }
                MapItemView {
    
    
                     model:  model
                     delegate: MapQuickItem {
                       coordinate: QtPositioning.coordinate(latitude,longitude)
                       anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height-dp(2))
                       sourceItem: AppImage {
                           id: image
                           width: dp(40)
                           height: dp(34)
                           source: {
                             // Inactive
                             if (enlinea !== false) {
                                 return "../assets/pin-green.png"
    
                             }
    
                             else {
                               return "../assets/pin-grey.png"
                             }
                           }
    
                           MouseArea {
                             anchors.fill: parent
                             onClicked: {
                               page.selectedIndex = index
                             }
                           }
                         }
                       z: 90-latitude
                     }
    
    
                   }
    
              }
    
    
              IconButton {
                icon: IconType.locationarrow
                anchors.left: parent.left
                anchors.bottom: parent.bottom
                anchors.leftMargin: dp(10)
                anchors.bottomMargin: dp(10)
    
                enabled: map.userPositionAvailable
    
                size: dp(26)
    
                onClicked: {
                  map.zoomToUserPosition()
                }
              }
            }
          }
    
       function saveLocation(coord){
    
           //console.log("Inicio guardar posición...")
    
          //  var userposition=  coord.latitude+","+coord.longitude;
              var dbItem = {
                  timestamp: timestamp,
                  location: coord,
                  email: firebaseAuth.email,
                  userId: firebaseAuth.userId,
                  enlinea: firebaseAuth.authenticated,
                  latitude: coord.latitude,
                  longitude:coord.longitude,
                  devicemodel:nativeUtils.deviceModel(),
                 // mac:system.macAddress
              }
    
    
    
              firebaseDb.setValue("public/userlocations/" , dbItem, function(success, message) {
                    if(success) loadData()
                  })
    
    
    
            //console.log("Posicion guardada")
          }
    
    
       function loadData() {
            loading = true
           // console.debug("loading data")
            // load the last X entries, ordered by timestamp property
           firebaseDb.getValue("public/userlocations", {
    
                               }, function(success, key, value) {
                                 if(success) {
    
                                    uids=JSON.stringify(value)
                                   // console.log("uids", uids)
                                     maps= JSON.parse(uids.valueOf())//property var maps:[]
                                 }
                                 loading = false
                               })
    
           for (var i in maps.valueOf()) {
    
               // console.log("UIDssssssss",i )
    
               getByUser(i) //function to obtain from the id of user
               //the details of that particular user
            }
    
          }
    
       function getByUser(uid){
             // console.log("Obteniendo usuario",uid )
           firebaseDb.getValue("public/userlocations/"+ uid, {
                                         limitToLast: maxListEntries,
                                         orderByChild: "timestamp",
    
                                          //equalTo:uid
    
                                       }, function(success, key, value) {
                                         if(success) {
    
                                             usuarios=JSON.stringify(value)
                                       //      console.log("usua ", usuarios)
                                              //  mapview.model = usuarios.valueOf()
    
                                           var parsedUser = JSON.parse(usuarios.valueOf())
                                            location=parsedUser.Location
                                            email=parsedUser.email
                                            timestamp=parsedUser.timestamp
                                            userId=parsedUser.userId
                                            enlinea=parsedUser.enlinea
                                            latitude=parsedUser.latitude
                                            longitude=parsedUser.longitude
                                             devicemodel=parsedUser.devicemodel
                                             mac=parsedUser.mac
                                           // dumpJSONObject(usuarios, 0 ); //here
                                            // console.log("Leenando List de ", email)
                //I filled the ListModel to then pass it to the MapItemView
                                             model.append({location: location, email: email,timestamp:timestamp,userId:userId, enlinea:enlinea, latitude:latitude,longitude:longitude, devicemodel:devicemodel, mac:mac});
                                            // console.log( "mostrar",  model.get(email))
                                         
     page.dataModelChanged()
                                         }
                                         loading = false
                                       })
    
    
       }
    
    
    }
    

    mi config firebase in Mail.qml is:

     FirebaseDatabase {
              id: firebaseDb
             persistenceEnabled:true
              config:  customConfig
              // define which values should be read in realtime
               realtimeValueKeys: ["public/userlocations/"+firebaseAuth.userId+"/location"]
          }

    Thanks?

    #20085

    Günther
    Felgo Team

    Hi Didier,
    thanks for sending over your Android crash details and the project!

    We believe the crash is related to Android Firebase SDK internals and threading issues in conjunction with QML.  We’ve prepared a fix, so with the next Felgo Update these Firebase Crashes on Android should no longer happen.

    You can find more details in my email reply to our conversation regarding this issue.

    Best,
    Günther from Felgo

Viewing 9 posts - 1 through 9 (of 9 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support