Unable to display and detect bluetooth devices - c#

using Android.App;
using Android.Widget;
using Android.OS;
using Android.Bluetooth;
using Android.Content;
using Android.Views;
namespace BluetoothBLE
{
[Activity(Label = "BluetoothBLE", MainLauncher = true)]
public class MainActivity : Activity
{
//Local Bluetooth adapter
private BluetoothAdapter bluetoothAdapter = null;
//Return Intent extra
public const string Extra_Device_Address = "device_address";
//Members Field
private static ArrayAdapter<string> Device;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
//Get our UI controls from the loaded layout
TextView Text = FindViewById<TextView>(Resource.Id.BluetoothDevices);
TextView Device_Name = FindViewById<TextView>(Resource.Id.DeviceName);
Button Scan = FindViewById<Button>(Resource.Id.Scan);
TextView NewDevice = FindViewById<TextView>(Resource.Id.NewDevice);
ListView List = FindViewById<ListView>(Resource.Id.ListBluetooth);
//Initialize array adapters
Device = new ArrayAdapter<string>(this, Resource.Layout.Main);
//Testing Faced
Scan.Click += (sender, e) =>
{
if (bluetoothAdapter.IsEnabled == true)
{
Toast.MakeText(Application, "Start scanning", ToastLength.Short).Show();
DoDiscovery();
(sender as View).Visibility = ViewStates.Visible;
if(Device.Count != 0)
{
NewDevice.Text = Device.GetItem(0).ToString();
}
else
{
NewDevice.Text = "Device is not recorded";
}
Toast.MakeText(Application, "Device found", ToastLength.Short).Show();
}
else
{
Toast.MakeText(Application, "Please enable bluetooth", ToastLength.Short).Show();
}
};
//Find and set up the ListView for newly discovered devices.
List.Adapter = Device;
List.ItemClick += DeviceListClick;
//Register for broadcasts when a device is discovered
Receiver receiver = new Receiver();
var filter = new IntentFilter(BluetoothDevice.ActionFound);
RegisterReceiver(receiver, filter);
//Register for broadcasts when discovery is finished
filter = new IntentFilter(BluetoothAdapter.ActionDiscoveryFinished);
RegisterReceiver(receiver, filter);
bluetoothAdapter = BluetoothAdapter.DefaultAdapter; //Get Loacl Bluetooth Adapter
if (bluetoothAdapter == null)
{
Toast.MakeText(this, "Bluetooth is not Supported.", ToastLength.Long).Show();
Finish();
return;
}
//Display the Name of local bluetooth
Device_Name.Text = bluetoothAdapter.Name;
}
protected override void OnResume()
{
base.OnResume();
//RegisterReceiver(bluetooth, new IntentFilter(""));
}
protected override void OnPause()
{
base.OnPause();
//UnregisterReceiver(bluetooth);
}
void DeviceListClick (object sender, AdapterView.ItemClickEventArgs args)
{
// Cancel discovery because it's costly and we're about to connect
bluetoothAdapter.CancelDiscovery();
//Get the device MAC address, which is the last 17 chars in the View
var info = (args.View as TextView).Text.ToString();
var address = info.Substring(info.Length - 17);
//Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.PutExtra(Extra_Device_Address, address);
//Set result and finish this Activity
SetResult(Result.Ok, intent);
Finish();
}
private void DoDiscovery()
{
//Indicate scanning in the title
SetProgressBarIndeterminateVisibility(true);
SetTitle(Resource.String.scanning);
//Turn on sub-title for new devices
FindViewById<View>(Resource.Id.NewDevice).Visibility = ViewStates.Visible;
//If we're already discovering, stop it
if (bluetoothAdapter.IsDiscovering)
{
bluetoothAdapter.CancelDiscovery();
}
//Request disccover from BluetoothAdapter
bluetoothAdapter.StartDiscovery();
}
public class Receiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
string action = intent.Action;
// When discovery finds a device
if (action == BluetoothDevice.ActionFound)
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
// If it's already paired, skip it, because it's been listed already
if(device.BondState != Bond.Bonded)
{
Device.Add(device.Name + "\n" + device.Address);
}
// When discovery is finished, change the Activity title
else if(Device.Count == 0)
{
Device.Add("Empty");
}
}
}
}
}
}
Testing my code, I found out that my application is unable to detect Bluetooth devices and also it is unable to display them. I went online to find examples to follow and did not find anything wrong. Any helps would be greatly appreciated. Apologies if I made small mistakes, this is my first time trying to create android application using Xamarin.

