I only get NETWORK_PROVIDER when requesting GPS_PROVIDER on Huawei P20? - xamarin.android

My app uses Location Manager to get location updates. On Samsung etc. it works fine but not for all Huawei P20 users. With this code
locationMgr.RequestLocationUpdates (LocationManager.GpsProvider, 2000, 1, this);
...
public void OnLocationChanged(Android.Locations.Location location)
{
Console.WriteLine("Location changed update: {0} provider, {1} accuracy", location.Provider, location.Accuracy);
...
...the OnLocationChanged method will in certain scenarios return "network" as provider even though I've specified "gps".
My test P20 device has the option to set "best location" in the device settings. If turned off, I get "gps" as provider with good accuracy but with the setting turned on I only get "network" with bad accuracy. Is this a bug in my code, xamarins implementation, android or Huaweis android implementation. Is there a way to force to only get "gps"?

Related

Core telephony CTCarrier and isoCountryCode. How to get user's current cellular provider's country?

I would like to get user's current country without asking for location. So I thought using CTCarrier class property isoCountryCode. To get access to CTCarrier I'm using serviceSubscriberCellularProviders, which returns "A dictionary that contains carrier information about each service".
https://developer.apple.com/documentation/coretelephony/cttelephonynetworkinfo/3024511-servicesubscribercellularprovide.
Now when I query serviceSubscriberCellularProviders it returns 2 objects - nil and presumably my home cellular service provider.
let networkInfo = CTTelephonyNetworkInfo()
let dictionary = networkInfo.serviceSubscriberCellularProviders;
for (type, value) in dictionary ?? [:] {
let country:String? = value.isoCountryCode == nil ? "nil" : value.isoCountryCode;
print("serviceSubscriberCellularProviders: "+country!)
}
If I was abroad and connected to roaming service provider would I still get two objects - home and now instead of nil - roaming service provider? And inside roaming service provider property isoCountryCode would return the actual country of the roaming service provider?
The documentation is confusing for me... What exactly is isoCountryCode for home cellular service provider? Let's say I live in France and my service provider is of course from France - isoCountryCode would return "FR". Now if I go on a vacation to Germany - what isoCountryCode would return now? Still the same "FR" or "DE"?
As the documentation explains:
Note
In this context, the “home” provider is the one with which the user has a cellular plan, as opposed to a roaming provider.
So, you will always get FR, even when roaming, if your home provider is in France.
The reason there are two possible values is that iPhones now support up to two sims; One physical and one e-SIM, so there may be two different cellular providers on a phone.

Google Home. Problem regarding configure a Lock device

Intro:
was created a Google Smart Home project
was configured a proxy server via ngrok to redirect the Google request to my local machine
I develop an IoT project that has the ability to open/close a lock. I need to implement Google integration to use the Google Assistant to control the user locks. I have implemented OAuth Server for Google. Also I have implemented some controllers to handle Google Action Intents: SYNC, QUERY and EXECUTE. Google send a request with the SYNC intent and App response a payload that contain devices list with specific settings. Instance:
{
requestId: 'requestIdOfGoogle', // contains in the request body
payload: {
agentUserId: 'userId123', // matches user id inside app system
devices: [
{
id: 1,
type: 'action.devices.types.LOCK', // device type
traits: ['action.devices.traits.LockUnlock'], // feature that has a device
name: {
name: 'Kos Lock'
},
willReportState: true,
roomHint: 'Main Door',
deviceInfo: { // Test data
manufacturer: 'smart-home-inc',
model: 'hs1234',
hwVersion: '3.2',
swVersion: '11.4'
}
}
]
}
}
Then Google send requests to my server with QUERY intent to get info about state of a devices, instance
{
requestId: 'requestIdOfGoogle', // contains in the request body
payload: {
devices: {
1: {
status: 'SUCCESS',
online: true,
isLocked: true,
// isJammed - Boolean. Whether the device is currently jammed and therefore its
// locked state cannot be determined.
isJammed: false
}
}
}
}
But after sending a response a test lock isn't configured and a user can't control one with Google Assistant.
enter image description here
I have tried to add other traits for a lock but it didn't help me. Also I have the same problem when I try to configure a Door device. But when I send to Google a Light device it works successfully. When you use the LockUnlock trait then Google Doc recommends to setup secondary user verification but it's optional.
I don't understand that do incorrect. If someone faced such a problem and solved it then could you help me, please
Prerequisites:
use node ^14.0.0
programming language - js
Touch controls are not supported for every device, and locks are not a device type that can be controlled directly. But they will still respond to voice commands.

Workaround for missing "Web Push" on Safari for my PWA

I am developing a PWA that requires Push-Notifications. Sadly IOS/Safari does not support https://w3c.github.io/push-api/#pushmanager-interface for now, so I think i might have to wrap a native APP around in some way.
In Android (before their "Trusted Web Activities" was a thing) you could use a WebView to basically display a headless Chrome-View in your App. Whats the equivalent in IOS and how does the interaction between push-notifications and the Webapp (the browser need to jump to a specific page) work?
One more thing I need is integration with our companys Mobile Device Management, which is Microsoft Intune. Having integrated MDMs in Android in the past i Know that this might be a major pain in the a**, so i'm considering to build the wrapper myself, for maximum flexibility. Another option would be something like Ionic, not sure now.
This may not necessarily work in your situation, but I had the exact same issue with a PWA for Safari and I solved it by just using long polling. It will allow you to get around all of the limitations with Safari and I was able to redirect and load sections within our SPA.
async function subscribe() {
let response = await fetch("/subscribe");
if (response.status == 502) {
// Status 502 is a connection timeout error,
// may happen when the connection was pending for too long,
// and the remote server or a proxy closed it
// let's reconnect
await subscribe();
} else if (response.status != 200) {
// An error - let's show it
showMessage(response.statusText);
// Reconnect in one second
await new Promise(resolve => setTimeout(resolve, 1000));
await subscribe();
} else {
// Get and show the message
let message = await response.text();
showMessage(message);
// Call subscribe() again to get the next message
await subscribe();
}
}
subscribe();
https://javascript.info/long-polling

fetchTimeEstimate not authorised - but strangely only on some iPhone's

I'm using the Uber Rides iOS SDK and currently only interested only in how long an uber will take to arrive, we just launch the uber app to the app if the user wants to proceed.
Strangely on some iPhones and the simulator it returns a result pretty much always (unless no cars available), but on others it says not authorised as a response.
Here is the code for the call:
func fetchTimeEstimates(from location: CLLocation, completion: #escaping (_ estimate: TimeEstimate?) -> Void) {
ridesClient.fetchTimeEstimates(pickupLocation: location) { (estimates, response) in
if response.statusCode != 200 || estimates.isEmpty {
print("UBER fetchTimeEstimates returned \(response.statusCode)")
completion(nil)
return
}
// Set default to uberX
for i in 0...estimates.count - 1 {
if let id = estimates[i].productID, id == UberRides.uberXProductId {
completion(estimates[i])
return
}
}
completion(estimates[0])
}
}
Im using server token setup in my plist
Although it either consistently works or does not on peoples phones, It does not seem a consistent pattern, i.e. its not that the first 5 devices worked and then it stopped working after that, or type of phone or OS version.
Heres what I tried:
Adding a failing devices user to list of developers in the dashboard authorisation screen, no difference.
Requesting full api access for a 'request', nope
checking if a brand new phone 8 with brand new user credentials both for the phone and uber login, works fine so don't explain why we go two people in the office where its consistently refused.
adding the app ID in the developer console.
Any ideas why I'm getting inconsistent results, its a challenge to debug as it always works on my test phones, but annoyingly it fails consistently on the CEO's phone.

How to get roaming status in IOS

I want to get notified when I enter in roaming area in my iOS app, I have already read the documentation for NSLocale , SCNetworkReachability , and core telephony (I may have missed something). I need to get this info from sim (or any other way if possible).
The usual method would be to get the carrier's country code from the core telephony interface and then compare that with the country code from reverse geocoding the location.
Advantages: works with VPNs and when the user has disabled data when roaming.
Disadvantages: doesn't work without location.
I don't have any non-copyright code for you, but the key you need in the place marks dictionary you need for country code is #"CountryCode"
Geocoding would be something like:-
CLGeocoder* geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler: ^(NSArray* placemarks){}]
The country code for the provider would be
NSString* homeCountry = [netInfo.subscriberCellularProvider isoCountryCode];
Hope this helps
There's no iOS API for detecting roaming status, but you can use third party services like http://ipinfo.io (my own service) to find out the current country of even carrier code based on the device's IP address. You can then compare that to the CTCarrier details to determine if the device is roaming. Here's the standard ipinfo.io API response:
$ curl ipinfo.io/24.32.148.1
{
"ip": "24.32.148.1",
"hostname": "doc-24-32-148-1.pecos.tx.cebridge.net",
"city": "Pecos",
"region": "Texas",
"country": "US",
"loc": "31.3086,-103.5892",
"org": "AS7018 AT&T Services, Inc.",
"postal": "79772"
}
Custom packages are available that also include the mnc/mcc details of mobile IPs though. See http://ipinfo.io/developers for details.
We used to have the same problem before on iOS and we ended up building a dedicated API for it. It works by comparing the IP Geolocation (based on IP address of the requester party) of the device against it's GPS position provided. If the user is detected as being physically outside of the country determined by their IP address, then they are deemed to be roaming.
We decided to offer this API for free and unlimited, no restrictions, no throttling. No credit card, not even account required, just run a simple query:
curl -X GET --header 'Accept: application/json' 'https://api.bigdatacloud.net/data/am-i-roaming?latitude=[your latitude]&longitude=[your longitude]'
the response is very simple, just a true or false:
{
"isRoaming": true
}
It's very fast too! Our servers usually respond in under 1 millisecond time.
This API can obviously give a false positive results if executed via VPN/proxy or a non cellular interface, therefore it would be suggested to make sure you're using cellular interface when making the call.
Enjoy!

Resources