For future me and you searching for the solution to my question:
function requestDevicePermissions() {
if (typeof DeviceOrientationEvent.requestPermission === 'function' && typeof DeviceMotionEvent.requestPermission === 'function') {
const requestOrientationPermission = () => {
DeviceOrientationEvent.requestPermission().then(permissionState => {
if (permissionState === 'granted') {
window.addEventListener('deviceorientation', function(event) {
_processGyroscopeData(event.alpha, event.beta, event.gamma, event.absolute);
});
} else {
const button = document.createElement('button');
button.innerText = "Enable Orientation";
button.style.position = 'absolute';
button.style.top = '100%';
button.style.left = '100%';
button.style.transform = 'translate(50%, 50%)';
document.body.appendChild(button);
button.addEventListener('click', () => {
requestOrientationPermission();
requestMotionPermission();
document.body.removeChild(button); // Remove button after requesting permissions
});
}
}).catch(err => {
console.error("Error requesting deviceorientation permission:", err);
});
};
const requestOrientationAbsolutePermission = () => {
DeviceOrientationEvent.requestPermission(true).then(permissionState => {
if (permissionState === 'granted') {
window.addEventListener('deviceorientationabsolute', function(event) {
_processGyroscopeData(event.alpha, event.beta, event.gamma, event.absolute);
});
} else {
console.log("deviceorientationabsolute permission denied.");
}
}).catch(err => {
console.error("Error requesting deviceorientationabsolute permission:", err);
});
};
const requestMotionPermission = () => {
DeviceMotionEvent.requestPermission().then(response => {
if (response === 'granted') {
window.addEventListener('devicemotion', function(event) {
_processAccelerometerData(event.acceleration.x, event.acceleration.y, event.acceleration.z);
if (event.accelerationIncludingGravity) {
_processAccelerometerDataGravity(
event.accelerationIncludingGravity.x,
event.accelerationIncludingGravity.y,
event.accelerationIncludingGravity.z
);
}
if (event.rotationRate) {
_processRotationRateData(
event.rotationRate.alpha,
event.rotationRate.beta,
event.rotationRate.gamma
);
}
window.addEventListener('deviceorientation', function(event) {
_processGyroscopeData(event.alpha, event.beta, event.gamma, event.absolute);
});
});
console.log("DeviceMotionEvent permission granted.");
} else {
console.error("DeviceMotionEvent permission denied.");
}
}).catch(err => {
console.error("Error requesting DeviceMotionEvent permission:", err);
});
};
requestOrientationPermission();
const button = document.createElement('button');
button.innerText = "Enable Orientation";
button.style.position = 'absolute';
button.style.top = '100%';
button.style.left = '100%';
button.style.transform = 'translate(50%, 50%)';
document.body.appendChild(button);
button.addEventListener('click', () => {
requestOrientationPermission();
requestMotionPermission();
document.body.removeChild(button); // Remove button after requesting permissions
});
} else {
// Automatically start listeners on non-iOS 13+ devices
window.addEventListener('deviceorientation', function(event) {
_processGyroscopeData(event.alpha, event.beta, event.gamma);
console.log("DeviceOrientationEvent listener added automatically.");
});
window.addEventListener('devicemotion', function(event) {
_processAccelerometerData(event.acceleration.x, event.acceleration.y, event.acceleration.z);
console.log("DeviceMotionEvent listener added automatically.");
});
}
It might be too much and too defensive, perhaps some lines are not needed, but at least this code works on both Android and iOS. I put this function in Defold NE in a function startSensorsOnUserInteraction() which includes the above block in EM_ASM()
and add call to it:
requestDevicePermissions();
Proper functions in Emscripten should be added to process the acquired data of course (processGyroscopeData, processAccelerometerData, e.g.) and perhaps then either use for calculations or pass to Lua in Native Extension.