Reputation: 1550
I have an Ionic/Cordova app where I need to get the direction the device is pointing to.
So I'm using the Cordova Plugin Device Orientation to get the compass data. But then I need to take into account, when the user rotates his device (portrait/landscape). I use the Cordova Plugin Screen Orientation to get the Screen-Orientation.
But as documented in the Screen Orientation plugin this does not work on Android, when the device is upside down, or even when it's rotated from landscape through the bottom to the other landscape: "The screen.orientation property will not update when the phone is rotated 180 degrees."
So my problem is: When the device is upside or rotated around the bottom I still get "LANDSCAPE_PRIMARY" or "LANDSCAPE_SECONDARY", cause this is not supported. So I can't calculate the correct heading.
Any idea how to do this in Ionic/Cordova? I couldn't find any other plugins and I would like to avoid creating my own.
Additional information:
Edit: I created a simple page to show the behaviour. It shows the heading directly from the compass. This value changes, when the device is rotated (portrait/landscape) and the value I try to calculate (which should stay the same, when the device is rotated).
import { Component, OnDestroy, OnInit } from '@angular/core';
import { distinctUntilChanged } from 'rxjs/operators';
import { DeviceOrientationCompassHeading } from '@awesome-cordova-plugins/device-orientation';
import { DeviceOrientation } from '@awesome-cordova-plugins/device-orientation/ngx';
import { ScreenOrientation } from '@awesome-cordova-plugins/screen-orientation/ngx';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-orientation',
template: 'Heading: {{compassHeading}}/{{calculatedHeading}}'
})
export class OrientationPage implements OnInit, OnDestroy {
compassHeading: number;
calculatedHeading: number;
private sub: Subscription;
constructor(private deviceOrientation: DeviceOrientation,
private screenOrientation: ScreenOrientation) {
}
ngOnInit(): void {
this.sub = this.deviceOrientation.watchHeading().pipe(distinctUntilChanged()).subscribe({
next: (currentHeading: DeviceOrientationCompassHeading) =>
{
this.compassHeading = currentHeading?.trueHeading;
this.calculatedHeading = this.calcHeading(currentHeading, this.screenOrientation);
},
error: (error) => console.error('Cannot subscribe to device orientation: ', error)
}
);
}
ngOnDestroy() {
this.sub?.unsubscribe();
}
calcHeading(currentHeading: DeviceOrientationCompassHeading, screenOrientation: ScreenOrientation): number {
if (currentHeading?.trueHeading) {
const rotationDelta = this.getScreenRotationDelta(screenOrientation);
const heading = currentHeading.trueHeading + rotationDelta;
// limit to 360
return heading % 360;
}
return undefined;
}
getScreenRotationDelta(screenOrientation: ScreenOrientation): number {
switch (screenOrientation.type) {
case screenOrientation.ORIENTATIONS.LANDSCAPE_PRIMARY:
return 90;
case screenOrientation.ORIENTATIONS.PORTRAIT_SECONDARY:
// I never get this value on android phone :-(
return 180;
case screenOrientation.ORIENTATIONS.LANDSCAPE_SECONDARY:
return 270;
default:
return 0;
}
}
}
Upvotes: 0
Views: 671
Reputation: 929
Ionic has their in house plugin that works great: @capacitor/motion Why not use this instead?
Upvotes: 0