Related

foreground service never stop xamarin android

i have xamarin android application that read from clipboard and write to it. it uses foreground services if the user hit the button. the problem is when the user hit the button again the services disappear from running services but still doing it's job (editing copied text). how can i completely stop it from working?
foreground.cs:
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
Clipboard.ClipboardContentChanged += async (o, e) =>
{
var text = await Clipboard.GetTextAsync();
Toast.MakeText(this, text, ToastLength.Long).Show();
if (text.Contains("#"))
{
await Clipboard.SetTextAsync(text.Replace("#", ""));
}
};
Notification notif = ReturnNotif();
StartForeground(1, notif);
return StartCommandResult.NotSticky;
}
public override void OnDestroy()
{
base.OnDestroy();
}
public override void OnCreate()
{
base.OnCreate();
}
public override bool StopService(Intent name)
{
StopForeground(true);
StopSelf();
return base.StopService(name);
}
MainActivity.cs:
if (id == Resource.Id.myService)
{
if (count != 1)
{
count = 1;
var intent = new Intent(this, typeof(foreground));
intent.SetAction("No");
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
StartForegroundService(intent);
}
else
{
StartService(intent);
}
}
else
{
var intent = new Intent(this,typeof(foreground));
StopService(intent);
Toast.MakeText(this, "Service Stopped", ToastLength.Long).Show();
count = 0;
}
}
what i am doing wrong ?
Edit :
Service will completely stops if the app is removed from recently used apps.
In your MyForegroundService.cs. Just add StopForeground(true) in OnDestroy() method like following code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace ForegroundServiceDemo
{
[Service]
class MyForegroundService : Service
{
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
CreateNotificationChannel();
string messageBody = "service starting";
// / Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this,typeof(Activity1));
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this);
stackBuilder.AddNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, PendingIntentFlags.UpdateCurrent);
var notification = new Notification.Builder(this, "10111")
.SetContentIntent(resultPendingIntent)
.SetContentTitle("Foreground")
.SetContentText(messageBody)
.SetSmallIcon(Resource.Drawable.main)
.SetOngoing(true)
.Build();
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
//do you work
return StartCommandResult.Sticky;
}
public override void OnDestroy()
{
base.OnDestroy();
StopForeground(true);
}
public override IBinder OnBind(Intent intent)
{
return null;
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
return;
}
var channelName = Resources.GetString(Resource.String.channel_name);
var channelDescription = GetString(Resource.String.channel_description);
var channel = new NotificationChannel("10111", channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
}
}
When you want to stop it. Just call following code.
Android.App.Application.Context.StopService(intent);
Here is my code in the Activity.
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Button button1 = FindViewById<Button>(Resource.Id.button1);
Button button2 = FindViewById<Button>(Resource.Id.button2);
button2.Click += Button2_Click;
button1.Click += Button1_Click;
}
Intent intent;
private void Button2_Click(object sender, System.EventArgs e)
{
// stop foreground service.
Android.App.Application.Context.StopService(intent);
}
private void Button1_Click(object sender, System.EventArgs e)
{
intent = new Intent(Android.App.Application.Context, typeof(MyForegroundService));
// start foreground service.
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
StartForegroundService(intent);
}
}
Here is running GIF.
====Update====
the expected behavior is : when service stopped user can copy and paste normally without the service interference
You can use following way to achieve that.Use Clipboard.ClipboardContentChanged += Clipboard_ClipboardContentChanged; to execute the behavior, use Clipboard.ClipboardContentChanged -= Clipboard_ClipboardContentChanged; to disable the behavior in the OnDistory method.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Essentials;
namespace ForegroundServiceDemo
{
[Service]
class MyForegroundService : Service
{
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
CreateNotificationChannel();
string messageBody = "service starting";
Clipboard.ClipboardContentChanged += Clipboard_ClipboardContentChanged;
// / Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this,typeof(Activity1));
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this);
stackBuilder.AddNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, PendingIntentFlags.UpdateCurrent);
var notification = new Notification.Builder(this, "10111")
.SetContentIntent(resultPendingIntent)
.SetContentTitle("Foreground")
.SetContentText(messageBody)
.SetSmallIcon(Resource.Drawable.main)
.SetOngoing(true)
.Build();
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
//do you work
return StartCommandResult.Sticky;
}
private async void Clipboard_ClipboardContentChanged(object sender, EventArgs e)
{
//throw new NotImplementedException();
var text = await Clipboard.GetTextAsync();
Toast.MakeText(this, text, ToastLength.Long).Show();
if (text.Contains("#"))
{
await Clipboard.SetTextAsync(text.Replace("#", ""));
}
}
public override void OnDestroy()
{
base.OnDestroy();
Clipboard.ClipboardContentChanged -= Clipboard_ClipboardContentChanged;
StopForeground(true);
}
public override IBinder OnBind(Intent intent)
{
return null;
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
return;
}
var channelName = Resources.GetString(Resource.String.channel_name);
var channelDescription = GetString(Resource.String.channel_description);
var channel = new NotificationChannel("10111", channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
}
}
Here is run GIF.
To prevent this issues, add a "myServiceIsRunning" bool value in the Properties dictionary when you start your foreground method like this:
Application.Current.Properties["myServiceIsRunning"] = true
With a get function or whatever you want, before start the foreground method, verify if the key "myServiceIsRunning" exist, and if it exist, how is his status:
public bool getRunningStateMyService(){
bool myServiceIsRunningValue;
if (Application.Current.Properties.ContainsKey("myServiceIsRunning"))
{
myServiceIsRunningValue = Convert.ToBoolean(Application.Current.Properties["myServiceIsRunning"]);
}
else
{
myServiceIsRunningValue = false;
}
return locationServiceIsRunning;
}
After you get the value, with a simple if{}/else{}, you can choose to start a new instance or not if you're service is running or not. Or, in you're case just prevent the foreground method continue to run.
Don't forget to set your value to false when you destroy the foreground method.
the Properties dictionary can store data trought closing app to. you can have more infos here:
https://learn.microsoft.com/fr-fr/xamarin/xamarin-forms/app-fundamentals/application-class#Properties_Dictionary

