Distinguishing between phone and tablet browsers - c#

I know this question as been beaten to death, but I don't want anything super complicated here.
We have a companion app with our site that is only compatible with 7 and 10-inch tablets. We need to only alert users on those devices about our app. Problem is, I can't go by resolution. My Galaxy S3 has a 1280 x 720 screen, but is obviously not a tablet. I also can't for the life of me find out a way to get the physical size of the screen. The only solution I have come up with is detecting whether the device can make calls with MobileCapabilities.CanInitiateVoiceCall. Unfortuantely, by boss isn't happy with that solution.
So... How can I distinguish between a phone and a tablet in my web app (Server or client side)?
UPDATE: So far it seems that the best approach for Android is something from a blog post by the Android team: All Android phones use "Mobile" in the UserAgent string, so checking for "Mobile" *and "Android" will tell you if it's a phone, while just "Android" should be a tablet. iOS devices should be just as simple--checking for "iPhone" vs "iPad" seems to have worked so far.

I know this is a little late, but I was looking for the same thing.
Wurfl has wat you want. You can implement it easily and and even have an api you can query.
For ASP.NET application first you must place the one-off initialization.
public class Global : HttpApplication
{
public const String WurflDataFilePath = "~/App_Data/wurfl.zip";
private void Application_Start(Object sender, EventArgs e)
{
var wurflDataFile = HttpContext.Current.Server.MapPath(WurflDataFilePath);
var configurer = new InMemoryConfigurer().MainFile(wurflDataFile);
var manager = WURFLManagerBuilder.Build(configurer);
HttpContext.Current.Cache[WurflManagerCacheKey] = manager;
}
}
And then use it like this.
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
var isTablet = device.GetCapability("is_tablet");
var isSmartphone = device.GetCapability("is_smartphone");
For more info check ASP.NET implementation
Hope this helps anyone else looking for this.

You can try to do a user agent detection and search for the keywrords, for example, all Non tablet devices have a "Mobile Safari" key words on their user agent.

Related

Get users current location

Have been working on WPF application where users current location had to be identified (it is configurable in settings = no anonymous tracking for private data). Several solutions has been tested.
Alternative number 1 - works fine on different computers, also with VPN is on. Location is tracked based on IP address and everything seems to be good. However downside of this is that it uses external sources, like third party websites for getting IP address and then read that IP address to get the location.
public string GetPublicIP()
{
String direction = string.Empty;
WebRequest request = WebRequest.Create("http://website/");
using (WebResponse response = request.GetResponse())
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
direction = stream.ReadToEnd();
}
//Search for the ip in the html
// code here
return direction;
}
Alternative number 2 - C# Geolocator class. This works fine with additional JSON file with geolocation coordinates and location data. However on corporate computer PositionChanged event is not firing for some reason. Not sure is it blocked somehow. No exceptions, but location is not recognized due to event is not firing. On my personal computer same solution works fine (same Windows version - Windows 10). Geolocator.ReportInterval = 1000; is also not force firing event every 1 second.
private void RunGeoTracker()
{
if (Geolocator == null)
{
Geolocator = new Geolocator();
Geolocator.DesiredAccuracy = PositionAccuracy.High;
Geolocator.MovementThreshold = 100; // The units are meters.
Geolocator.ReportInterval = 1000;
Geolocator.PositionChanged += this.PositionChanged;
}
}
private async void PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
await Dispatcher.InvokeAsync(() =>
{
// code here
}
}
Are there are any alternatives, preferably without using any REST API or websites. Preferably using JSON or database for getting location data. I heard there is some PowerShell solution? Can't find examples. I mean basically Latitude and Longitude are needed. All the rest can be already achieved.
The Windows-native Geolocator API is limited by the wide variety of states a Windows laptop can be in - airplane mode, location settings disabled in common Windows settings, disabled in application-specific settings, or merely that no data providers are available to the OS (GPS satellites, WiFi triangulation, internet connectivity, OEM hardware and firmware etc.). So, any strategy to use OS-specific Geolocator API is contingent on your application (a) needing high-accuracy GPS fix, (b) involving mobility - e.g a worker driving with their open laptop in a car, or (c) ability to guide the user through UX that helps them get a location fix.
That said, do check if your Geolocator object initialization is done correctly via the steps in Microsoft's documentation - they matter!
IP geolocation has its limitations around VPN users, but it has much fewer ways of failing once you ship the software to real-world PCs and laptops. The following REST API for example will not only auto-detect the device's public IP but also respond with the approximate city-level location, including coarse latitude+longitude.
https://ep.api.getfastah.com/whereis/v1/json/auto?fastah-key=<trial_key>
The JSON response may look as follows, where the public IP is echoed back to your client application:
{
"ip": "146.75.209.1",
"isEuropeanUnion": false,
"locationData": {
"countryName": "Australia",
"countryCode": "AU",
"cityName": "Canberra",
"cityGeonamesId": 2172517,
"lat": -35.28,
"lng": 149.13,
"tz": "Australia/Sydney",
"continentCode": "OC"
}
}
The trick is to use IP location APIs that constantly update themselves as the internet and mobile landscape evolve fast.
Disclaimer: I am the developer of the above Fastah API service, so I may be a bit biased here :)

