I have an ionic application for android and IOS, the app display a message when specific action happen.
But i realized that there is a difference in this action if the IOS OS was higher than 11 or less than 10.
So i want to detect IOS' version, if it was less than 10 display this message and if it was higher then don't displau it.
I'm new to ionic, so how can i achive this?
CODE:
function (err) {
if (err == "has no access to assets") {
_this.presentAlert('no access');
}
else if (err == "no image selected") {
_this.presentAlert('nothing selected');
}
});
The first if is where i want to check the device's OS version, if it was less than 11 then display the message.
How to do it?
for version: const currentPlatformVersion = ionic.Platform.version();
if it is ios device const isIOS = ionic.Platform.isIOS();
even this const deviceInformation = ionic.Platform.device(); returns an object with the device that runs the ionic app.
Related
Looking to hide/show a component in a React/Nextjs/tailwind webapp depending on the device that the user is on (e.g. desktop vs tablet vs mobile) since there are certain keys on the keyboard available for desktop but not on table and mobile (e.g. the tab key). Don't want to do it by screen size since this is a device problem (no tab on keyboard) rather than a screen size problem
Initially I thought about getting device type (code referenced from another stackoverflow Q/A), but this seems to fail when the user is on a device such as an ipad and is using the Desktop version for that browser (e.g. Desktop safari and not mobile safari). Is there a better way to handle this such that it can properly check what device the user is on in order to be able to hide/show the react component?
const getDeviceType = () => {
const ua = navigator.userAgent;
if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
return "tablet";
}
if (
/Mobile|iP(hone|od)|Android|BlackBerry|IEMobile|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(
ua
)
) {
return "mobile";
}
return "desktop";
};
In JavaScript you can detect browser with JavaScript using window.navigator
Code example according to https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator would be
var sBrowser, sUsrAg =
navigator.userAgent;
// The order matters here, and this may
report false positives for unlisted
browsers.
if (sUsrAg.indexOf("Firefox") > -1) {
sBrowser = "Mozilla Firefox";
// "Mozilla/5.0 (X11; Ubuntu; Linux
x86_64; rv:61.0) Gecko/20100101
Firefox/61.0"
}
alert("You are using: " + sBrowser);
But for react there's another package you can use that is npm install react-device-detect
Code example would be
import { browserName, browserVersion }
from "react-device-detect"
console.log(`${browserName}
${browserVersion}`);
After detecting browser you just conditionally render whatever you want to show
I'm using the 'facingMode' constrain in order to switch between the two cameras,
but I'm not able to fully decided whether the user end has an 'environment' camera (back facing camera).. it's not enough to to count the 'videoinput' of the returned promise of enumerateDevices function.
I tried searching for it and all I found was to use the video MediaTrack label and search for containing "facing back" string, which doesnt seem to be constant in all browsers (IOS for instance).
I'm sure there must be a better way :)
A second answer here. The selection of front (facingMode:'user') and back (facingMode:'environment') cameras is an issue for something I'm working on.
It's possible to tell which camera you're using if you have an open .getUserMedia() stream to a camera. stream.getTracks[0].getCapabilities() gives back an object with either a facingMode:'user' or facingMode:'environment' field in it. But you already must have a stream open to the particular device to get this.
Here's what I have discovered using multiple devices in a mobile-device test farm. These are the order of the device entries yielded by .enumerateDevices().
tl;dr: On iOs devices, the front facing camera is the first videoinput device in the list, and the back-facing camera is the second one. On Android devices, the front facing camera or cameras have the string "front" in their device.label values and the back facing camra or cameras have the string "back".
iOS devices
iOS devices running Mobile Safari: the device.label items are all localized to the currently selected national language.
The devices always appear in this order in the device array, with the front camera always appearing as the first device in the array with device.kind:'videoinput'. Here is the list of devices labels I got from every iOS device I tried, auf Deutsch:
audioinput:iPhone Mikrofon
videoinput:Frontkamera
videoinput:Rückkamera
Some iPhones have multiple camera lenses on the back. Nevertheless, the MediaStream APIs in Mobile Safari only show one camera.
You can tell you’re on an iPhone when
navigator.userAgent.indexOf(' iPhone ') >= 0
You can tell you’re on an iPad when
typeof navigator.maxTouchPoints === 'number'
&& navigator.maxTouchPoints > 2
&& typeof navigator.vendor === 'string'
&& navigator.vendor.indexOf('Apple') >= 0
Notice that iPad Safari now lies and claims it's an Intel Mac. It presents this User-Agent string:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15
Android devices
Android devices: the `device.label' items are not localized.
The devices I looked at had different device.label lists. But the cameras I found all had either the string front or back in the device.label.
A Pixel 3A running Android 11 has this list of devices.
audioinput:Standard
audioinput:Speakerphone
audioinput:Headset earpiece
videoinput:camera2 1, facing front
videoinput:camera2 0, facing back
audiooutput:Standard
A Samsung SM-A205F running Android 9 has these devices in order.
audioinput:Default
audioinput:Speakerphone
audioinput:Headset earpiece
videoinput:camera2 1, facing front
videoinput:camera2 2, facing front
videoinput:camera2 0, facing back
audiooutput:Default
This one enumerates two different front-facing selfiecams. The first one offers higher resolution than the second one.
A Samsung SM-G925I running Android 6.0.1
audioinput:Default
audioinput:Speakerphone
audioinput:Headset earpiece
videoinput:camera2 1, facing front
videoinput:camera2 0, facing back
audiooutput:Default
And, by the way, the results of .getSupportedConstraints() don't help much: both iOS and Android give facingMode:true.
It's my experience, across a wide variety of mobile devices with English as their default language, that the device.label property you get back from enumerateDevices() contains the string 'front' or 'back' for the user or environment camera. But on some devices the string is in upper case. So you need to check for those strings in a case insensitive way.
Also, enumerateDevices() conceals the label values unless your user has granted permission to access media. In most browsers, the permission is sticky. That is, once a user has granted it to your web site, it stays granted. But on Mobile Safari devices the permission is not sticky: your user must grant it each time your page loads. You get your user to grant permission with a getUserMedia() call.
This code should let you know whether you have front and back cameras.
async function hasFrontBack() {
let result = {hasBack: false, hasFront: false, videoDevices: []}
try {
const stream = await navigator.mediaDevices.getUserMedia(
{video: true, audio: false})
let devices = await navigator.mediaDevices.enumerateDevices()
const videoDevices = devices.filter(device => {
if (device.kind === 'videoinput') {
if (device.label && device.label.length > 0) {
if (device.label.toLowerCase().indexOf('back') >= 0) {
result.hasBack = true
} else if (device.label.toLowerCase().indexOf('front') >= 0) {
result.hasFront = true
} else { /* some other device label ... desktop browser? */ }
}
return true
}
return false
})
result.videoDevices = videoDevices
/* drop stream */
const tracks = stream.getTracks()
if (tracks) {
for (let t = 0; t < tracks.length; t++) tracks[t].stop()
}
return result
}
catch (ex) {
/* log and swallow exception, this is a probe only */
console.error(ex)
return result
}
}
Once you have this result, you can use getUserMedia() again without prompting the user for permission again.
To determine if we are using the mobile back camera, use this after the stream has loaded. Currently Firefox does not support getCapabilities(). Tested on MacOS/iOS/Android, Safari/Chrome/Firefox.
if (stream.getTracks()[0].getCapabilities) {
isBackCamera = stream.getTracks()[0].getCapabilities()?.facingMode?.[0] === 'environment';
}
I found a decent solution, still not perfect but can help.
determine by the MediaStreamTrack applied constraints:
MediaStream.getVideoTracks()[0].getConstraints().facingMode
As long as you are not using 'exact' while using 'facingMode', it won't be guaranteed..
I have a hybrid app on the play store currently (The Stylista) which runs perfectly across different platforms until its loaded on a Samsung Galaxy 5 or 6..
The app opens to a white screen with my loading gif just spinning and get no further - is there something I am missing? Code should be added?
I have been doing research and see that it is a permission issue..
White screen and loading gif
The answer was adding this snippet to the config file:
<gap:config-file platform="android" parent="/manifest">
<application android:debuggable="true" />
</gap:config-file>
Then I was able to debug in the browser - ALSO with the new android versions, when testing the connection to Cordova, it was not returning the Connection variable thus failing as it was undefined. You can change the code to read:
function getData(tableName, data, onSuccess) {
if (navigator && navigator.connection && navigator.connection.type) {
var networkState = navigator.connection.type;
if (navigator.connection.type == 'none') {
showMessage("You don't appear to be connected to the internet. Please check your connection.");
return;
}
}
Instead of the default:
function getData(tableName, data, onSuccess) {
if (navigator && navigator.connection && navigator.connection.type) {
var networkState = navigator.connection.type;
if (networkState == Connection.NONE) {
showMessage("You don't appear to be connected to the internet. Please check your connection.");
return;
}
}
This will allow your hybrid app to work again :)
I am a WP dev beginner and learning how to write a simple video recorder app. I am using javascript and HTML on VS Pro 2013 and debugging on my actual device Lumia 520 (running Windows Phone 8.1 Preview). I read through a body of documentations and found that the MediaCapture class was the core class for this purpose. So I started following some tutorials and wrote up some functions to access the camera and display a preview in a HTML5 video tag. However, I wasn't successful in getting the MediaCapture object initialized, not even displaying the preview. Below are the major functions of which the first one was problematic:
function initCapture() {
findRearFacingCamera().then(function (cameraId) {
try {
if (cameraId != null && cameraId != "") {
// Initialize the settings
captureInitSettings = null;
captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
captureInitSettings.videoDeviceId = cameraId;
captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.video;
captureInitSettings.photoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.videoPreview;
captureInitSettings.realTimeModeEnabled = true;
// Initialize the capture
oMediaCapture = null;
oMediaCapture = new Windows.Media.Capture.MediaCapture();
oMediaCapture.initializeAsync(captureInitSettings).then(preview, errorHandler);
}
} catch (e) { }
});
}
function preview() {
var preview = document.getElementById("PreviewScreen");
preview.msZoom = true;
if (preview != null) {
preview.src = URL.createObjectURL(oMediaCapture);
preview.play();
}
}
function errorHandler(e) {
var information = document.getElementById("message");
information.innerHTML = e.message;
}
During debugging, I paused at the statement oMediaCapture = new Windows.Media.Capture.MediaCapture(); in the initCapture() function. At this point, captureInitSettings.videoDeviceId has the value: "\\?\DISPLAY#QCOM_AVStream#3&25691128&0&UID32768#{e5323777-f976-4f5b-9b55-b94699c46e44}\Back Sensor", which I believed was a correct identification of the rear camera that I intended to use. Then, when I continued with a break point set at var preview = document.getElementById("PreviewScreen"); in function preview(), which was supposed to be called upon successful initialization of the MediaCapture object, the program was trapped into the errorHandler() function instead, with the error message being "Access is denied" with error number "-2147024891". So I guess the problem rose from the .initializeAsync() function, which was unsuccessful. Deeper causes might also be related to the permission to access the camera. BTW, I have enabled the webcam and microphone capabilities for this app, which was not the issue.
I believe I was missing something either in the code or in the big picture of the development settings. Please help me identify the issue and let me know if any additional information is needed. Much appreciated!
Did you make sure you added the Rear Camera requirement in your Package Manifest?
Turned out the problem was really with my device. Recall that I was testing on a Lumia 520 with Windows Phone 8.1 preview, the firmware stayed at Lumia Black. After upgrading the firmware to Lumia Cyan (parallel to Windows Phone 8.1) using the Nokia Recovery Software Tool, the problem disappeared.
I'm going a window.onerror "SECURITY_ERR: DOM Exception 18: An attempt was made to break through the security policy of the user agent." Each time I load my iOS PhoneGap app. THe app uses local storage and webSQL. I have isolated this error to be throw when I open my db using: db = window.openDatabase("db", "1.0", "Test DB", 1000000);
I haven't had this issue before and my code hasn't changed - this just came out of now where. I've been looking at the iOS 5.1 web view storage bugs and fear it may be related.
Help?
It's a confirmed Apple bug in iOS 5.1. Details here in this PhoneGap/Cordova issue tracker: https://issues.apache.org/jira/browse/CB-347
I have used this and It is working perfectly.Try this
try {
if (!window.openDatabase) {
alert('not supported');
} else {
var shortName = 'WineDatabase';
var version = '1.0';
var displayName = 'PhoneGap Test Database';
var maxSize = 655367; // in bytes
mydb = openDatabase(shortName, version, displayName, maxSize);
}
} catch(e) {
// Error handling code goes here.
if (e == INVALID_STATE_ERR) {
// Version number mismatch.
alert("Invalid database version.");
} else {
alert("Unknown error "+e+".");
}
return;
}
EDIT:
At that time I was using Phonegap on ios.So I hadn't get it,Now on blackberry phonegap I am getting same issue and and found the cause that: while datacable is plugged app is not able to write anything on SDCard.So I unplugged it and run working fine.Sorry buddy not the solution for ios But people who are searching this issue for blackberry can use this solution.