xamarin android webview file upload download does not work . please i am comfortable with c#

i have created a mobile app for my website .the webview does not handle upload and download .so i followed the link Uploading files using a webview in Xamarin Android App and included the code from this link but does not handle upload and download. please guide. the storeactivity.cs code here.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Net;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Webkit;
using Android.Widget;
namespace smartapp
{
[Activity(Label = "StoreActivity")]
public class StoreActivity : Activity
{
static ProgressBar progressBar;
WebView webview;
IValueCallback mUploadMessage;
private static int FILECHOOSER_RESULTCODE = 1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.StoresView);
webview = FindViewById<WebView>(Resource.Id.StoreView);
// show progress bar
progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar);
// chrome client to upload files from webview
var chrome = new FileChooserWebChromeClient((uploadMsg, acceptType, capture) => {
mUploadMessage = uploadMsg;
var i = new Intent(Intent.ActionGetContent);
i.AddCategory(Intent.CategoryOpenable);
i.SetType("image/*");
StartActivityForResult(Intent.CreateChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
});
webview.LoadUrl("https://smartbook.pk/Stores/index");
webview.SetWebViewClient(new WebViewListener());
// download files from webview
webview.SetDownloadListener(new MyDownloadListerner(this));
webview.SetWebChromeClient(chrome);
webview.Settings.JavaScriptEnabled = true;
}
//
class MyDownloadListerner : Java.Lang.Object, IDownloadListener
{
Context cont;
public MyDownloadListerner(Context context)
{
cont = context;
}
public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
{
Android.Net.Uri uri = Android.Net.Uri.Parse(url);
Intent intent = new Intent(Intent.ActionView, uri);
cont.StartActivity(intent);
}
}
//
//
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage)
return;
Java.Lang.Object result = intent == null || resultCode != Result.Ok
? null
: intent.Data;
mUploadMessage.OnReceiveValue(result);
mUploadMessage = null;
}
}
// file chooser code
partial class FileChooserWebChromeClient : WebChromeClient
{
Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback;
public FileChooserWebChromeClient(Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback)
{
this.callback = callback;
}
//For Android 4.1
[Java.Interop.Export]
public void openFileChooser(IValueCallback uploadMsg, Java.Lang.String acceptType, Java.Lang.String capture)
{
callback(uploadMsg, acceptType, capture);
}
}
// webview listener code here
public class WebViewListener : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
{
view.LoadUrl(request.Url.ToString());
return true;
}
public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
{
progressBar.Progress = view.Progress;
}
public override void OnLoadResource(WebView view, string url)
{
progressBar.Progress = view.Progress;
}
public override void OnPageFinished(WebView view, string url)
{
progressBar.Progress = 0;
}
}
public override bool OnKeyDown(Android.Views.Keycode keyCode, Android.Views.KeyEvent e)
{
if (keyCode == Keycode.Back && webview.CanGoBack())
{
webview.GoBack();
return true;
}
return base.OnKeyDown(keyCode, e);
}
}
}
This is the Working Code of File Upload Hope this will Help you
public class MyWb : Activity
{
int count = 1;
IValueCallback mUploadMessage;
private static int FILECHOOSER_RESULTCODE = 1;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
button.Text = string.Format ("{0} clicks!", count++);
};
var chrome = new FileChooserWebChromeClient ((uploadMsg, acceptType, capture) => {
mUploadMessage = uploadMsg;
var i = new Intent (Intent.ActionGetContent);
i.AddCategory (Intent.CategoryOpenable);
i.SetType ("image/*");
StartActivityForResult (Intent.CreateChooser (i, "File Chooser"), FILECHOOSER_RESULTCODE);
});
var webview = this.FindViewById<WebView> (Resource.Id.webView1);
webview.SetWebViewClient (new WebViewClient ());
webview.SetWebChromeClient (chrome);
webview.Settings.JavaScriptEnabled = true;
webview.LoadUrl ("http://www.script-tutorials.com/demos/199/index.html");
}
protected override void OnActivityResult (int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage)
return;
Java.Lang.Object result = intent == null || resultCode != Result.Ok
? null
: intent.Data;
mUploadMessage.OnReceiveValue (result);
mUploadMessage = null;
}
}
}
partial class FileChooserWebChromeClient : WebChromeClient
{
Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback;
public FileChooserWebChromeClient (Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback)
{
this.callback = callback;
}
//For Android 4.1
[Java.Interop.Export]
public void openFileChooser (IValueCallback uploadMsg, Java.Lang.String acceptType, Java.Lang.String capture)
{
callback (uploadMsg, acceptType, capture);
}
}