Turn on Airplane mode using AccessibilityService Class in Xamarin

I want to turn on or off airplane mode using AccessibilityService.
Any idea how we can do it?
Yes, you can't change it from app that target bigger than Android 4.2. But you can open the settings page instead if you want:
if (Android.OS.Build.VERSION.SdkInt < BuildVersionCodes.JellyBeanMr1)
{
try
{
Intent intentAirplaneMode = new Intent(Android.Provider.Settings.ActionAirplaneModeSettings);
intentAirplaneMode.SetFlags(ActivityFlags.NewTask);
Context.StartActivity(intentAirplaneMode);
}
catch (ActivityNotFoundException e)
{
Log.Error("exception", e + "");
}
}
else
{
Intent intent1 = new Intent("android.settings.WIRELESS_SETTINGS");
intent1.SetFlags(ActivityFlags.NewTask);
Context.StartActivity(intent1);
}
}
And AccessibilityService can used with dependency service.
Kamal you’re not going to be able to do it.
It doesn’t seem like you’re doing iOS, but iOS has a lot of limitations due to privacy and security purposes that won’t allow you to do this. You can see more details here stackoverflow.com/q/20469425/11104068
Also android blocked being able to do this from Android 4.2 onwards. Only system apps can make changes to Airplane mode, as you can see here stackoverflow.com/a/5533943/11104068
Since it doesn’t seem you’re creating a system app that gets installed with the operating system, and not through the Play Store, you won’t be able to get permissions. It will give you an error /exception even if you implement everything

Android's - performHapticFeedback vs Vibrator - documentation and use

TL;DR:
Would appreciate any extra information on Android's
abstract class Vibrator
vs
performHapticFeedback
Preferably avoiding the use of the Vibrator class and prioritising performHapticFeedback to circumvent having to ask the user for permissions, and rely only on their system's preference.
Scenario:
I'm working with Xamarin trying to implement Haptic Feedback for Android and iOS.
Now, whereas the iOS documentation has a short explanation, which I've implemented as the following:
void Platform.Vibrate(HapticsIntensity HapticsIntensity)
{
UIKit.UIImpactFeedbackGenerator ImpactFeedbackGenerator;
switch (HapticsIntensity)
{
case HapticsIntensity.Light:
ImpactFeedbackGenerator = new UIKit.UIImpactFeedbackGenerator(UIKit.UIImpactFeedbackStyle.Light);
break;
case HapticsIntensity.Medium:
ImpactFeedbackGenerator = new UIKit.UIImpactFeedbackGenerator(UIKit.UIImpactFeedbackStyle.Medium);
break;
case HapticsIntensity.Heavy:
ImpactFeedbackGenerator = new UIKit.UIImpactFeedbackGenerator(UIKit.UIImpactFeedbackStyle.Heavy);
break;
default:
ImpactFeedbackGenerator = null;
break;
};
if (ImpactFeedbackGenerator != null)
{
ImpactFeedbackGenerator.Prepare();
ImpactFeedbackGenerator.ImpactOccurred();
}
}
The Android documentation for Haptic Feedback states that the method performHapticFeedback expects a HapticFeedbackConstant as a parameter.
public boolean performHapticFeedback (int feedbackConstant)
The available feedbackConstant's are here, but they seem to have no difference between them.
Calling:
LongPress
Engine.AndroidActivity.Window.DecorView.PerformHapticFeedback(Android.Views.FeedbackConstants.LongPress);
has the same effect as
VirtualKey
Engine.AndroidActivity.Window.DecorView.PerformHapticFeedback(Android.Views.FeedbackConstants.VirtualKey);
or
KeyboardTap
Engine.AndroidActivity.Window.DecorView.PerformHapticFeedback(Android.Views.FeedbackConstants.KeyboardTap);
moreover, some of the FeedbackConstants don't even result in haptic feedback.
Does anyone know where I could find any more documentation around this matter?
The reason why I ask is that I am implementing an abstract layer over Xamarin with Invention where my intention is to have my method calls like:
Vibrate(HapticsIntensity.Light);
Vibrate(HapticsIntensity.Medium);
Vibrate(HapticsIntensity.Heavy);
This works today, but where on iOS I get the tactile feedback of Light, Medium and Heavy vibration, on Android, I can't differentiate between them.
Now, I know Android has a Vibrate class (see here), which allows for granular control; however, to use this I need to add to my manifest or ask for specific permissions for my app (android.permission.VIBRATE), and that is not optimal.
Also, if I add the android.permission.VIBRATE permission to my manifest, it seems like (if the device has Haptic Feedback enabled in its settings), I don't even need to add the Vibrate() method call to my buttons` onClick; and they will already provide the tactile feedback (BZZZTT!!1!).
It totally depends upon if the device OEM has altered ASOP code and the vibration timing arrays in com.android.internal.R.array resource to enable a special haptic feedback "engine" that they are using on their device.
By default, the hardware OEMs are only required to support (in hardware) a standard on/off vibration (linear actuator, weighted rotary, etc..), not a "true" haptic feedback one which is normally based upon waveforms.
In comparison to the newer iOS devices (7|8+?), they are using the "Taptic Engine" (fancy speak for an "advanced linear actuator") for haptic feedback and only recently are Android devices "catching" up on the hardware side (new OnePlus, Pixel 3s, etc...) are starting to include more advanced haptic/vibration hardware (whether are not the OEM has done any special with that new hardware, you decide...)
So if you look at ASOP's PhoneWindowManager.java you will find that most of the HapticFeedbackConstants get lumped into a few VibrationEffects constants such as:
~~~
VibrationEffect.EFFECT_TICK
VibrationEffect.EFFECT_CLICK
VibrationEffect.EFFECT_HEAVY_CLICK
~~~
Look at the source if you want to see what the ASOP default VibrationEffects would be for a specific HapticFeedbackConstants:
PhoneWindowManager.java
If you have to provide manual-based haptic for your app for some reason, you can use the Vibrator API and provide the byte array for your on/off timing and then special case it for phone devices at offer more hardware features.

