Ionic 2 native geolocation, no error thrown when location is turned off - ionic-framework

I m using native geolocation module of an Ionic 2. Following are the part of my code
import { Geolocation } from '#ionic-native/geolocation';
..
..
getLocation(){
this.platform.ready().then(() => {
this.geolocation.getCurrentPosition().then(pos => {
console.warn("latitude = "+pos.coords.latitude);
console.warn("longitude = "+pos.coords.longitude);
}, (error) => {
console.warn("Error in fetching location");
});
});
}
I m testing app in an android phone. Everything works fine, except when the location is turned off, error is not thrown in the console. Can anybody tell me how to throw error if location service is turned off in the device??
Thanks

I have fixed myself
what I needed to do is -
this.geolocation.getCurrentPosition({timeout: 100})
I have to add timeout option as a parameter of a getCurrentPosition method.
According to Android Quirks section of plugin page:-
If Geolocation service is turned off the onError callback is invoked
after timeout interval (if specified). If timeout parameter is not
specified then no callback is called.
For more details Click Here
Infact I can also use diagnostic plugin to detect the location. Check Here

Related

Flutter and Adafruit Feather nRF52: Could not locate CCCD descriptor

I'm trying to set up notify so that my BLE with sensor can send data to my android phone. My embedded code is based off of the example for Custom HRM on Adafruit's site (https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/custom-hrm ) and the code for flutter is based off flutter blue's example
for (final BluetoothService service in services) {
if(service.uuid == widget.serviceID){
for (final BluetoothCharacteristic characteristic in service.characteristics) {
if(characteristic.uuid == widget.charID) {
await characteristic.setNotifyValue(true);
characteristic.value.listen((value) {
print(value);
});
}
}
I keep getting this error:
Unhandled Exception: PlatformException(set_notification_error, could not locate CCCD descriptor for characteristic: 00002a24-0000-1000-8000-00805f9b34fb, null, null)
I tested my flutter code for every available characteristic in case my ID is wrong (it's not though). I also tried printing out all descriptors for that characteristic and found out there's none.
In the example adafruit code, we don't need to add any descriptors, we only need to do
characteristic.setProperties(CHR_PROPS_NOTIFY);
characteristic.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
Am I missing something? How can I fix this?
Solved: It was a hardware issue. Service and characteristic UUIDs weren't setting correctly. Tested on a new Feather nRF52 and everything is good.

Firestore emulator - simulate loss of connectivity

I have an app with a real time listener setup to instantly pick up all updates on a collection. I also have some logic to pick missing documents afterwards in case my app loses its connectivity (in which case the listener would miss some documents).
I want to test this logic using the simulator, but how do I simulate the loss of connectivity? is there built-in function for that?
Actually the following page shows how to proceed in general, be it with the emulator or an actual Firestore instance:
firebase.firestore().disableNetwork()
.then(() => {
// Do offline actions
// ...
});
firebase.firestore().enableNetwork()
.then(() => {
// Do online actions
// ...
});

Check if App is running in a Testing Environment

was just wondering if I can determine if my app currently runs in a Testing environment.
Reason is that I am running automated screenshots and want to hide/modify parts of my App only when running that UI Test.
For example I'd like to skip registering for push notifications to avoid that iOS Popup at launch.
I'm searching for something like
if (kTestingMode) { ... }
I know that we do have a driver that basically launches the app and then connects. Guess the App actually does not even know if it is running in Testmode or not. But maybe someone knows an answer.
Thanks!
Some answers aim to detect if you are in debug mode. The question was about how to detect if you are in a test environment, not if you are in debug mode. In fact, when you run a test, you are in debug mode, but you can run an app in debug mode even without running a test.
In order to properly detect if you are running a test, you can check for the presence of the key FLUTTER_TEST in Platform.environment.
import 'dart:io' show Platform;
if (Platform.environment.containsKey('FLUTTER_TEST')) { ... }
Another solutions is to use --dart-define build environment variable. It is available from Flutter 1.17
Example of running tests with --dart-define:
flutter drive --dart-define=testing_mode=true --target=test_driver/main.dart
In code you can check this environment variable with the following code:
const bool.fromEnvironment('testing_mode', defaultValue: false)
Not using const can lead to the variable not being read on mobile, see here.
Okay I just found a solution my myself.
What I did is introduce a global variable which I will set in my main driver.
First I created a new globals.dart file:
library my_prj.globals;
bool testingActive = false;
Then, in my test_driver/main.dart file I import that and set the testingActive variable to true
import '../lib/globals.dart' as globals;
..
void main() {
final DataHandler handler = (_) async {
final response = {};
return Future.value(c.jsonEncode(response));
};
// Enable integration testing with the Flutter Driver extension.
// See https://flutter.io/testing/ for more info.
enableFlutterDriverExtension(handler: handler);
globals.testingActive = true;
WidgetsApp.debugAllowBannerOverride = false; // remove debug banner
runApp(App());
}
Now, I do have this global variable everywhere in my Flutter App by simply importing and checking.
e.g. in my app.dart
import '../globals.dart' as globals;
...
if (globals.testingActive) {
print("We are in a testing environment!");
}
Is there a better solution? Guess this works just fine!
I have another solution for this, may be this would work out as well for you. Let me know if that goes well with you or not.
1. So, I am suggesting to use assert(), as it only runs on debug mode.
Here is an example for navigator:
assert(() {
if (navigator == null && !nullOk) {
throw new FlutterError(
'Error!!!'
);
}
return true;
}());
Note: In particular the () at the end of the call - assert can only operate on a boolean, so just passing in a function doesn't work.
2. Other way is to use kReleaseMode from package package:flutter/foundation.dart
kReleaseMode is a constant. Therefore the compiler is correctly able to remove unused code, and we can safely do:
import 'package:flutter/foundation.dart' as Foundation;
//is release mode
if (Foundation.kReleaseMode) {
print('release mode');
} else {
print('debug mode');
}
3. This is the snippet which will be helpful for you:
bool get isInDebugMode {
bool inDebugMode = false;
assert(inDebugMode = true);
return inDebugMode;
}
If not you can configure your IDE to launch a different main.dart in debug mode where you can set a boolean.

Protractor Failed: element not interactable

I am running an E2E test for an Angular 7.x app. The test runs straight forward on my local machine. But when I push it on the repo (GitLab), then pipeline fails and throws following error:
USER PROFILE - Check and change PROFILE
- Failed: element not interactable
(Session info: chrome=71.0.3578.80)
(Driver info: chromedriver=2.45.615279 (12b89733300bd268cff3b78fc76cb8f3a7cc44e5),platform=Linux 4.14.74-coreos x86_64)
Test Case:
it('USER PROFILE - Check and change PROFILE', () => {
page.navigateTo();
browser.sleep(1000);
expect(page.getProfileEditTagName()).toMatch('app-edit-profile');
expect(element(by.className('logged-as')).getText()).toBe( testEmail );
browser.actions().mouseMove( element.all( by.id('editIcon-salutation') ).get(0)).click().perform().then(function () {
browser.sleep(4000);
element( by.className('mat-select-arrow') ).click().then(function () {
browser.actions().mouseMove( element.all(by.className('option-value mat-option')).get(0)).click().perform();
browser.sleep(1000);
browser.actions().mouseMove( element.all( by.id('saveButton-salutation') ).get(0)).click().perform();
browser.sleep(1000);
});
});
});
navigateTo() is just a method in profile.po.ts:
navigateTo() {
browser.get('/profileComponentUrl');
}
What's confusing me and where I even can't localize the bug or what's wrong, is that it works fine locally. But once I push to repo, then it fails exactly at that test case. Any Hint please?
The reason element is not interactable could be - performing an action on hidden or obscured element.
You can try -
1. add sleep after by.className('mat-select-arrow') ).click(), as I can see you have not added any waits there.
2. Try to check if you running the test on your local and Jenkins machine with same screen resolution. (this could be the reason of obscured element)
I'd recommend to:
Enable the stacktrace in protractor config: new SpecReporter({ spec: { displayStacktrace: true } }) so you can see exactly what element is throwing the error. This won't solve it but at least should point you in the right direction.
Then if you're using tabs, buttons or other elements that hide/show/disable/enable or change the DOM view, you add a browser.sleep(100) after calling a .click()
I had a same kind of problem and I found this.
I copy pasted that (and some other minor tweaks for example force clicking on previous page in for-loop) and it worked. I believe that the browser.driver.manage().window().maximize(); was part of the solution.
One reason which i figure out is the scroll issue. You need to check the element is displaying properly or not. It may be hidden. So use scrollToTop/scrollToElement/scrollToElementView etc. You can write different scroll methods which suites the condition better.
Another reason is the locator. Try to change the locator, do not trim the locator too much. Just try with full body css locator, if it works then trim properly. Some time in chrome console it may work but not with the test case.

How to get current location in google maps using "nativescript-google-maps-sdk"?

I am building an app on nativescript+Angular2. I have downloaded the "nativescript-google-maps-sdk" plugin from npm. If I enable setMyLocationEnabled(true), I get the "my-location" button on the upper right corner of the screen and clicking it takes me to my actual location.
What I would like to do is to get these coordinates programmaticaly, because I will need them for other operations (markers, proximity values etc.).
Ran through their code, but couldn't find how they are getting this current location. gMap.getMyLocation() is deprecated, so I can't use that, based on what's written here: https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap
We should be using FusedLocationProviderApi. If this plugin isn't using it, then how does it acquire current location?
Can anyone shed some light?
mapReady(args) {
console.log("Map Ready");
var gMap = args.gMap;
gMap.setMyLocationEnabled(true);
// gMap.getMyLocation(); deprecated
// need to get current location coordinates, somehow...
}
The nativescript-google-maps-sdk plugin doesn't support getting your location from the device.
You need to get the location from nativescript-geolocation ( you are already doing that) and then pass that to the google-map.
If you check the google-maps plugin's AndroidManifest.xml, it doesn't have the permission to access the device's location.
So, as it turns out, you can get your location from your device in 2 ways:
with built in android LocationManager
with google play services location module, which uses FusedLocationProviderApi which is built on default android LocationManager
The difference, from what I've read, is that the googles' version is more advanced - it switches from different location modes (gps, wifi) automatically and saves up your battery.
So, in order to use the googles' way, we need to:
Import google play services location module (+ means newest version):
dependencies {
compile 'com.google.android.gms:play-services-location:+'
}
Then initialise the play services API:
declare var com: any;
GoogleApiClient = com.google.android.gms.common.api.GoogleApiClient;
LocationServices = com.google.android.gms.location.LocationServices;
var dis = this; // writing in typescript, so this is reference to our current component where this code will lay
// Create an instance of GoogleAPIClient.
if (this.googleApiClient == null) {
this.googleApiClient = new dis.GoogleApiClient.Builder(application.android.context)
.addConnectionCallbacks(new dis.GoogleApiClient.ConnectionCallbacks({
onConnected: function() {
console.log("GoogleApiClient: CONNECTED");
}.bind(this),
onConnectionSuspended: function() {
console.log("GoogleApiClient: SUSPENDED");
}.bind(this)
}))
.addOnConnectionFailedListener(new dis.GoogleApiClient.OnConnectionFailedListener({
onConnectionFailed: function() {
console.log("GoogleApiClient: CONNECTION ERROR");
}.bind(this)
}))
.addApi(dis.LocationServices.API)
.build();
}
this.googleApiClient.connect();