WakefulBroadcastReceiver Xamarin Does not work

I wrote a program, for when sms received it will play ring. But it's work only when program is running and when program closed it's doesn't work.
What should I do?
public class MainActivity : Activity
{
SampleReceiver receiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
receiver = new SampleReceiver();
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
intentFilter.Priority = 1000;
RegisterReceiver(receiver, intentFilter);
// Code omitted for clarity
}
}
[BroadcastReceiver(Enabled = true, Exported = true)]
public class SampleReceiver : WakefulBroadcastReceiver
{
private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED";
public override void OnReceive(Context context, Intent intent)
{
try
{
Android.Net.Uri uri = RingtoneManager.GetDefaultUri(RingtoneType.Ringtone);
Ringtone ringtone = RingtoneManager.GetRingtone(context, uri);
ringtone.Play();
if (intent.HasExtra("pdus"))
{
var smsArray = (Java.Lang.Object[])intent.Extras.Get("pdus");
foreach (var item in smsArray)
{
var sms = SmsMessage.CreateFromPdu((byte[])item);
string address = sms.OriginatingAddress;
string smsText = sms.MessageBody;
Toast.MakeText(context, "Massage from : " + address + " Says : " + smsText, ToastLength.Long).Show();
}
}
}
catch (System.Exception ex)
{
//Toast.MakeText(context, ex.Message, ToastLength.Long).Show();
}
}
}
Tnx