Is it possible to launch system/third party app using an NDEFLaunchApp record to get the URI and by using LaunchUriAsync without NFC Tags?

So I have spent the whole night looking like a zombie in the morning trying to figure out how the OS handles an NFC tap for an NDEFLaunchApp Record and I have known the following.
I'm pretty sure that there is a workaround which lets you launch a system app / third party app (if you know the product Id / GUID) from your app. As there are apps in the Windows Phone Store which I have somehow figured out what I've been trying to.
I have come up with the following code:
NdefLaunchAppRecord appLaunchRecord = new NdefLaunchAppRecord();
appLaunchRecord.AddPlatformAppId("WindowsPhone", "{App GUID}");
appLaunchRecord.Arguments = "_default";
// Creating a new NdefMessage from the above record.
var message = new NdefMessage { appLaunchRecord };
// Getting the record from the message that we just created
foreach (NdefLaunchAppRecord record in message)
{
var specializedType = record.CheckSpecializedType(false);
if (specializedType == typeof(NdefLaunchAppRecord))
{
var x = String.Join(" ", record.Payload);
// Getting the payload by GetString gets a formatted Uri with args
string result = System.Text.Encoding.UTF8.GetString(record.Payload, 0, record.Payload.Length);
// result = "\0\fWindowsPhone&{5B04B775-356B-4AA0-AAF8-6491FFEA5630}\0\b_default";
// result = "(null)(form feed)WindowsPhone&{App GUID}(null)(backspace)_default
// So this will be sent to the OS and I believe the OS will then launch the specified app by an unknown protocol
// like xxx://result
// and the app will be launched?
// So is it then possible to somehow call the following:
await Windows.System.Launcher.LaunchUriAsync(new Uri("OUR MAGIC RESULT?", UriKind.RelativeOrAbsolute));
If anyone has / can figure out a way for this, it would be a REAL Service to the WP Community as developers are restricted by Microsoft to open certain settings / apps which are actually needed by those apps. For instance (speech settings, audio settings, about settings, alarms, region settings, date+time);
APPS that possibly have a workaround:
Music Hub Tile (Launches the old Music+Videos Hub)
http://www.windowsphone.com/en-gb/store/app/music-hub-tile/3faa2f9e-6b8d-440a-bb60-5dd76a5baec1
Tile for Bing Vision
http://www.windowsphone.com/en-gb/store/app/tile-for-bing-vision/05894022-e18c-40a4-a6cc-992383aa7ee8
There are reserved uri schemes for bing and zune.
See: http://msdn.microsoft.com/en-us/library/windows/apps/jj207065(v=vs.105).aspx
Those two apps propably use these and have found some undocumented use of the scheme.
If there is an uri scheme that launches any app by guid from within your app, it is hidden well.
Currently you can only launch apps that registered for an uri scheme or file association.

How to turn GPS on in Android from browser(c#.net web application)

when my sales guys access my c#.net website/web application through browser, it will send the GPSco-ordinates to the server only if the GPS tuned on, but occasionally i am facing problem when my agents turning off the gps on their android tablets, so i am thinking of turning their GPS ON grammatically , can any one please help me how can i achieve that one
Thanks
Create a thread that constantly checks for a value in your webservice like GPS status=true/false
and call this function when the value is turned true
public void turnGPSOn()
{
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
this.ctx.sendBroadcast(intent);
String provider = Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if(!provider.contains("gps")){ //if gps is disabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
this.ctx.sendBroadcast(poke);
}
}
and add Permissions in the manifest too

Categories