Can someone point me into the right direction what I am doing wrong in this Api call? I am getting an odd error that I don’t know what it means. The api call should work as I tested it using VBA and I get a response with the payload. Also any feedback is welcomed.
Id = 190, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}" - this is the response I am getting back from it
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Xml.Linq;
namespace BarcodeScanner.Classes
{
public class Api : IDisposable
{
private readonly TimeSpan _timeout;
private HttpClient _httpClient;
private HttpClientHandler _httpClientHandler;
private readonly string _baseUrl;
private readonly string _credentials;
private const string MediaTypeXml = "application/xml";
public Api(string baseUrl, string authToken, TimeSpan? timeout = null)
{
_baseUrl = NormaliseBaseUrl(baseUrl);
_credentials = Base64Encode(authToken);
_timeout = timeout ?? TimeSpan.FromSeconds(90);
}
public async Task<string> GetAsync(string url)
{
EnsureHttpClientCreated();
using (var response = await _httpClient.GetAsync(url).ConfigureAwait(continueOnCapturedContext: false))
{
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
public void Dispose()
{
_httpClientHandler?.Dispose();
_httpClient?.Dispose();
}
private void CreateHttpClient()
{
_httpClientHandler = new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
_httpClient = new HttpClient(_httpClientHandler, false)
{
Timeout = _timeout
};
if (!string.IsNullOrWhiteSpace(_baseUrl))
{
_httpClient.BaseAddress = new Uri(_baseUrl);
}
_httpClient.DefaultRequestHeaders.Add("Authorization", "Basic " + _credentials);
}
private void EnsureHttpClientCreated()
{
if (_httpClient == null)
{
CreateHttpClient();
}
}
//call the api
try
{
using (var client = new Api(requestUrl, authToken))
{
var response = client.GetAsync(requestUrl);
}
}
catch (Exception err)
{
throw new Exception("Something went wrong: ", err);
}
this must be a stupid question but please help me. How can we get the image file path in camera2basic api and display the image on the other activity's imageview? I have been trying to get the "Absolutepath" of the mFile in the project but not getting anything.
As Camera2 api is relatively complex to understand for me. Please help me.
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
mFile = new Java.IO.File(Activity.GetExternalFilesDir(null), "pic.jpg");
mCaptureCallback = new CameraCaptureListener(this);
mOnImageAvailableListener = new ImageAvailableListener(this, mFile);
}
when we press the button, it evokes takepicture(); which has lockfocus();
private void LockFocus()
{
try
{
// This is how to tell the camera to lock focus.
mPreviewRequestBuilder.Set(CaptureRequest.ControlAfTrigger, (int)ControlAFTrigger.Start);
// Tell #mCaptureCallback to wait for the lock.
mState = STATE_WAITING_LOCK;
mCaptureSession.Capture(mPreviewRequestBuilder.Build(), mCaptureCallback,
mBackgroundHandler);
}
catch (CameraAccessException e)
{
e.PrintStackTrace();
}
}
I have showCapturePhoto which is getting the image from ImageAvailableListener
using Android.Media;
using Java.IO;
using Java.Lang;
using Java.Nio;
using Android.Util;
namespace Camera2Basic.Listeners
{
public class ImageAvailableListener : Java.Lang.Object,
ImageReader.IOnImageAvailableListener
{
private readonly File file;
private Camera2BasicFragment owner;
public ImageAvailableListener(Camera2BasicFragment fragment, File
file)
{
if (fragment == null)
throw new System.ArgumentNullException("fragment");
if (file == null)
throw new System.ArgumentNullException("file");
owner = fragment;
this.file = file;
}
//public File File { get; private set; }
//public Camera2BasicFragment Owner { get; private set; }
public void OnImageAvailable(ImageReader reader)
{
owner.mBackgroundHandler.Post(new ImageSaver(reader.AcquireNextImage(), file));
}
// Saves a JPEG {#link Image} into the specified {#link File}.
private class ImageSaver : Java.Lang.Object, IRunnable
{
// The JPEG image
private Image mImage;
// The file we save the image into.
private File mFile;
public ImageSaver(Image image, File file)
{
if (image == null)
throw new System.ArgumentNullException("image");
if (file == null)
throw new System.ArgumentNullException("file");
mImage = image;
mFile = file;
}
public void Run()
{
ByteBuffer buffer = mImage.GetPlanes()[0].Buffer;
byte[] bytes = new byte[buffer.Remaining()];
buffer.Get(bytes);
using (var output = new FileOutputStream(mFile))
{
try
{
output.Write(bytes);
}
catch (IOException e)
{
e.PrintStackTrace();
}
finally
{
mImage.Close();
}
}
Camera2BasicFragment.showCapturedPhoto(mImage);
}
}
}
}
ShowcapturePhoto
public static void showCapturedPhoto(Image img)
{
ByteBuffer buffer;
byte[] bytes;
MemoryStream memStream = new MemoryStream();
buffer = img.GetPlanes()[0].Buffer;
bytes = new byte[buffer.Capacity()];
buffer.Get(bytes);
Activity activity= new Activity();
Intent showPhoto = new Intent(activity, typeof(RetryOK));
showPhoto.PutExtra("savedImg", bytes);
showPhoto.PutExtra("zoomAmount", 1.7f / 1.4f);
showPhoto.PutExtra("focusDistance", -1.0f);
activity.StartActivity(typeof(RetryOK));
}
I am trying to implement a custom activity that initialises the Fused Location services in Xamarin c# so I can reuse this activity whenever the Fused Location is needed. The problem that I am having is that the map is being loaded before the location services. This way, I cannot animate the camera to zoom in at the user's location since the location is still null.
Here is the custom activity:
using System;
using Android.App;
using Android.Gms.Common;
using Android.Gms.Common.Apis;
using Android.Gms.Maps.Model;
using Android.Locations;
using Android.OS;
using Android.Gms.Location;
using Android.Widget;
namespace Maps.Droid.LocationService {
public class LocationTrackerActivity : Activity, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener {
// Static Fields
public static long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 5 meters
public static long MIN_TIME_BW_UPDATES = 1000 * 10; // 10 seconds
private Location currentLocation;
private Activity activity;
private bool hasGooglePlayServices;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private bool locationAvailable = false;
protected override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
this.activity = this;
hasGooglePlayServices = checkPlayServices();
if (hasGooglePlayServices) {
initFusedLocation();
} else {
initAndroidLocation();
}
}
private void initFusedLocation() {
mLocationRequest = new LocationRequest();
mLocationRequest.SetInterval(LocationTrackerActivity.MIN_TIME_BW_UPDATES);
mLocationRequest.SetFastestInterval(LocationTrackerActivity.MIN_TIME_BW_UPDATES / 2);
mLocationRequest.SetSmallestDisplacement(LocationTrackerActivity.MIN_DISTANCE_CHANGE_FOR_UPDATES);
mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
mGoogleApiClient = new GoogleApiClient.Builder(Application.Context)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(LocationServices.API)
.Build();
}
protected override void OnResume() {
base.OnResume();
if (mGoogleApiClient.IsConnected) {
LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
protected override void OnPause() {
base.OnPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.IsConnected) {
LocationServices.FusedLocationApi.RemoveLocationUpdates(mGoogleApiClient, this);
}
}
protected override void OnStart() {
base.OnStart();
mGoogleApiClient.Connect();
}
protected override void OnStop() {
base.OnStop();
// only stop if it's connected, otherwise we crash
if (mGoogleApiClient != null) {
mGoogleApiClient.Disconnect();
}
}
private void initAndroidLocation() {
}
private bool checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.Instance;
int resultCode = apiAvailability.IsGooglePlayServicesAvailable(activity);
if (resultCode != ConnectionResult.Success) {
// In case we want to tell the user to install or update Google Play Services
//if (apiAvailability.IsUserResolvableError(resultCode)) {
// apiAvailability.GetErrorDialog(activity, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).Show();
//} else {
// Toast.MakeText(activity, "This device is not supported", ToastLength.Long).Show();
//}
return false;
}
return true; // has google play services installed
}
public double getLatitude() {
return currentLocation == null ? 0.0 : currentLocation.Latitude;
}
public double getLongitude() {
return currentLocation == null ? 0.0 : currentLocation.Longitude;
}
public bool canGetLocation() {
return locationAvailable;
}
public LatLng getLatLng() {
return new LatLng(currentLocation.Latitude, currentLocation.Longitude);
}
public void OnConnected(Bundle connectionHint) {
// Get last known recent location. If the user launches the activity,
// moves to a new location, and then changes the device orientation, the original location
// is displayed as the activity is re-created.
if (currentLocation == null && mGoogleApiClient.IsConnected) {
currentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient);
}
Console.WriteLine("location is about to be set to true");
locationAvailable = true;
LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
public void OnConnectionSuspended(int cause) {
// GoogleApiClient will automatically attempt to restore the connection.
// Applications should disable UI components that require the service, and wait for a call to onConnected(Bundle) to re-enable them
if (cause == GoogleApiClient.ConnectionCallbacks.CauseServiceDisconnected) {
Toast.MakeText(activity, "Location Services disconnected. Please re-connect.", ToastLength.Long).Show();
} else if (cause == GoogleApiClient.ConnectionCallbacks.CauseNetworkLost) {
Toast.MakeText(activity, "Network lost. Please re-connect.", ToastLength.Long).Show();
}
}
public void OnConnectionFailed(ConnectionResult result) {
Console.WriteLine("Connection failed: " + result.ToString());
}
public void OnLocationChanged(Location location) {
currentLocation = location;
}
}
}
Here is the class that inherit the custom class:
using Android.App;
using Android.OS;
using Maps.Droid.LocationService;
namespace Maps.Droid {
[Activity(Label = "Map Activity")]
public class MapActivity : LocationTrackerActivity {
// Properties
protected override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.map_activity);
var mapFrag = new MapViewFragment();
var ft = FragmentManager.BeginTransaction();
ft.Add(Resource.Id.map_container, mapFrag);
ft.Commit();
}
}
}
Here is the fragment in the inherited activity:
using System;
using Android.App;
using Android.OS;
using Android.Views;
using Android.Gms.Maps;
namespace Maps.Droid {
public class MapViewFragment : Fragment, IOnMapReadyCallback {
// private Activity activity;
private GoogleMap map;
private MapActivity parent;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.Inflate(Resource.Layout.map_fragment, null);
parent = ((MapActivity)Activity);
MapFragment frag = this.FragmentManager.FindFragmentById<MapFragment>(Resource.Id.map);
frag.GetMapAsync(this);
return view;
}
public void OnMapReady(GoogleMap googleMap) {
if (googleMap != null) {
map = googleMap;
var zoomVariance = 0.2;
var defaultZoom = 16f;
var currentZoomLevel = map.CameraPosition.Zoom;
map.MapType = GoogleMap.MapTypeNormal;
map.MyLocationEnabled = true;
map.CameraChange += delegate (object sender, GoogleMap.CameraChangeEventArgs e) {
if (Math.Abs(e.Position.Zoom - currentZoomLevel) < zoomVariance) {
return;
}
currentZoomLevel = e.Position.Zoom;
Console.WriteLine("Zooming " + currentZoomLevel);
};
map.UiSettings.ZoomControlsEnabled = true;
map.UiSettings.CompassEnabled = true;
map.UiSettings.SetAllGesturesEnabled(true); // Zoom, Tilt, Scroll, Rotate
if (parent.canGetLocation()) {
// ***** PROBLEM HERE ******* canGetLocation is set to true just afterwards.
map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(parent.getLatLng(), defaultZoom)); // Mosaic coordinates
}
}
}
}
}
I was thinking of implementing a call back to LocationTrackerActivity. So when the location services become available the class MapActivity then would be able to load the MapViewFragment within that custom callback. This way the location services would be loaded before the map. Therefore, this part of the code would always execute :
if (parent.canGetLocation()) {
// ***** PROBLEM HERE ******* canGetLocation is set to true just afterwards.
map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(parent.getLatLng(), defaultZoom)); // Mosaic coordinates
}
However I have no idea how to customise a callback. Maybe there are better solutions to this problem?
The problem can be because of OnConnected method. That's my OnConnected method for FusedLocationProvider in Xamarin. You can take a look on it.
public async void OnConnected(Bundle bundle)
{
Location location = LocationServices.FusedLocationApi.GetLastLocation(apiClient);
if (location != null)
{
latitude = location.Latitude;
longitude = location.Longitude;
locRequest.SetPriority(100);
locRequest.SetFastestInterval(500);
locRequest.SetInterval(1000);
await LocationServices.FusedLocationApi.RequestLocationUpdates(apiClient, locRequest, this);
}
}
When it is connected, i set the latitude and longitude values. Then in my onMapReady method, i create a new LatLng variable with these latitude and longitude variables.
void IOnMapReadyCallback.OnMapReady(GoogleMap myMap)
{
this.myMap = myMap;
myMarker = new MarkerOptions();
locCoordinates = new LatLng(latitude, longitude);
myMap.MapType = GoogleMap.MapTypeNormal;
myMap.UiSettings.ZoomControlsEnabled = true;
myMap.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(locCoordinates, 10));
}
UPDATE:
I have managed to find a solution. If the user has google play services then use FusedLocation Services, if the user does not then we use Android Location Services. Then we only have to interact with one object of the type LocationTracker and everything is done by this interface:
namespace Maps.Droid.LocationService {
public interface LocationInterface {
void startLocationServices();
void stopLocationServices();
void pauseLocationServices();
void resumeLocationServices();
double getLatitude();
double getLongitude();
bool canGetLocation();
}
}
using System;
using Android.App;
using Android.Gms.Location;
using Android.Gms.Common.Apis;
using Android.OS;
using Android.Gms.Maps.Model;
using Android.Widget;
using Android.Locations;
using Android.Gms.Common;
using Android.Gms.Maps;
namespace Maps.Droid.LocationService {
public class FusedLocation : Java.Lang.Object, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener {
private Activity activity;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Location currentLocation;
private bool locationAvailable = false;
private GoogleMap map;
public FusedLocation(Activity activity) {
this.activity = activity;
mLocationRequest = new LocationRequest();
mLocationRequest.SetInterval(LocationTracker.MIN_TIME_BW_UPDATES);
mLocationRequest.SetFastestInterval(LocationTracker.MIN_TIME_BW_UPDATES / 2);
mLocationRequest.SetSmallestDisplacement(LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES);
mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
mGoogleApiClient = new GoogleApiClient.Builder(Application.Context)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(LocationServices.API)
.Build();
}
public Location getCurrentLocation() {
return currentLocation;
}
public void setMap(GoogleMap map) {
this.map = map;
}
public double getLatitude() {
return currentLocation.Latitude;
}
public double getLongitude() {
return currentLocation.Longitude;
}
public void OnResume() {
if (mGoogleApiClient.IsConnected) {
LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
public void OnPause() {
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.IsConnected) {
LocationServices.FusedLocationApi.RemoveLocationUpdates(mGoogleApiClient, this);
}
}
public void OnStart() {
mGoogleApiClient?.Connect();
}
public void OnStop() {
// only stop if it's connected, otherwise we crash
if (mGoogleApiClient.IsConnected) {
mGoogleApiClient?.Disconnect();
}
}
public LatLng getLatLng() {
return new LatLng(currentLocation.Latitude, currentLocation.Longitude);
}
public bool canGetLocation() {
return locationAvailable && currentLocation != null;
}
public void OnConnected(Bundle connectionHint) {
// Get last known recent location. If the user launches the activity,
// moves to a new location, and then changes the device orientation, the original location
// is displayed as the activity is re-created.
currentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient);
if (currentLocation != null) {
locationAvailable = true;
LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
if (map != null) {
map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(getLatLng(), LocationTracker.DEFAULT_ZOOM));
}
}
}
public void OnConnectionSuspended(int cause) {
// GoogleApiClient will automatically attempt to restore the connection.
// Applications should disable UI components that require the service, and wait for a call to onConnected(Bundle) to re-enable them
if (cause == GoogleApiClient.ConnectionCallbacks.CauseServiceDisconnected) {
Toast.MakeText(activity, "Location Services disconnected. Please re-connect.", ToastLength.Long).Show();
} else if (cause == GoogleApiClient.ConnectionCallbacks.CauseNetworkLost) {
Toast.MakeText(activity, "Network lost. Please re-connect.", ToastLength.Long).Show();
}
}
public void OnLocationChanged(Location location) {
currentLocation = location;
}
public void OnConnectionFailed(ConnectionResult result) {
Console.WriteLine("Connection failed: " + result.ToString());
}
}
}
using System;
using Android.OS;
using Android.Locations;
using Android.Runtime;
using Android.App;
using Android.Content;
using Android.Widget;
using Android.Gms.Maps.Model;
using Java.Util.Concurrent;
namespace Maps.Droid.LocationService {
public class AndroidLocation : Java.Lang.Object, ILocationListener {
// Properties
private LocationManager locMgr;
private Activity activity;
private Location locationGPS, locationNetwork/*, locationPassive*/, currentLocation;
private bool locationAvailable = false;
private Android.Gms.Maps.GoogleMap map;
// UNCOMMNET
// private bool isPassiveEnabled = false; // Gets location from other apps that uses Location Services
// Initializer method (Constructor). Call this method onCreate
public AndroidLocation(Activity activity) {
this.activity = activity;
getLocation();
}
public Location getCurrentLocation() {
return currentLocation;
}
public void setMap(Android.Gms.Maps.GoogleMap map) {
this.map = map;
}
private Location getLocation() {
// Use Standard Android Location Service Provider
try {
locMgr = activity.GetSystemService(Context.LocationService) as LocationManager;
bool isGPSEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider);
// Varying precision, Less power consuming. Combination of WiFi and Cellular data
bool isNetworkEnabled = locMgr.IsProviderEnabled(LocationManager.NetworkProvider);
// UNCOMMENT
// bool isPassiveEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider);
// UNCOMMNET
//if (isPassiveEnabled) {
// locMgr.RequestLocationUpdates(LocationManager.PassiveProvider, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
// locationPassive = locMgr.GetLastKnownLocation(LocationManager.PassiveProvider);
//}
if (isGPSEnabled) {
locMgr.RequestLocationUpdates(LocationManager.GpsProvider, LocationTracker.MIN_TIME_BW_UPDATES, LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
locationGPS = locMgr?.GetLastKnownLocation(LocationManager.GpsProvider);
}
if (isNetworkEnabled) {
locMgr.RequestLocationUpdates(LocationManager.NetworkProvider, LocationTracker.MIN_TIME_BW_UPDATES, LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
locationNetwork = locMgr?.GetLastKnownLocation(LocationManager.NetworkProvider);
}
// UNCOMMENT - Method must be implement if PassiveLocation is to be used
// currentLocation = getBestLocation(locationGPS, locationNetwork, locationPassive);
currentLocation = getBestLocation(locationNetwork, locationGPS);
if (currentLocation != null) {
locationAvailable = true;
if (map != null) {
map.AnimateCamera(Android.Gms.Maps.CameraUpdateFactory.NewLatLngZoom(getLatLng(), LocationTracker.DEFAULT_ZOOM));
}
}
} catch (Exception e) {
Console.WriteLine("ERROR: getLocation() " + e.ToString());
}
return currentLocation;
}
// Determines the most recent and/or most accurate location
private Location getBestLocation(Location loc1, Location loc2) {
if (loc1 == null || loc2 == null) {
return loc1 ?? loc2; // If either location is null then return the not null location
}
long time1 = TimeUnit.Milliseconds.ToSeconds(loc1.Time);
long time2 = TimeUnit.Milliseconds.ToSeconds(loc2.Time);
long twiceUpdate = (LocationTracker.MIN_TIME_BW_UPDATES / 1000) * 2;
if (Math.Abs(time1 - time2) > twiceUpdate) { // If location times are more than twiceUpdate apart
if (time1 > time2) { // More time value, most current time
return loc1;
} else {
return loc2;
}
} else {
float accuracy1 = loc1.Accuracy;
float accuracy2 = loc2.Accuracy;
// Smaller the value (meters), the greater the accuracy
if (accuracy1 < accuracy2) {
return loc1;
} else {
return loc2;
}
}
}
public void OnStop() {
locMgr = null;
}
public void OnPause() {
locMgr?.RemoveUpdates(this);
}
public void OnStart() {
}
public void OnResume() {
if (locMgr == null || currentLocation == null) {
getLocation();
}
}
public bool canGetLocation() {
return locationAvailable;
}
public LatLng getLatLng() {
return new LatLng(currentLocation.Latitude, currentLocation.Longitude);
}
public double getLatitude() {
return currentLocation.Latitude;
}
public double getLongitude() {
return currentLocation.Longitude;
}
public void OnLocationChanged(Location location) {
currentLocation = getBestLocation(currentLocation, location);
}
// User disabled a provider
public void OnProviderDisabled(string provider) {
getLocation(); // Check if all providers are disabled and pop up alertDialog if they are so
}
// User enabled a provider
public void OnProviderEnabled(string provider) {
getLocation(); // Update all available providers for getting the best provider available
}
public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras) {
}
}
}
using Android.App;
using Android.Gms.Common;
using Android.Gms.Common.Apis;
using Android.Gms.Maps.Model;
using Android.Gms.Maps;
using Android.Locations;
using Android.Content;
using Android.Widget;
namespace Maps.Droid.LocationService {
public class LocationTracker {
public static long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 5 meters
public static long MIN_TIME_BW_UPDATES = 1000 * 15; // 15 seconds ok, 5 seconds really fast, 30s slow
public static float DEFAULT_ZOOM = 16f;
private bool hasGooglePlayServices;
public GoogleApiClient mGoogleApiClient;
private FusedLocation fusedLocation;
private AndroidLocation androidLocation;
private bool locationIsDisabled;
public LocationTracker(Activity activity) {
if (locationIsDisabled = isLocationDisabled(activity)) {
showSettingsAlert(activity);
} else {
hasGooglePlayServices = checkPlayServices(activity);
if (hasGooglePlayServices) {
fusedLocation = new FusedLocation(activity);
} else {
androidLocation = new AndroidLocation(activity);
}
}
}
private void showSettingsAlert(Activity activity) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.SetTitle("Location Services Not Active");
builder.SetMessage("Please enable Location Services and GPS");
builder.SetPositiveButton("OK", delegate {
// Show location settings when the user acknowledges the alert dialog
var intent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings);
activity.StartActivity(intent);
});
builder.SetNegativeButton("Cancel", delegate {
Toast.MakeText(activity, "Location disabled by user", ToastLength.Short).Show();
});
AlertDialog alertDialog = builder.Create();
alertDialog.SetCanceledOnTouchOutside(false);
alertDialog.Show();
}
private bool isLocationDisabled(Activity activity) {
LocationManager locMgr = activity.GetSystemService(Context.LocationService) as LocationManager;
// More precise, More power consuming
bool isGPSEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider);
// Varying precision, Less power consuming. Combination of WiFi and Cellular data
bool isNetworkEnabled = locMgr.IsProviderEnabled(LocationManager.NetworkProvider);
// UNCOMMENT
// bool isPassiveEnabled = locMgr.IsProviderEnabled(LocationManager.PassiveProvider);
// UNCOMMENT
// return !isGPSEnabled && !isNetworkEnabled && !isPassiveEnabled; // True only when the 3 location services are disabled
return !isGPSEnabled && !isNetworkEnabled; // True only when both location services are disabled
}
// Call this method at OnMapReady callback if initial zooming/animation on user's location is desired
public void setMap(GoogleMap map) {
if (locationIsDisabled) {
return;
}
if (hasGooglePlayServices) {
fusedLocation.setMap(map);
} else {
androidLocation.setMap(map);
}
}
public void OnResume() {
if (locationIsDisabled) {
return;
}
if (hasGooglePlayServices) {
fusedLocation.OnResume();
} else {
androidLocation.OnResume();
}
}
public void OnPause() {
if (locationIsDisabled) {
return;
}
if (hasGooglePlayServices) {
fusedLocation.OnPause();
} else {
androidLocation.OnPause();
}
}
public void OnStart() {
if (locationIsDisabled) {
return;
}
if (hasGooglePlayServices) {
fusedLocation.OnStart();
} else {
androidLocation.OnStart();
}
}
public void OnStop() {
if (locationIsDisabled) {
return;
}
if (hasGooglePlayServices) {
fusedLocation.OnStop();
} else {
androidLocation.OnStop();
}
}
private bool checkPlayServices(Activity activity) {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.Instance;
int resultCode = apiAvailability.IsGooglePlayServicesAvailable(activity);
if (resultCode == ConnectionResult.Success) {
return true;
}
return false;
}
public double getLatitude() {
if (locationIsDisabled) {
return 0;
}
if (hasGooglePlayServices) {
return fusedLocation.getCurrentLocation() == null ? 0.0 : fusedLocation.getLatitude();
} else {
return androidLocation.getCurrentLocation() == null ? 0.0 : androidLocation.getLatitude();
}
}
public double getLongitude() {
if (locationIsDisabled) {
return 0;
}
if (hasGooglePlayServices) {
return fusedLocation.getCurrentLocation() == null ? 0.0 : fusedLocation.getLongitude();
} else {
return androidLocation.getCurrentLocation() == null ? 0.0 : androidLocation.getLongitude();
}
}
public bool canGetLocation() {
if (locationIsDisabled) {
return false;
}
if (hasGooglePlayServices) {
return fusedLocation.canGetLocation();
} else {
return androidLocation.canGetLocation();
}
}
public LatLng getLatLng() {
if (locationIsDisabled) {
return null;
}
LatLng latlng;
if (hasGooglePlayServices) {
latlng = fusedLocation.getLatLng();
} else {
latlng = androidLocation.getLatLng();
}
return latlng;
}
public Location getCurrentLocation() {
if (hasGooglePlayServices) {
return fusedLocation.getCurrentLocation();
} else {
return androidLocation.getCurrentLocation();
}
}
}
}
Then to use it on your fragment or activity:
Initialise it at OnCreate:
Location tracker = new LocationTracker(this.Activity);
make a referent for the life cycles:
public override void OnResume() {
base.OnResume();
tracker.OnResume();
}
public override void OnPause() {
base.OnPause();
tracker.OnPause();
}
public override void OnStart() {
base.OnStart();
tracker.OnStart();
}
public override void OnStop() {
base.OnStop();
tracker.OnStop();
}
if you want the animation to zoom at the users location in the beginning, then you have to add this line of code when you have the googlemap:
tracker.setMap(googleMap); // Invoke this method if zooming/animating to the user's location is desired
Spent many days on this solution. Hope it can help somebody!
Repository
namespace AgenziaMatrimoniale.DataAccess {
public class AgenziaMatrimonialeRepository
{
private readonly string _connectionString = ConfigurationManager.ConnectionStrings["AgenziaMatrimonialeConnectionString"].ConnectionString;
public List<Candidato> FindSimple(int? id, string sesso, string citta)
{
List<Candidato> result = new List<Candidato>();
string query = "SELECT * FROM Candidato";
using (var connection = new SqlConnection(_connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
var dbId = Convert.ToInt32(reader["Id"]);
var dbNome = Convert.ToString(reader["Nome"]);
var dbCognome = Convert.ToString(reader["Cognome"]);
var dbSesso = Convert.ToString(reader["Sesso"]);
var dbCitta = Convert.ToString(reader["Citta"]);
var dbProfessione = Convert.ToString(reader["Professione"]);
var dbDescrizione = Convert.ToString(reader["Descrizione"]);
if (id.HasValue && dbId == id)
{
AggiungiCandidatoAiRisultati(result, dbId, dbNome, dbCognome, dbSesso, dbCitta, dbProfessione, dbDescrizione);
}
else if (!id.HasValue
&& (string.IsNullOrEmpty(sesso) || dbSesso==sesso)
&& (string.IsNullOrEmpty(citta)|| dbCitta.ToLower().Contains(citta.ToLower())))
{
AggiungiCandidatoAiRisultati(result, dbId, dbNome, dbCognome, dbSesso, dbCitta, dbProfessione, dbDescrizione);
}
}
reader.Close();
}
catch (Exception ex)
{
Debug.WriteLine(string.Format("Errore applicativo: {0}", ex.Message));
throw ex;
}
}
return result;
}
public Candidato FindCandidato(int id)
{
List<Candidato> candidati = FindSimple(id, null, null);
if (candidati.Count == 1)
{
return candidati[0];
}
return null;
}
Controller
namespace AgenziaMatrimoniale.Controllers
{
public class CandidatoController : Controller
{
private readonly AgenziaMatrimonialeRepository _repository;
public CandidatoController()
{
_repository = new AgenziaMatrimonialeRepository();
}
public ActionResult Index(string sesso, string citta)
{
List<Candidato> candidati = _repository.FindSimple(null, sesso, citta);
List<SelectListItem> sessi= new List<SelectListItem> {
new SelectListItem { Text = "Maschio", Value = "M" },
new SelectListItem { Text = "Femmina", Value = "F" }
};
ViewBag.sesso = sessi;
return View(candidati);
}
public ActionResult Details(int id)
{
Candidato candidato = _repository.FindCandidato(id);
return View(candidato);
}
}
}
It depends...if you're trying to fill a table with data collected from a DB and possibly filter that data....then you are doing just fine.
You remind me this little piece of code that's just VERY similar.
using Prova1.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Web;
namespace Prova1.DataAccess
{
public class ProvaRepository
{
private readonly string _connectionString = ConfigurationManager.ConnectionStrings["StringConnectionName"].ConnectionString;
public List<Modello> Find(int? id, string filtro1, string filtro2)
{
List<Modello> result = new List<Modello>();
string query = "SELECT * FROM Tabella";
using (var connection = new SqlConnection(_connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
var dbId = Convert.ToInt32(reader["Id"]);
var dbCampo1 = Convert.ToString(reader["Campo1"]);
var dbCampo2 = Convert.ToString(reader["Campo2"]);
var dbCampo3 = Convert.ToString(reader["Campo3"]);
Modello modello = new Modello();
if (id.HasValue && dbId == id)
{
AddModello(result, dbId, dbCampo1, dbCampo2, dbCampo3, modello);
}
else if (!id.HasValue
&& (string.IsNullOrEmpty(filtro1) || dbCampo1.ToLower().Contains(filtro1.ToLower()))
&& (string.IsNullOrEmpty(filtro2) || dbCampo2.ToLower().Contains(filtro2.ToLower()))
)
{
AddModello(result, dbId, dbCampo1, dbCampo2, dbCampo3, modello);
}
}
reader.Close();
}
catch (Exception ex)
{
Debug.WriteLine(string.Format("Errore Applicativo {0}: ", ex.Message));
throw ex;
}
}
return result;
}
private static void AddModello(List<Modello> result, int dbId, string dbCampo1, string dbCampo2, string dbCampo3, Modello modello)
{
modello.Id = dbId;
modello.Campo1 = dbCampo1;
modello.Campo2 = dbCampo2;
modello.Campo3 = dbCampo3;
result.Add(modello);
}
public Modello FindDetail(int id)
{
List<Modello> modello = Find(id, null, null);
if (modello.Count == 1)
{
return modello[0];
}
return null;
}
}
}
Edit: I forgot the Controller
using Prova1.DataAccess;
using Prova1.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Prova1.Controllers
{
public class ProvaController : Controller
{
private readonly ProvaRepository _repository;
public ProvaController()
{
_repository = new ProvaRepository();
}
// GET: Prova
public ActionResult Index(string filtro1, string filtro2)
{
List<Modello> modelli = _repository.Find(null, filtro1, filtro2);
return View(modelli);
}
public ActionResult Detail(int id)
{
Modello modello = _repository.FindDetail(id);
return View(modello);
}
}
}
I am creating an imageresult.. but the "public override void ExecuteResult (ControllerContext Context)" says: no suitable method found to overide.
my class looks like this..
public override void ExecuteResult(ControllerContext Context)
{
byte[] bytes;
string contentType = GetContentTypeFromFile();
//if there's no context, stop the processing
if (Context == null)
{
throw new ArgumentNullException("context");
}
//check for file
if(File.Exists(_path)){
bytes = File.ReadAllBytes(_path);
}
else{
throw new FileNotFoundException(_path);
}
//
HttpResponseBase response = Context.HttpContext.Response;
response.ContentType = contentType;
MemoryStream imageStream = new MemoryStream(bytes);
byte[] buffer = new byte[4096];
while (true)
{
int read = imageStream.Read(buffer, 0, buffer.Length);
if (read == 0)
break;
response.OutputStream.Write(buffer, 0, read);
}
response.End();
}
Does your class subclass ActionResult? Try the following:
using System.Web.Mvc;
public class ImageResult : ActionResult
{
public override void ExecuteResult(ControllerContext Context)
{
...
}
}