Xamarin Android Background Service crashes when the Application get closed

Hello, I want to build an app, in which you can start a service, which runs intependenly and creates a notification, and this service should constantly proof, if the DateTime.Now.Date is bigger than a spezific Date.
When I execute the code below, the notification gets displayed, but when I am closing the app, a few secondes later I get two times an information that the app crashed and I dont know why.
I cant even debug the code because this anly happens when the application is closed....
I hope you can help me thanks!
Here is my code:
namespace App
{
[Activity(Label = "App", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate {
button.Text = string.Format("{0} clicks!", count++);
StartService(new Intent(this, typeof(backgroudservice)));
};
}
}
public class backgroudservice : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
newnotification("Title", "Text: ", 0);
new Task(() => {
DoWork();
Thread.Sleep(1000);
}).Start();
return StartCommandResult.Sticky;
}
public void DoWork()
{
if (DateTime.Now.Date > Convert.ToDateTime("2016-03-29").Date)
{
cancelnotification(0);
StopSelf();
}
}
public override void OnDestroy()
{
base.OnDestroy();
cancelnotification(0);
}
private void newnotification(string titel, string text, int id)
{
Notification.Builder builder = new Notification.Builder(this)
.SetContentTitle(titel)
.SetContentText(text)
.SetSmallIcon(Resource.Drawable.droidlogo_small)
.SetAutoCancel(false)
.SetVisibility(NotificationVisibility.Public)
.SetContentIntent(PendingIntent.GetActivity(this, 0, new Intent(this, typeof(MainActivity)), PendingIntentFlags.OneShot));
// Build the notification:
Notification notification = builder.Build();
notification.Flags = NotificationFlags.NoClear;
//notification.ContentIntent = new Intent(this,typeof(login));
// Get the notification manager:
NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
// Publish the notification:
notificationManager.Notify(id, notification);
}
private void cancelnotification(int id)
{
NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
notificationManager.Cancel(id);
}
}
}
I solved it, I forgot the [Service] above my class, now it works!
[Service]
public class backgroudservice : Service
{
...
}
You might try moving the call to cancelnotification in your service's OnDestroy to before the call to the base method, i.e.:
public override void OnDestroy()
{
cancelnotification(0);
base.OnDestroy();
}

Collecting GPS co-Ordinates

