i am new to Xamarin, i have a code to get GPS location, which is working fine for IOS 6 but for IOS 8 it is not fetching the long. and lat.
//Check for getting current lat/long
CLLocationCoordinate2D toLocation;
private CLLocationManager locationManager;
if (!CLLocationManager.LocationServicesEnabled) {
AppDelegate.currLat = "";
AppDelegate.currLong = "";
gpsFlag = false;
} else {
gpsFlag = true;
locationManager = new CLLocationManager();
locationManager.StartUpdatingLocation();
if (locationManager.Location != null) {
toLocation = locationManager.Location.Coordinate;
AppDelegate.currLat = Convert.ToString (toLocation.Latitude);
AppDelegate.currLong = Convert.ToString (toLocation.Longitude);
}
locationManager.StopUpdatingLocation ();
}
i am using the Universal Template to create Application in Xamarin. i have R&D for IOS 8 GPS location, i got to know that i need to add "NSLocationAlwaysUsageDescription" to info.plist, but i am not getting how to add this.
getting-gps-location-using-core-location-in-ios-8
Please help me how can get the GPS location for IOS 8
public class LocationHelper
{
private static bool _isTracking;
public static bool IsTracking { get { return _isTracking; } }
private static string _longitude;
private static string _latitude;
private static DateTime _lastUpdated;
public static event EventHandler LocationUpdated;
public static CLLocationManager LocationManager { private set; get; }
public static void StartLocationManager(double distanceFilter, double accuracy)
{
LocationManager = new CLLocationManager();
if (LocationManager.RespondsToSelector(new MonoTouch.ObjCRuntime.Selector("requestWhenInUseAuthorization")))
LocationManager.RequestWhenInUseAuthorization();
LocationManager.DistanceFilter = CLLocationDistance.FilterNone;
LocationManager.DesiredAccuracy = accuracy;
LocationManager.LocationsUpdated += LocationManager_LocationsUpdated;
LocationManager.StartUpdatingLocation();
_isTracking = true;
System.Diagnostics.Debug.WriteLine("Location manager started ");
}
public static void StopLocationManager()
{
if (LocationManager != null)
{
LocationManager.LocationsUpdated -= LocationManager_LocationsUpdated;
LocationManager = null;
_isTracking = false;
}
}
public static void Refresh()
{
LocationManager.StopUpdatingLocation();
LocationManager.StartUpdatingLocation();
}
private static void LocationManager_LocationsUpdated(object sender, CLLocationsUpdatedEventArgs e)
{
if (LocationUpdated != null)
LocationUpdated(null, null);
UpdateLocation(e.Locations[e.Locations.Length - 1]);
}
private static void UpdateLocation(CLLocation location)
{
_longitude = location.Coordinate.Longitude.ToString();
_latitude = location.Coordinate.Latitude.ToString();
_lastUpdated = DateTime.Now;
}
public static LocationResult GetLocationResult()
{
return new LocationResult(_latitude, _longitude, _lastUpdated);
}
public class LocationResult
{
public DateTime UpdatedTime { private set; get; }
public string Latitude { private set; get; }
public string Longitude { private set; get; }
public LocationResult(string latitude, string longitude, DateTime updated)
{
UpdatedTime = updated;
Latitude = latitude;
Longitude = longitude;
}
}
}
This works in iOS8I'm using this static class, every time before taking coordinates I'm calling Refresh() I'm cant find thread where i found this solution but this causes to return location immediately, and then call to GetLocationResult() to get location and when u finished with locationManager call StopLocationManager()
When you create a new instance of CLLocationmanager it is extremely important that you call the following:
manager = new CLLocationManager();
1.) manager.RequestWhenInUseAuthorization (); //This is used if you are doing anything in the foreground.
2.) manager.RequestAlwaysAuthorization ();// This is used if you want to scan in the background
Of course these are iOS 8 only methods so makes sure to do a version check with: UIDevice.CurrentDevice.CheckSystemVersion (8, 0);
This isn’t enough though to prompt your user for access to location. You will need to now modify your Info.plist! You will need to add a new string entry called NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription. Then you can specify the message you want to prompt your user with when attempting to get location
Related
I have an app which uses zxing to scan qr codes in the app. However when I build the app with these scripts in the scene the app crashes on startup. I thought it was something in the Awake() or Start() but I've wrapped those methods in a try catch, and even then I'm not getting any errors, and it doesn't crash on android and in the editor.
I don't have access to a Mac, and am using Unity Cloud Build to build it.
I also don't know how to enable permissions, I thought I did when creating the .p12 file, but I've also found that there's an info.plist file that I have to request permissions with.
Prior research I found this Unity Question about adding items to the Xcode project but not only did including the xcodeapi give me errors, but the using statements didn't work.
There are two scripts
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class WebCamController : MonoBehaviour {
public int desiredWidth = 1280;
public int desiredHeight = 720;
public int desiredFPS = 60;
public RawImage output;
[HideInInspector]
public WebCamTexture webcamTexture;
void Start ()
{
webcamTexture = new WebCamTexture(desiredWidth, desiredHeight, desiredFPS);
output.texture = webcamTexture;
Play();
}
public void Play()
{
webcamTexture.Play();
}
public void Pause()
{
webcamTexture.Stop();
}
}
and
using UnityEngine;
using System.Collections;
using ZXing;
using ZXing.QrCode;
using ZXing.Common;
using System;
public class CodeScanner : MonoBehaviour {
private static CodeScanner _instance;
public static CodeScanner Instance
{
get
{
if(null == _instance)
{
Debug.Log("Code Scanner Instance not found");
}
return _instance;
}
}
[Header("References")]
public WebCamController wcc;
[Header("Properties")]
private BarcodeReader codeScanner;
private string lastScanned = "";
public delegate void Found(string text, string type);
public event Found OnCodeScanned;
private bool active;
public void Awake()
{
_instance = this;
}
void Start () {
codeScanner = new BarcodeReader();
StartCoroutine(ReadCode());
wcc.Play();
}
IEnumerator ReadCode()
{
while (active)
{
try
{
var data = codeScanner.Decode(wcc.webcamTexture.GetPixels32(), wcc.webcamTexture.width, wcc.webcamTexture.height);
if (data != null)
{
//if (data.Text != lastScanned)
//{
OnCodeScanned(data.Text, data.BarcodeFormat.ToString());
//}
lastScanned = data.Text;
}
}
catch(Exception e)
{
}
yield return new WaitForSeconds(1.0f);
}
}
public void Activate()
{
wcc.Play();
active = true;
StartCoroutine(ReadCode());
}
public void Stop()
{
active = false;
wcc.Pause();
}
}
My device is added properly to the .p12 certificate I can compile and run the program without these scripts in the scene.
I am trying to get the location. I implement everything but nothing works.
This is my class:
public class Best2 : CLLocationManagerDelegate
{
public CLLocationManager _locationManager;
private Int32 _numEvento;
public Best2()
{
}
protected Best2(NSObjectFlag t) : base(t)
{
}
protected internal Best2(IntPtr handle) : base(handle)
{
}
public Best2(Int32 paramEvento)
{
_numEvento = paramEvento;
_locationManager = new CLLocationManager ();
_locationManager.PausesLocationUpdatesAutomatically = false;
_locationManager.DesiredAccuracy = CLLocation.AccurracyBestForNavigation;
if (UIDevice.CurrentDevice.CheckSystemVersion (9, 0)) {
_locationManager.AllowsBackgroundLocationUpdates = true;
}
_locationManager.Delegate = this;
StartLocationUpdates();
}
public void StartLocationUpdates ()
{
if (CLLocationManager.LocationServicesEnabled) {
_locationManager.RequestLocation();
System.Diagnostics.Debug.WriteLine(
String.Format(
"FA&)#2 RequestLocation() Data:D {0}"
, DateTime.UtcNow
)
);
}
}
public override void Failed (CLLocationManager manager, Foundation.NSError error)
{
System.Diagnostics.Debug.WriteLine(
String.Format(
"FA&)#2 Failed() Data:D {0}"
, DateTime.UtcNow
)
);
}
public override void UpdatedLocation (CLLocationManager manager, CLLocation newLocation, CLLocation oldLocation)
{
System.Diagnostics.Debug.WriteLine(
String.Format(
"FA&)#2 UpdatedLocation() Data:D {0}"
, DateTime.UtcNow
)
);
}
I call this way:
Best2 position = new Best2(1);
Based in the apple documentation, I think it should call the method Failed if not works and UpdatedLocation if works. But nothing is calling.
I already try to put the class receiving events, but it doesn't work either.
According to the documentation about Request Location we know that if we want to use location in iOS we must follow the steps below:
Add the NSLocationWhenInUseUsageDescription key and the NSLocationAlwaysAndWhenInUseUsageDescription key to your Info.plist file.
If your app supports iOS 10 and earlier, add the NSLocationAlwaysUsageDescription key to your Info.plist file.
Then before RequestLocation() we need to call RequestAlwaysAuthorization() or RequestWhenInUseAuthorization() to get user's authentication.
At last we can get the location but you misunderstand the event:
I think it should call the method Failed if not works and
UpdatedLocation if works.
If it works the event LocationsUpdated() will fire not UpdatedLocation().
I ask because I'm noticing on my site, if I hit it with an iPhone, sometimes it shows the mobile views, sometimes it shows regular views.
I've also read that MVC 4's not particularly effective at determining if the browser is from a mobile device or not, is that true? If so, anything we can do about it?
Update: Microsoft have published a workaround package for this bug.
I have added this workaround at here,
public class MyDefaultViewLocationCache : DefaultViewLocationCache, IViewLocationCache
{
public MyDefaultViewLocationCache(TimeSpan timeSpan): base(timeSpan)
{
}
public MyDefaultViewLocationCache()
: base()
{
}
public new string GetViewLocation(HttpContextBase httpContext, string key)
{
var location = base.GetViewLocation(httpContext, key);
if (location == null)
{
var cache = httpContext.Cache;
RemoveAllCacheStartWith(key, cache);
}
return location;
}
private static void RemoveAllCacheStartWith(string key, System.Web.Caching.Cache cache)
{
var keyWithoutDisplayMode = key.Substring(0, key.Substring(0, key.Length - 1).LastIndexOf(':') + 1);
var items = new List<string>();
var enumerator = cache.GetEnumerator();
while (enumerator.MoveNext())
{
var _key = enumerator.Key.ToString();
if (_key.StartsWith(keyWithoutDisplayMode))
{
items.Add(_key);
}
}
foreach (string item in items)
{
cache.Remove(item);
}
}
public new void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath)
{
base.InsertViewLocation(httpContext, key, virtualPath);
}
}
// In App Start
ViewEngines.Engines.OfType<RazorViewEngine>().First().ViewLocationCache =
new MyDefaultViewLocationCache();
For detail see this.
I want to get the user's latitude and longitude in my BlackBerry app, and then generate the maps according to it.
How can I do that?
my code is:
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;
import net.rim.device.api.system.Application;
public class GPS_Location
{
private String log;
double longi;
double lati;
public GPS_Location()
{
new LocationTracker();
}
public boolean onClose()
{
Application.getApplication().requestBackground();
return false;
}
class LocationTracker extends TimerTask
{
private double longitude, latitude;
private Timer timer;
private LocationProvider provider;
Criteria cr;
public LocationTracker()
{
timer = new Timer();
cr= new Criteria();
resetGPS();
timer.schedule(this, 0, 60000);
}
public void resetGPS()
{
try
{
provider = LocationProvider.getInstance(cr);
if(provider != null)
{
/*provider.setLocationListener(null, 0, 0, 0);
provider.reset();
provider = null;*/
provider.setLocationListener(new MyLocationListener(), 3, -1, -1);
}
//provider = LocationProvider.getInstance(null);
} catch(Exception e)
{
}
}
public void run()
{
System.out.println("********************");
}
private class MyLocationListener implements LocationListener
{
public void locationUpdated(LocationProvider provider, Location location)
{
if(location != null && location.isValid())
{
QualifiedCoordinates qc = location.getQualifiedCoordinates();
try
{
lati = location.getQualifiedCoordinates().getLatitude();
System.out.println("********************latitude :: "+lati);
longi = location.getQualifiedCoordinates().getLongitude();
System.out.println("********************longitude ::"+longi);
}
catch(Exception e)
{
}
}
}
public void providerStateChanged(LocationProvider provider, int newState)
{
//LocationTracker.this.resetGPS();
if(newState == LocationProvider.TEMPORARILY_UNAVAILABLE)
{
provider.reset();
provider.setLocationListener(null, 0, 0, -1);
}
}
}
}
}
A Google result (coincidentally Stack Overflow) reveals the API call getLocation(). This may provide you with a starting point for retrieving the longitude and latitude.
Addition; the following may be helpful (from a subsequent Google search using terms based on your comment): http://www.blackberryforums.com/developer-forum/133152-location-api.html. I would quote some of the code, but there is a fair bit of information there. Let's just hope the link remained valid, or you post your solution when found :)
Actually I want to make an application which will getGlobalEvent and control that event through another custom application. Is there any way to do so. Can i get global event from a particular application? Its like an application which will lock custom application in your blackberry, if you add following application in that locking app list and put password to access then when u try to open that application, it will ask for a password which u set in the locking app.
Common advices
this should be background application
in timer thread check current foreground application
use custom global modal dialog to request password
if password was wrong close app by simulating back key press or move app to background
Checking Application
Have to say, there can be several processes within one application so we will perform check based on module name:
private String getModuleNameByProcessId(int id) {
String result = null;
ApplicationManager appMan = ApplicationManager.getApplicationManager();
ApplicationDescriptor appDes[] = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
if (appMan.getProcessId(appDes[i]) == id) {
result = appDes[i].getModuleName();
break;
}
}
return result;
}
Move application to Background?
Yep, there's no requestBackground() in ApplicationManager... so what you can do is requestForeground() on the next best app which is not on foreground, and this will move active app to background! You can even bring up Home Screen with requestForegroundForConsole():
protected int switchForegroundModule() {
int id = -1;
ApplicationManager appMan = ApplicationManager.getApplicationManager();
ApplicationDescriptor appDes[] = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
if (!appDes[i].getModuleName().equalsIgnoreCase(STR_MODULE_NAME)) {
id = appMan.getProcessId(appDes[i]);
appMan.requestForeground(id);
// give a time to foreground application
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
return id;
}
Global Dialog
Just to input password you can extend Dialog, it will be easier to consume result:
class PaswordDialog extends Dialog {
private BasicEditField mPwdField = new BasicEditField();
public PaswordDialog() {
super(Dialog.D_OK_CANCEL, "Enter password", Dialog.CANCEL, null,
Dialog.FIELD_HCENTER);
add(mPwdField);
}
public String getPassword() {
return mPwdField.getText();
}
}
And password check will look like:
private boolean checkPassword() {
boolean result = false;
final PaswordDialog pwdDlg = new PaswordDialog();
invokeAndWait(new Runnable() {
public void run() {
Ui.getUiEngine().pushGlobalScreen(pwdDlg, 0,
UiEngine.GLOBAL_MODAL);
}
});
result = ((Dialog.OK == pwdDlg.getSelectedValue()) && pwdDlg
.getPassword().equalsIgnoreCase(STR_PASSWORD));
return result;
}
Put this all together
Sample to block Adress Book App:
public class LockMainApp extends Application {
private static final String STR_MODULE_NAME = "net_rim_bb_addressbook_app";
private static final String STR_PASSWORD = "12345";
int mFGProcessId = -1;
public LockMainApp() {
Timer timer = new Timer();
timer.schedule(mCheckForeground, 1000, 1000);
}
public static void main(String[] args) {
LockMainApp app = new LockMainApp();
app.enterEventDispatcher();
}
TimerTask mCheckForeground = new TimerTask() {
public void run() {
int id = ApplicationManager
.getApplicationManager().getForegroundProcessId();
if (id != mFGProcessId) {
mFGProcessId= id;
String moduleName = getModuleNameByProcessId(mFGProcessId);
if (moduleName.equalsIgnoreCase(STR_MODULE_NAME)) {
if (!checkPassword())
mFGProcessId = switchForegroundModule();
}
}
};
};
}