i try get curent coordinate and addres with NETWORK_PROVIDER in trhead, but when i change to GPS_PROVIDER, the app force close: with the message from LogCat :
02-24 16:54:00.249: E/AndroidRuntime(3004):
android.view.ViewRoot$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
I think what the difference is when I just change the provider from Network to GPS, as before when using a network, application is running well..
this is the code for thread :
private void requestPosition()
{
if(!cekInternet())
{
Txt_konek.setText("Need internet Connection");
}
else
{
new Thread()
{
public void run()
{
Message localMessage = Message.obtain();
localMessage.what=1;
try
{
Splash2.this.ll = Splash2.this.show_current_location();
Splash2.this.lat = Double.valueOf(Double.parseDouble(Splash2.this.ll.substring(0,Splash2.this.ll.indexOf(",")-1)));
Splash2.this.lng = Double.valueOf(Double.parseDouble(Splash2.this.ll.substring(1+Splash2.this.ll.indexOf(","))));
Splash2.this.posisiUser = Splash2.this.goToGeocoder(Splash2.this.lat.doubleValue(), Splash2.this.lng.doubleValue());
Splash2.this.messageHandler.sendMessage(localMessage);
return;
}
catch(Exception localException)
{
while(true)
{
Splash2.this.Txt_konek.setText("no internet connection");
}
}
}
}
.start();
}
}
this method for get current location :
private String show_current_location()
{
Location localLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(localLocation==null)
{
this.longLat = localLocation.getLatitude()+","+localLocation.getLongitude();
}
else
{
this.longLat = localLocation.getLatitude()+","+localLocation.getLongitude();
}
return this.longLat;
}
and this is locationListener :
GPS provider takes time to get a fix and you are processing your show_current_location method before that, so you are getting the error. You need to wait until you receive lat and lang
if your location localLocation is null then a null pointer exception will be thrown at
localLocation.getLatitude()
Related
I have a Xamarin.Forms application that supports UWP, iOS, and Android. Specifically, I am now testing my app on Android emulator. For getting location, I am using Xamarin.Essentials. Here are pieces of my code:
In a PageModel:
bu = await GeolocationSrvc.GetBusinessUnitAsync();
And here is the implementation of the method above:
public static async Task<BusinessUnits> GetBusinessUnitAsync()
{
BusinessUnits bu = BusinessUnits.Aus;
try
{
Location location = await GetLocation().ConfigureAwait(false);
IEnumerable<Placemark> placemarks = await Geocoding.GetPlacemarksAsync(location);
Placemark placemark = placemarks?.FirstOrDefault();
string countryCode = placemark?.CountryCode;
switch (countryCode)
{
case "AQ":
case "AU":
case "NZ":
bu = BusinessUnits.Aus;
break;
default:
bu = BusinessUnits.NA;
break;
}
}
catch (Exception)
{
throw;
}
return bu;
}
private static Task<Location> GetLocation()
{
GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
TaskCompletionSource<Location> locationTaskCompletionSource = new TaskCompletionSource<Location>();
Device.BeginInvokeOnMainThread(async () =>
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLocationAsync(request));
});
return locationTaskCompletionSource.Task;
}
When the execution comes to
locationTaskCompletionSource.SetResult(await Geolocation.GetLocationAsync(request));
I am asked if I want to allow the app to get my location. If I press Yes, it works as expected. But if I press No, the location is never returned (not even null), the following code is never executed. I expected in case of answering No to use default value set in
BusinessUnits bu = BusinessUnits.Aus;
But it does not happen.
Alternate approach would be to check for location permission before hand using a simple dependency service for each platform.
If the permission is granted, then continue with location fetch. Else prompt user to get permission.
For ex. Android implementation to check location permission:
public bool IsLocationPermissionGranted()
{
if (ContextCompat.CheckSelfPermission(Application.Context,
Manifest.Permission.AccessFineLocation) == Permission.Granted)
{
return true;
}
return false;
}
You're not setting the Exception of your TaskCompletionSource object:
private static Task<Location> GetLocation()
{
GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
TaskCompletionSource<Location> locationTaskCompletionSource = new TaskCompletionSource<Location>();
Device.BeginInvokeOnMainThread(async () =>
{
try
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLocationAsync(request));
}
catch(Exception exception)
{
locationTaskCompletionSource.SetException(exception);
locationTaskCompletionSource.SetResult(null);
}
});
return locationTaskCompletionSource.Task;
}
I want to get the GPS location of my device. I am using GeolocatorPlugin for Xamarin to get the Longitude and Latitude of my device. GPS is enabled on my device. I already added permission to my android manifest but I still get the error: "A geolocation error occured: Unauthorized" How can I fix this?
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync();
entLocation.Text = position.Longitude.ToString() + "," + position.Latitude.ToString();
}
catch (Exception ex)
{
//will catch any general exception and set message in a string
string msg = ex.Message;
await DisplayAlert("error", msg, "ok");
}
Put the code below inside your MainActivity.cs in your Android Project.
if(CheckSelfPermission(Manifest.Permission.AccessCoarseLocation) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation }, 0);
}
i am using code-name one to develop an app which has google map in it, i want when i open the app it gets my current location how could i do that, here is the code i have.
static Location lastKnownLocation;
#Override
protected void beforeMap(Form f) {
MapContainer mapContainer = new MapContainer(new GoogleMapsProvider("AIzaSyCyy_vOWn3DvR3Y8pzAWUmKTzBaDa81Tfc"));
lastKnownLocation = LocationManager.getLocationManager().getLastKnownLocation();
Style s = new Style();
s.setBgTransparency(0);
s.setFgColor(0);
mapContainer.addMarker(FontImage.createMaterial(FontImage.MATERIAL_MY_LOCATION, s).toEncodedImage(), new Coord(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()), "", "", evt -> {
ToastBar.showErrorMessage(lastKnownLocation.toString());
});
mapContainer.addTapListener(evt -> {
Coord coord = mapContainer.getCoordAtPosition(evt.getX(), evt.getY());
mapContainer.addMarker(FontImage.createMaterial(FontImage.MATERIAL_LOCATION_ON, s).toEncodedImage(), coord, "", "", null);
});
f.add(BorderLayout.CENTER, mapContainer);
FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD);
fab.addActionListener(e -> {
ParseObject object = ParseObject.create("Geo");
object.put("current", new ParseGeoPoint(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()));
if (ParseUser.getCurrent() != null)
object.put("user", ParseUser.getCurrent());
try {
object.save();
ToastBar.showErrorMessage("Geo Sent");
} catch (ParseException ex) {
ex.printStackTrace();
ToastBar.showErrorMessage(ex.getMessage());
}
});
fab.bindFabToContainer(f.getContentPane());
}
}
Notice that on the device your current location will be used and highlighted since the device runs the native maps whereas the simulator runs a simulation.
Having said that you can get your location from the LocationManager class.
E.g.:
Location position = LocationManager.getLocationManager().getCurrentLocationSync();
I create app on Xamarin.Android. There is a socket, with it's help I'm getting some data for my app. I'm checking the internet connection like this:
_timer = new Timer(CheckNetworkAvailable, new AutoResetEvent(false), 0, 10000);
It calls in OnCreate method.
cts = new CancellationTokenSource();
var isNetwork = await Task.Run(() => this.NetworkRechableOrNot(), cts.Token);
var linear = SupportActionBar.CustomView.FindViewById<LinearLayout>(Resource.Id.linearForActionBanner);
var identOn = linear.FindViewById<ImageView>(Resource.Id.identificator_on);
var identOff = linear.FindViewById<ImageView>(Resource.Id.identificator_off);
RunOnUiThread(() =>
{
identOn.Visibility = !isNetwork ? ViewStates.Gone : ViewStates.Visible;
identOff.Visibility = !isNetwork ? ViewStates.Visible : ViewStates.Gone;
});
if (isNetwork)
{
if (isNetwork != oldNet)
{
oldNet = isNetwork;
MainDataClass.UpdateSymbolsList();
SocketClass.Start();
}
}
else
{
oldNet = isNetwork;
cts.Cancel();
SocketClass.Stop();
}
Here oldNet - previos status of internet access.
private bool NetworkRechableOrNot()
{
try
{
var connectivityManager = (_Net.ConnectivityManager)GetSystemService(Context.ConnectivityService);
var activeConnection = connectivityManager.ActiveNetworkInfo;
return (activeConnection != null) && activeConnection.IsConnected;
}
catch (Exception)
{
return false;
}
}
And this is the result method for checking.
SocketClass - class for socket and getting data; Start method creating new Task and Start it, socket created via SocketIOClient.Socket; Stop method calls Close method of Socket. And it all works fine until I try to disable internet connection, I got only once NameResolutionFailure. What can be the reason of it? And what should I change for meking it works fine? Thanks.
I think the main reason is your internet is off. You need a internet to try resolve some address.
I solved it, there was not correct realization of socket, it come in loop because when socket gets error it calls itself and doesn't finish that's why it crashes.
I use phonegap 1.3.0 to develop mobile application.
when i click one button that will invoke my plugin to invoke a js function, after about 20s, countered the error: "E/DroidGap(21383): DroidGap: TIMEOUT ERROR! - calling webViewClient" in eclipse log console.
and the emulator alert a dialog, show error message : The connection to the server was unsuccessful.(javascript:showProcessBar(1))
How can I fix the error? thanks!
There are some details below to complement my question.
when I invoke js function in phonegap plugin. there must will show error message in logcat:"E/DroidGap(21383): DroidGap: TIMEOUT ERROR! - calling webViewClient" .
I find the code that generate the error. just below:
private void loadUrlIntoView(final String url) {
if (!url.startsWith("javascript:")) {
LOG.d(TAG, "DroidGap.loadUrl(%s)", url);
}
this.url = url;
if (this.baseUrl == null) {
int i = url.lastIndexOf('/');
if (i > 0) {
this.baseUrl = url.substring(0, i+1);
}
else {
this.baseUrl = this.url + "/";
}
}
if (!url.startsWith("javascript:")) {
LOG.d(TAG, "DroidGap: url=%s baseUrl=%s", url, baseUrl);
}
// Load URL on UI thread
final DroidGap me = this;
this.runOnUiThread(new Runnable() {
public void run() {
// Init web view if not already done
if (me.appView == null) {
me.init();
}
// Handle activity parameters
me.handleActivityParameters();
// Track URLs loaded instead of using appView history
me.urls.push(url);
me.appView.clearHistory();
// Create callback server and plugin manager
if (me.callbackServer == null) {
me.callbackServer = new CallbackServer();
me.callbackServer.init(url);
}
else {
me.callbackServer.reinit(url);
}
if (me.pluginManager == null) {
me.pluginManager = new PluginManager(me.appView, me);
}
else {
me.pluginManager.reinit();
}
// If loadingDialog property, then show the App loading dialog for first page of app
String loading = null;
if (me.urls.size() == 1) {
loading = me.getStringProperty("loadingDialog", null);
}
else {
loading = me.getStringProperty("loadingPageDialog", null);
}
if (loading != null) {
String title = "";
String message = "Loading Application...";
if (loading.length() > 0) {
int comma = loading.indexOf(',');
if (comma > 0) {
title = loading.substring(0, comma);
message = loading.substring(comma+1);
}
else {
title = "";
message = loading;
}
}
me.spinnerStart(title, message);
}
// Create a timeout timer for loadUrl
final int currentLoadUrlTimeout = me.loadUrlTimeout;
Runnable runnable = new Runnable() {
public void run() {
try {
synchronized(this) {
wait(me.loadUrlTimeoutValue);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// If timeout, then stop loading and handle error
if (me.loadUrlTimeout == currentLoadUrlTimeout) {
me.appView.stopLoading();
LOG.e(TAG, "DroidGap: TIMEOUT ERROR! - calling webViewClient");
//me.webViewClient.onReceivedError(me.appView, -6, "The connection to the server was unsuccessful.", url);
}
}
};
Thread thread = new Thread(runnable);
thread.start();
me.appView.loadUrl(url);
}
});
}
I comment the line : me.webViewClient.onReceivedError(me.appView, -6, "The connection to the server was unsuccessful.", url); because it will alert a dialog to terminate my program.
Android enforces a timeout when loading URLs in a webview.
check out this link, (it doesn't really pertain to JQM) , but phonegap android
http://jquerymobile.com/test/docs/pages/phonegap.html
The problem explains itself.. when there's a time out response in any PhoneGap call to an external URL it throws that error.
You can you this HTML5 feature to check the internet connection:
navigator.onLine;
You can see it working here: http://html5demos.com/nav-online
super.setIntegerProperty("loadUrlTimeoutValue",60000);
Place this line in java code in Activity