How to get location using qml - BlackBerry - blackberry

It is possible to get longitude and latitude in BlackBerry using only qml? I found http://dengineer.com/adding-qml-gps-to-blackberry-10/ but it isnt work. Only black screen on my device.
This is my code:
import bb.cascades 1.0
import QtMobilitySubset.location 1.1
Page {
property string longitude
property string latitude
property variant cord
Container {
layout: DockLayout {}
attachedObjects: [
PositionSource{
id: location
updateInterval: 1000
onPointChanged: {
cord = location.position.coordinate;
longitude = cord.longitude;
latitude = cord.latitude;
result.setText(longitude + " " + latitude)
}
}]
Button {
text: qsTr("Locate me")
horizontalAlignment: HorizontalAlignment.Center
onClicked: {
location.start()
}
}
Label {
id: result
text: qsTr("0 0")
textStyle.base: SystemDefaults.TextStyles.BigText
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
}
}
}
I have error:
Jun 08 19:31:14.025 com.example.GPS_qml.testDev_ple_GPS_qml341af9aa.30007492 default 9000 WARNING --- errors: (file:///apps/com.example.GPS_qml.testDev_ple_GPS_qml341af9aa/native/assets//main.qml:32:13: Cannot assign to non-existent property "onPointChanged"
onPointChanged: {
^)

My understanding for QML is that it's only for display, you'll have to write some native code to do what you need. See samples at
https://github.com/blackberry/Cascades-Samples
you can check possibly the locationdiagnostics project giving an example of the Location API

Related

MapQuickItem is not displayed

I'm new to Qt and i'm starting a new GUI using QML.
I have a map and i want to display a marker. But i'm not able to display the marker using a MapQuickItem.
In my code below the title, the map and the MapCircle are displayed correctly, but the MapQuickItem is not displayed.
The image "marker.png" exists and i'm able to display it.
Thanks for your help.
import QtQuick 2.0
import QtLocation 5.6
import QtPositioning 5.6
import "../items"
SimpleTile {
m_width : 300
m_height : 300
property double m_latitude;
property double m_longitude;
innerObject: Column {
id: colMap
anchors.fill: parent
Plugin {
id: mapPlugin
name: "esri"
}
Text {
id: title
width: colMap.width
height: 25
horizontalAlignment: TextInput.AlignHCenter
font.bold: true
font.pointSize: 15
text: "Position"
}
Map {
id: map
width: colMap.width
height: parent.height - title.height
plugin: mapPlugin
center: QtPositioning.coordinate(m_latitude, m_longitude)
zoomLevel: 14
MapQuickItem {
id: marker
anchorPoint.x: image.width/2
anchorPoint.y: image.height
coordinate {
latitude: m_latitude
longitude: m_longitude
}
sourceItem: Image { id: image; source: "qrc:/images/marker.png" }
}
MapCircle {
radius: 1000
color: "red"
opacity: 0.4
center {
latitude: m_latitude
longitude: m_longitude
}
}
}
}
}
Ok, I solve my problem by changing
...
MapQuickItem {
...
coordinate {
latitude: m_latitude
longitude: m_longitude
}
...
to
...
MapQuickItem {
...
coordinate: QtPositioning.coordinate(m_latitude, m_longitude)
...
Thanks for your answers.

Appcelerator Geolocation never returns a speed on iOS

I'm using Appcelerator to provide a geo track. This works very well on Android, but on the iOS platform I am not getting speed or heading information from the onLocation event.
I initialise my GPS:
permissions.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS, function (e) {
if (e.success && !configuredMonitoring) {
if (OS_IOS) {
Ti.Geolocation.accuracy = Ti.Geolocation.ACCURACY_BEST;
Ti.Geolocation.distanceFilter = 5;
Ti.Geolocation.preferredProvider = Ti.Geolocation.PROVIDER_GPS;
Ti.Geolocation.pauseLocationUpdateAutomatically = true;
Ti.Geolocation.activityType = Ti.Geolocation.ACTIVITYTYPE_OTHER_NAVIGATION;
}
if (OS_ANDROID) {
Ti.Geolocation.Android.addLocationProvider(Ti.Geolocation.Android.createLocationProvider({
name: Ti.Geolocation.PROVIDER_GPS,
minUpdateDistance: 10,
minUpdateTime: 1
}));
Ti.Geolocation.Android.addLocationRule(Ti.Geolocation.Android.createLocationRule({
provider: Ti.Geolocation.PROVIDER_GPS,
accuracy: 10,
maxAge: 5000,
minAge: 1000
}));
Ti.Geolocation.Android.addLocationProvider(Ti.Geolocation.Android.createLocationProvider({
name: Ti.Geolocation.PROVIDER_NETWORK,
minUpdateDistance: 10,
minUpdateTime: 1
}));
Ti.Geolocation.Android.addLocationRule(Ti.Geolocation.Android.createLocationRule({
provider: Ti.Geolocation.PROVIDER_NETWORK,
accuracy: 10,
maxAge: 5000,
minAge: 1000
}));
Ti.Geolocation.Android.manualMode = true;
}
}
Then I add eventlisteners for iOS location updates being paused
if (Ti.Geolocation.locationServicesEnabled){
Ti.Geolocation.addEventListener('location', onLocation);
if (OS_IOS) {
Ti.Geolocation.addEventListener('locationupdatepaused', onLocationupdate);
Ti.Geolocation.addEventListener('locationupdateresumed', onLocationupdate);
}
}
My onLocation function runs
function onLocation(e) {
if (!e.error) {
var coords = e.coords;
console.log(JSON.stringify(e));
} else {
console.log('Error!':+JSON.stringify(e))
}
}
in my return data I see
{
"success":true,
"coords:{
"timestamp":1488757841662,
"speed":-1,
"longitude":173.2793426513672,
"floor":{"level":0},
"latitude":-41.274879455566406,
"accuracy":65,
"heading":-1,
"altitude":3.9126133918762207,
"altitudeAccuracy":10
},
"code":0,
"bubbles":true,
"type":"location",
"source":{
"preferredProvider":null
},
"cancelBubble":false
}
I never see anything other than -1 in my speed or heading, which according to the documentation: "On iOS, a negative value indicates that the heading data is not valid."
What am I doing wrong here?
We had this same issue and were pulling our hair out trying to figure it out. Try changing Ti.Geolocation.ACCURACY_BEST to Ti.Geolocation.ACCURACY_BEST_FOR_NAVIGATION. This fixed it for us.

Signal between QML with Repeater

I have the following qml files, the main.qml creates TestWindow.qml elements.
I would like to connect a signal in TestWindow.qml (click on a button mySignalToMainWindow() ) to a function in main.qml, testConnection().
main.qml
Window {
id: _component
property int instances: 3
width: 200
height: Screen.height / 2
visible: true
Component.onCompleted: {
x = 40
y = 40
}
Repeater {
id: _windows
model: instances
TestWindow {
index: model.index
leftOffset: _component.width
}
}
Column {
Repeater {
model: instances
Button {
text: "Window " + index
onClicked:{ _windows.itemAt(index).window.raise();
}
}
}
}
function testConnection(){console.log("Subwindow To Main Window")}
}
And TestWindow.qml :
Item {
id: _windowItem
property int index
property int leftOffset
property alias window: _window
signal mySignalToMainWindow()
Window {
id: _window
visible: true
title: "SubWindowText " + index
Component.onCompleted: {
x = leftOffset
y = 40
width = Screen.width - leftOffset
height = Screen.height / 2
}
Text {
id: windowText
text: qsTr("SubWindowText")
}
Button {
text: "SubWindow " + index
onClicked: {console.log("TestWindow::Button onClicked "+_window);
_windowItem.mySignalToMainWindow();
}
}
}
}
I tested those two :
How to bind to a signal from a delegate component within a ListView in QML
and
How to access dynamically/randomly loaded Repeater items in QML?
with no success.
So, how to do that?
Thanks
You have multiple options there. The first is to define the binding, when creating the Component for the delegate:
Repeater {
id: _windows
model: instances
TestWindow {
index: model.index
leftOffset: _component.width
onMySignalToMainWindow: testConnection() <--- Here you can connect it.
}
}
Another option is to use the onItemAdded and onItemRemoved-Handlers and connect the function there (mySignalToMainWindow.connect(functionToConnect)) and the respective disconnect, when it gets destroyed.
I'd recommend the former, if you want the connection to be permanent, and the latter if you might want to disconnect at some time.
The onItemAdded/onRemoved handlers are especially important if you don't declare a delegate for the Repeater. This happens for example if you use a DelegateModel or an ObjectModel. As with those models, you can't be sure, the objects are instantiated or destroyed when the Repeater adds or removes them, you could not use the often mentioned: Component.onCompleted/onDestruction, so I consider the itemAdded/Removed-signals superior/more general for the use with a Repeater.

Blackberry 10 Cascades - search-ahead drop-down + tag field

My question is related to Filipe Figueiredo's query (see: Blackberry 10 Cascades - Images inside Text Area)
My Cascades BB10 App requires a search-ahead drop-down with the ability to have multiple items selected and displayed as Tag Fields. Look & feel and behavior same as BB10 email composer's "To" address field - but with different data (e.g. country names).
Questions:
Is there a way to do this using Cascades components / controls?
(FlowListLayout does not meet exact requirements)
Can we achieve this using QML + javascript?
Or is there a way using C++ and QML for achieving this?
Is there a Component market Place for procuring custom controls for Cascades?
My development is stalled. Please help.
It should be possible. This is a prototype. It doesn't work well, but it's an idea. This is how it looks:
Code (yeah, it's bad. but it should work out of the box):
import bb.cascades 1.2
Page {
Container {
ListView {
id: tagList
dataModel: tagModel
layout: FlowListLayout {
headerMode: ListHeaderMode.None
}
preferredHeight: 200
function itemType(data, indexPath) {
return (data.add == 1 ? 'add' : '');
}
function mload(text) {
myList.load(text);
}
function showDropDown() {
myList.visible = true;
}
listItemComponents: [
ListItemComponent {
type: "add"
Container {
id: myAdd
TextField {
id: searchBox
preferredWidth: 300
onTextChanging: {
myAdd.ListItem.view.mload(searchBox.text);
}
onFocusedChanged: {
if (focused)
myAdd.ListItem.view.showDropDown();
}
}
}
},
ListItemComponent {
Container {
background: Color.create("#660000FF")
leftPadding: 10
rightPadding: 10
topPadding: 10
bottomPadding: 10
leftMargin: 10
bottomMargin: 10
Label {
id: country
textStyle.fontSize: FontSize.Medium
text: ListItemData.country
}
}
}
]
onTriggered: {
//todo: make it possible to remove a tag
console.log("item touched.. yay!")
}
attachedObjects: [
ArrayDataModel {
id: tagModel
}
]
}
ListView {
id: myList
visible: false
dataModel: mdataModel
preferredHeight: 400
attachedObjects: [
ArrayDataModel {
id: mdataModel
}
]
onTriggered: {
var selected = dataModel.data(indexPath);
var tmp = new Object();
tmp.country = selected;
tagModel.insert(tagModel.size() - 1, tmp);
console.log("removing: " + (tagModel.size() - 1 ) + " at size " + tagModel.size())
visible = false;
}
function load(text) {
var cities = [ "Slovenia", "Italy", "Slovakia", "Croatia", "Sweden", "Norway", "Poland", "Finland", "Spain",
"Indonesia", "Ireland" ]
var tmp = [];
for (var i = 0; i < cities.length; i ++)
if (cities[i].toLowerCase().indexOf(text.toLowerCase()) >= 0)
tmp.push(cities[i]);
mdataModel.clear();
mdataModel.insert(0, tmp);
}
function insertEdit() {
var edit = new Object();
edit["add"] = "1";
tagModel.insert(tagModel.size(), edit);
}
}
}
onCreationCompleted: {
myList.load("");
myList.insertEdit(); // insert item with TextField
}
}

Use setSeconds(); to close my splash screen in blackberry cascade

Well, Here I have a screen which I want to get close after 2-3 Seconds. For that I am using setDate() method.
I am very new to this Blackberry Cascade QML programming. I want to attach 1 more splash screen, so for that reason I want to use timer to close and open the sheet according to seconds.
Any help will be appreciated.
Thanks in advance.
I have worked on the following code.
import bb.cascades 1.0
import bb.cascades.pickers 1.0
Page
{
Container
{
background: Color.Transparent
//Todo: fill me with QML
onCreationCompleted:
{
mysheet1.open();
new Date();
**Error is shown in for loop**
for(Date.setSeconds(1),Date.setSeconds()<=5 , Date.setSeconds()+1)
{
if(Date == 5)
{
mysheet1.closed();
mysheet2.open();
}
}
}
attachedObjects:
[
Sheet
{
id: mysheet1
peekEnabled: false
Page
{
Container
{
background: Color.Transparent
ImageView
{
horizontalAlignment: HorizontalAlignment.Fill
verticalAlignment: VerticalAlignment.Fill
imageSource: "asset:///splash1.png"
}
}
}
}
]
}
Context Invokable: Date Date(...)
The Date object is used to work with dates and times.
Date objects are created with the new Date() constructor.
There are four ways of initiating a date:
new Date() // current date and time (or)
new Date(milliseconds) //milliseconds since 1970/01/01 (or)
new Date(dateString) (or)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
Invokable: number setSeconds(number sec)
Sets the seconds of a date object.
It will use a lot of process for some seconds. But there is no setInterval in QML.
The best solution is using a C++ class, TimeManager.cpp with a QTimer:
To expose the C++ method to QML you can register as a ContextProperty when the QML is instanciated:
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("TimeManager", new TimeManager());
And declare the method:
Q_INVOKABLE void callLater(int milliSeconds, QObject* sloter);
The implementation:
void TimeManager::callLater(int milliSeconds, QObject* sloter){
QTimer::singleShot(milliSeconds, sloter, SLOT(timerEnd()));
}
And the QML:
onCreationCompleted: {
TimeManager.callLater(2500, this);
}
onTimerEnd: {
mysheet1.closed();
}
Here is sample code of Timer.
import bb.cascades 1.0
import my.timer 1.0
Page {
Container {
layout: DockLayout {
}
onCreationCompleted: {
mTimer.start();
}
ImageView {
id: mImageViewIcon
horizontalAlignment: HorizontalAlignment.Fill
verticalAlignment: VerticalAlignment.Fill
imageSource: "asset:///images/splash.png"
}
attachedObjects: [
QTimer {
id: mTimer
interval: 2000
onTimeout: {
//Push New Page here
}
}
]
}
}
Don't forgot to add below line in main.cpp
qmlRegisterType<QTimer>("my.timer", 1, 0, "QTimer");

Resources