I am building a native android app using xamarin. The issue is, that the application collects and displays the coordinates perfectly on the emulator but when I put it on a smartphone (tried 2 samsung phones) it comes up with can't determine the current address. Extra information data and locations are turned on so I am not sure where the issue is. Thanks for your help. here is the xammarin recipe encase that helps https://developer.xamarin.com/recipes/android/os_device_resources/gps/get_current_device_location/
[Activity(Label = "NewRoute")]
public class NewRouteActivity : Activity, ILocationListener
{
static readonly string TAG = "X:" + typeof(NewRouteActivity).Name;
TextView _addressText;
Location _currentLocation;
LocationManager _locationManager;
string _locationProvider;
TextView _locationText;
public async void OnLocationChanged(Location location) {
_currentLocation = location;
if (_currentLocation == null)
{
_locationText.Text = "Unable to determine your location. Try again in a short while.";
}
else
{
_locationText.Text = string.Format("{0:f6},{1:f6}", _currentLocation.Latitude, _currentLocation.Longitude);
Address address = await ReverseGeocodeCurrentLocation();
DisplayAddress(address);
}
}
public void OnProviderDisabled(string provider) { }
public void OnProviderEnabled(string provider) { }
public void OnStatusChanged(string provider, Availability status, Bundle extras) { }
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.CreatetRoute);
_addressText = FindViewById<TextView>(Resource.Id.address_text);
_locationText = FindViewById<TextView>(Resource.Id.location_text);
FindViewById<TextView>(Resource.Id.get_address_button).Click += AddressButton_OnClick;
InitializeLocationManager();
Button btnEndPoint = FindViewById<Button>(Resource.Id.btnEndPoint);
btnEndPoint.Click += new EventHandler(AfterPointsCollected);
}
//Location Stuff
void InitializeLocationManager()
{
_locationManager = (LocationManager)GetSystemService(LocationService);
Criteria criteriaForLocationService = new Criteria
{
Accuracy = Accuracy.Fine
};
IList<string> acceptableLocationProviders = _locationManager.GetProviders(criteriaForLocationService, true);
if (acceptableLocationProviders.Any())
{
_locationProvider = acceptableLocationProviders.First();
}
else
{
_locationProvider = string.Empty;
}
Log.Debug(TAG, "Using " + _locationProvider + ".");
}
//Override OnResume so that Activity1 will begin listening to the LocationManager when the activity comes into the foreground:
protected override void OnResume()
{
base.OnResume();
_locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
}
async void AddressButton_OnClick(object sender, EventArgs eventArgs)
{
if (_currentLocation == null)
{
_addressText.Text = "Can't determine the current address. Try again in a few minutes.";
return;
}
Address address = await ReverseGeocodeCurrentLocation();
DisplayAddress(address);
}
async Task<Address> ReverseGeocodeCurrentLocation()
{
Geocoder geocoder = new Geocoder(this);
IList<Address> addressList =
await geocoder.GetFromLocationAsync(_currentLocation.Latitude, _currentLocation.Longitude, 10);
Address address = addressList.FirstOrDefault();
return address;
}
void DisplayAddress(Address address)
{
if (address != null)
{
StringBuilder deviceAddress = new StringBuilder();
for (int i = 0; i < address.MaxAddressLineIndex; i++)
{
deviceAddress.AppendLine(address.GetAddressLine(i));
}
// Remove the last comma from the end of the address.
_addressText.Text = deviceAddress.ToString();
}
else
{
_addressText.Text = "Unable to determine the address. Try again in a few minutes.";
}
}
//Override OnPause and unsubscribe Activity1 from the LocationManager when the activity goes into the background:
protected override void OnPause()
{
base.OnPause();
_locationManager.RemoveUpdates(this);
}
//Changing Activity
void AfterPointsCollected(object sender, EventArgs e)
{
//context //activity
Intent intent = new Intent(this, typeof(AfterPointsCollectedActivity));
//starts the activity with the intent above
this.StartActivity(intent);
}
Your phones are probably running MarshMallow which now require that you request permission for location services.
You can read more about it here https://blog.xamarin.com/requesting-runtime-permissions-in-android-marshmallow/. You might want to use this Nuget package that handles all that for you. https://github.com/jamesmontemagno/Xamarin.Plugins/tree/master/Geolocator

Categories