Unable to access data from service in activity - c#

I am building a Xamarin.Android application. I have a working service, and I am trying to get data from that service to an activity that I have. I know that people get upset over too much code being posted, but I am unsure where my issue is. I am going post what I think is necessary:
Service
[Service]
public class DataService : Service
{
public List<MyObjects> MyObjectList { get; private set; }
public IBinder Binder { get; private set; }
public override IBinder OnBind(Intent intent)
{
this.Binder = new DataServiceBinder(this);
return this.Binder;
}
public override void OnCreate()
{
base.OnCreate();
pendingIntent = PendingIntent.GetActivity(this, 0, new Intent(this, typeof(MainActivity)), 0);
StartForeground(NotificationID, GetNotification("Started Sync"));
//Do some work here to instantiate and populate the List
}
}
Service Binder
public class DataServiceBinder : Binder
{
public DataServiceBinder(DataService service)
{
Service = service;
}
public DataService Service { get; private set; }
}
Service Connection
public class DataServiceConnection : Object, IServiceConnection
{
public DataService Service { get; private set; }
public DataServiceBinder dataServiceBinder;
public bool IsConnected { get; private set; }
public void OnServiceConnected(ComponentName name, IBinder service)
{
dataServiceBinder = service as DataServiceBinder;
IsConnected = this.dataServiceBinder != null;
Service = dataServiceBinder.Service;
ServiceConnectionChanged?.Invoke(this, true);
}
public void OnServiceDisconnected(ComponentName name)
{
ServiceConnectionChanged?.Invoke(this, false);
Service = null;
}
public event EventHandler<bool> ServiceConnectionChanged;
}
Activity
public class MyDataActivity : AppCompatActivity
{
private DataServiceConnection DataServiceConnection;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (DataServiceConnection == null)
{
this.DataServiceConnection = new DataServiceConnection();
}
Intent serviceToStart = new Intent(this, typeof(DataService));
BindService(serviceToStart, this.DataServiceConnection, Bind.AutoCreate);
SetContentView(Resource.Layout.MyDataLayout);
var adapter = new MyDataAdapter(DataServiceConnection.Service.MyObjectList);
}
protected override void OnResume()
{
var intent = new Intent(this, typeof(DataService));
BindService(intent, DataServiceConnection, Bind.AutoCreate);
base.OnResume();
}
protected override void OnPause()
{
UnbindService(DataServiceConnection);
base.OnPause();
}
In my activity, when I try to pass the adapter the list from the service, the "Service" is null, and there for I get a null reference exception. Why is my Service null? Am I not binding my service properly? For the record, they service is started in the Application context.

Ok, I found the solution. Since connecting to the service is asynchronous I cannot expect the adapter to be able to get data synchronously like this:
var adapter = new MyDataAdapter(DataServiceConnection.Service.MyObjectList);
Instead, I modified my activity to look like this:
public class MyDataActivity : AppCompatActivity
{
private DataServiceConnection DataServiceConnection;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (DataServiceConnection == null)
{
this.DataServiceConnection = new DataServiceConnection();
}
Intent serviceToStart = new Intent(this, typeof(DataService));
BindService(serviceToStart, this.DataServiceConnection, Bind.AutoCreate);
DataServiceConnection.ServiceConnectionChanged += ServiceConnectionChanged;
SetContentView(Resource.Layout.MyDataLayout);
}
private void ServiceConnectionChanged(object sender, bool isConnected)
{
if(DataServiceConnection.Service == null)
{
return;
}
if(isConnected)
{
var adapter = new MyDataAdapter(DataServiceConnection.Service.MyObjectList);
}
}
protected override void OnResume()
{
var intent = new Intent(this, typeof(DataService));
BindService(intent, DataServiceConnection, Bind.AutoCreate);
base.OnResume();
}
protected override void OnPause()
{
UnbindService(DataServiceConnection);
base.OnPause();
}
I also modified my Service Connection as such:
public class DataServiceConnection : Object, IServiceConnection
{
public DataService Service { get; private set; }
public MyDataActivity DataActivity;
public event EventHandler<bool> ServiceConnectionChanged;
public DataServiceConnection(MyDataActivity myDataActivity)
{
DataActivity = myDataActivity;
}
public void OnServiceConnected(ComponentName name, IBinder service)
{
dataServiceBinder = service as DataServiceBinder;
Service = dataServiceBinder.Service;
ServiceConnectionChanged?.Invoke(this, true);
}
public void OnServiceDisconnected(ComponentName name)
{
ServiceConnectionChanged?.Invoke(this, false);
Service = null;
}
}
Now my solution only tries to send data to the adapter when the service is connected. This solution is working for me, and I hope it helps anyone else.

Related

how to send value from android-project to share-project?

how to send verificationId from SendOtpCodeAsync() to SendCode_Button_Clicked()
Share Project code
IAuth auth;
auth = DependencyService.Get<IAuth>();
private async void SendCode_Button_Clicked(object sender, EventArgs e)
{
bool result = await auth.SendOtpCodeAsync(PhonenumberEntry.Text);
}
android project code
[assembly: Dependency(typeof(AuthDriod))]
namespace TestApp_MiniApps.Droid
{
public class AuthDriod : PhoneAuthProvider.OnVerificationStateChangedCallbacks, IAuth
{
private TaskCompletionSource<bool> _phoneAuthTcs;
public Task<bool> SendOtpCodeAsync(string phonenumber)
{
_phoneAuthTcs = new TaskCompletionSource<bool>();
Java.Lang.Long num = (Java.Lang.Long)60;
PhoneAuthOptions options =
PhoneAuthOptions.NewBuilder(FirebaseAuth.Instance)
.SetPhoneNumber(phonenumber) // Phone number to verify
.SetTimeout(num, TimeUnit.Seconds) // Timeout and unit
.SetActivity(Platform.CurrentActivity) // Activity (for callback binding)
.SetCallbacks(this) // OnVerificationStateChangedCallbacks
.Build();
PhoneAuthProvider.VerifyPhoneNumber(options);
return _phoneAuthTcs.Task;
}
public override void OnVerificationCompleted(PhoneAuthCredential credential)
{
}
public override void OnVerificationFailed(FirebaseException exception)
{
_phoneAuthTcs?.TrySetResult(false);
}
public override void OnCodeSent(string verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken)
{
base.OnCodeSent(verificationId, forceResendingToken);
_phoneAuthTcs?.TrySetResult(true);
}
}//end of class
}
share project interface
namespace TestApp_MiniApps.Views.Xamarin.FireBase
{
public interface IAuth
{
Task<bool> SendOtpCodeAsync(string phonenumber);
}//end of class
}
To summarise what Leo had put in the comments you can check what is returned from your method call.
Change from bool to your own class. For the purpose of this answer I will call it OtpResult.
// The new class definition:
public class OtpResult
{
public bool Success { get; set; }
// Define whatever you like here
public string StringValue { get; set; }
}
public interface IAuth
{
Task<OtpResult> SendOtpCodeAsync(string phonenumber);
}

How to use PendingIntent instead of an Intent with ConnectivityManager.ConnectivityAction with a callback in C# Xamarin API 28?

I need to make a simple callback in Xamarin, to check if the network status is connected or disconnected.
I have so far been doing it with this code:
class NetworkControl : INetworkControl
{
private readonly INetworkControl.ICallback _callback;
private readonly Context _context;
private readonly NetworkBroadcastReceiver _receiver = new NetworkBroadcastReceiver();
public NetworkControl(INetworkControl.ICallback callback, Context context)
{
_callback = callback;
_context = context;
IntentFilter filter = new IntentFilter(ConnectivityManager.ConnectivityAction);
context.RegisterReceiver(_receiver, filter);
}
public INetworkControl.ICallback Callback => _callback;
public INetworkControl.NetworkStatus Status
{
get
{
var current = Connectivity.NetworkAccess;
if (current == NetworkAccess.Internet)
{
return INetworkControl.NetworkStatus.Connected;
}
return INetworkControl.NetworkStatus.Disconnected;
}
}
}
class NetworkBroadcastReceiver : BroadcastReceiver
{
private static String TAG = "NetworkBroadcastReceiver";
public override void OnReceive(Context context, Intent intent)
{
if (ShellBridge.Instance != null)
{
if (intent.Action.Equals(ConnectivityManager.ConnectivityAction))
{
NetworkInfo ni = (NetworkInfo)intent.Extras.Get(ConnectivityManager.ExtraNetworkInfo);
if (ni.isConnected)
{
// do something if connected
ShellBridge.Instance.NetworkBridge.Callback.NetworkStatusChanged(INetworkControl.NetworkStatus.Connected);
} else
{
ShellBridge.Instance.NetworkBridge.Callback.NetworkStatusChanged(INetworkControl.NetworkStatus.Connected);
}
}
}
}
The problem is, the function ConnectivityManager.ConnectivityAction in the Intent creating is depricated, and will soon be obsolete. After searching, I found that the pendingIntent should be used for that, but I could not find any valid example of how to use it.
The closest to what I need is this:
https://stackoverflow.com/questions/58588132/how-to-use-registernetworkcallback-with-pendingintent
But, it has not all the information I need.
I need it to be all programmatically, without changing the manifest, for, my app should be a fore- and background app.
Please help, and thank you for your time.
You can take a look at NetworkCallback .
public class ConnectionStateMonitor : NetworkCallback
{
NetworkRequest networkRequest;
public ConnectionStateMonitor()
{
networkRequest = new NetworkRequest.Builder().
AddTransportType(TransportType.Cellular).
AddTransportType(TransportType.Wifi).Build();
}
public void enable(Context context) {
ConnectivityManager connectivityManager = context.GetSystemService(Context.ConnectivityService) as ConnectivityManager;
connectivityManager.RegisterNetworkCallback(networkRequest, this);
}
public override void OnAvailable(Network network)
{
//network available
}
public override void OnLost(Network network)
{
//network lost
}
}
Usage
You just need to instantiate the class ConnectionStateMonitor and enable it , you could detect the network status with the method OnAvailable and OnLost .
ConnectionStateMonitor m = new ConnectionStateMonitor ();
m.enable(context);
Refer
https://github.com/xamarin/Essentials/issues/512
ConnectivityManager.CONNECTIVITY_ACTION deprecated
You don't need to reinvent the wheel. You can achieve all that with Xamarin Essentials' Connectivity.
Besides checking if there is a connectivity like this:
var current = Connectivity.NetworkAccess;
if (current == NetworkAccess.Internet)
{
// Connection to internet is available
}
you can also track when the connectivity type changes:
public class ConnectivityTest
{
public ConnectivityTest()
{
// Register for connectivity changes, be sure to unsubscribe when finished
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
}
void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e)
{
var access = e.NetworkAccess;
var profiles = e.ConnectionProfiles;
}
}

How to call same service instance from multiple activities in Android

I've just started looking into Xamarin and just can not to wrap around my head how to make multiple Activities have a reference same instance of service.
I am starting KeyPressedReceiver from MainActivity and start listening for power button being pressed.
When three click are being made, I am calling service method InitCancelActivity, which starts playing mp3 file and opens CancelActivity.
In CancelActivity there is a text field and a button. And when user press this button, I want the value from text field to be passes to the GeneralService method KillAlert.
The question is how to reference instance of GeneralService (which is already created) from CancelActivity, so I could call KillAlert?
And this part
if (_service == null)
_service = new GeneralService();
looks absolutely wrong. Should I instantiate it in MainActivity and pass to a KeyPressedReceiver constructor?
[Activity(Label = "TTTT", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
KeyPressedReceiver receiver;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
receiver = new KeyPressedReceiver();
RegisterReceiver(receiver, new IntentFilter(Intent.ActionScreenOn));
}
}
[BroadcastReceiver(Enabled = true)]
public class KeyPressedReceiver : BroadcastReceiver
{
private GeneralService _service;
private int _clicks = 0;
public override void OnReceive(Context context, Intent intent)
{
if (_service == null)
_service = new GeneralService();
_clicks++;
if (_clicks > 5)
{
_service.InitCancelActivity();
}
}
}
[Service(Name = "com.ff.GeneralService")]
public class GeneralService : Service {
private readonly Android.Media.MediaPlayer _player;
public GeneralService()
{
_player = new Android.Media.MediaPlayer();
}
public void RaiseAlert()
{
// start playing .mp3 file
}
public void KillAlert(string pass)
{
// stop playing .mp3 file
}
public void InitCancelActivity()
{
this.RaiseAlert();
var i = new Intent(this, typeof(CancelActivity));
i.SetFlags(ActivityFlags.NewTask);
this.StartActivity(i);
}
}
[Activity(Label = "CancelActivity")]
public class CancelActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.cancel);
this.FindViewById(Resource.Id.cancelButtonYes).Click += delegate
{
var password = this.FindViewById(Resource.Id.cancelPassword);
// call KillAlert method from GeneralServic
};
}
}
Create static GeneralService instance and use in Cancel Activity.
for example
[Service(Name = "com.ff.GeneralService")]
public class GeneralService : Service {
private readonly Android.Media.MediaPlayer _player;
public static generalService;
public GeneralService()
{
_player = new Android.Media.MediaPlayer();
generalService=this
}
public void RaiseAlert()
{
// start playing .mp3 file
}
public void KillAlert(string pass)
{
// stop playing .mp3 file
}
public void InitCancelActivity()
{
this.RaiseAlert();
var i = new Intent(this, typeof(CancelActivity));
i.SetFlags(ActivityFlags.NewTask);
this.StartActivity(i);
}
}
and use in CancelActivity like below example
[Activity(Label = "CancelActivity")]
public class CancelActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.cancel);
this.FindViewById(Resource.Id.cancelButtonYes).Click += delegate
{
var password = this.FindViewById(Resource.Id.cancelPassword);
// call KillAlert method from GeneralServic
GeneralService.generalService.KillAlert(password.TEXT);
};
}
}

How to get variable from another class to OnPrepare/CreateOptionsMenu

I have a simple wifi app. It is just scanning wifis and listing them. I figured out my ScanResult List is filling in another method but in OnPrepare/CreateOptionsMenu it is always null.
This method calls first when program starts I know that, but when i try to call it again with InvalidateOptionsMenu(); nothing changes. Here is my piec of code:
MainActivity:
public class MainActivity : Activity
{
public static Context context;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Button wifiButton = FindViewById<Button>(Resource.Id.popupButton);
RegisterReceiver(new WiFiReceiver(), new IntentFilter(WifiManager.ScanResultsAvailableAction));
((WifiManager)GetSystemService(WifiService)).StartScan();
wifiButton.Click += (s, arg) => {
InvalidateOptionsMenu();
PopupMenu menu = new PopupMenu(this, wifiButton);
menu.Inflate(Resource.Menu.menu);
menu.Show();
};
}
public override bool OnCreateOptionsMenu(IMenu menu) {
WiFiReceiver wifiReceiver = new WiFiReceiver();
IList<ScanResult> availableWifis = wifiReceiver.GetWifiList();//This is always null
if (availableWifis != null) {
foreach (ScanResult token in availableWifis) {
menu.Add(token.Ssid);
}
}
return base.OnCreateOptionsMenu(menu);
}
}
WiFi Scanning this class:
class WiFiReceiver : BroadcastReceiver {
private IList<ScanResult> wifiList;
private string message;
public override async void OnReceive(Context context, Intent intent) {
MainActivity mainActivity = (MainActivity)context;
WifiManager wifiManager = (WifiManager)mainActivity.GetSystemService(Context.WifiService);
this.message = string.Join("\r\n", wifiManager.ScanResults
.Select(r => $"{r.Ssid} - {r.Level} dB"));
this.wifiList = wifiManager.ScanResults.ToList(); //This has connection informations
mainActivity.DisplayText(message);
await Task.Delay(TimeSpan.FromSeconds(1));
wifiManager.StartScan();
}
public IList<ScanResult> GetWifiList() {
return wifiList;
}

Send Data from a Service to BroadcastReceiver of other Activity (Xamarin Android)

I have a problem with sending Location from service to custom BroadcastReceiver.
This is my BroadcastReceiver.cs
[BroadcastReceiver]
class MyBroadcastReceiver : BroadcastReceiver
{
public static readonly string GRID_STARTED = "GRID_STARTED";
public event EventHandler<OnLocationChangedEventArgs> mOnLocationChanged;
private Location location;
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == GRID_STARTED)
{
Toast.MakeText(context, "Grid Started", ToastLength.Short).Show();
//location = JsonConvert.DeserializeObject<Location>(intent.GetStringExtra("location"));
//mOnLocationChanged.Invoke(this, new OnLocationChangedEventArgs(location));
}
}
}
If I UNCOMMENT two lines in the upper code my app suddenly stops. I cannot tell you what is the error because, while developing Xamarin apps debugging is stopped by an internal error (I read about it on Xamarin Forums but couldn't find time to deal with it).
This is what I have done in service:
private void BroadcastStarted(Location location)
{
Intent BroadcastIntent = new Intent(this, typeof(MyBroadcastReceiver));
BroadcastIntent.PutExtra("location",JsonConvert.SerializeObject(location));
BroadcastIntent.SetAction(MyBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
}
I'm using Newtonsoft.Json for sending an objet.
Any help would be appreciated.
UPDATE:
Ok, somehow I managed to reveal the error:
Unable to find a constructor to use for type
Android.Location.Location. A class should either have a default
constructor,one constructor with arguments or a constructor marked
with JsonConstructor attribute.
UPDATE:
Whole service code:
using Newtonsoft.Json;
namespace GoogleMaps
{
public class OnLocationChangedEventArgs
{
Location location;
public Location Location
{
get { return location; }
set { location = value; }
}
public OnLocationChangedEventArgs(Location location)
{
this.location = location;
}
}
[Service]
class MyService : Service
{
private LocationManager locationManager = null;
public MyService()
{
}
private class MyLocationListener : Java.Lang.Object,ILocationListener
{
Location mLastLocation;
public event EventHandler<OnLocationChangedEventArgs> onLoc;
public MyLocationListener(String provider)
{
mLastLocation = new Location(provider);
}
public void OnLocationChanged(Location location)
{
try
{
mLastLocation.Set(location);
onLoc.Invoke(this, new OnLocationChangedEventArgs(mLastLocation));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void OnProviderDisabled(string provider)
{
}
public void OnProviderEnabled(string provider)
{
}
public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras)
{
}
}
private MyLocationListener locationListener = new MyLocationListener("network");
public override IBinder OnBind(Intent intent)
{
return null;
}
private void BroadcastStarted(Location location)
{
Intent BroadcastIntent = new Intent(this, typeof(MyBroadcastReceiver));
BroadcastIntent.PutExtra("location",JsonConvert.SerializeObject(location));
BroadcastIntent.SetAction(MyBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
return StartCommandResult.Sticky;
}
public override void OnCreate()
{
try
{
base.OnCreate();
InitializeLocationManager();
locationManager.RequestLocationUpdates(LocationManager.NetworkProvider, 0, 0, locationListener);
locationListener.onLoc += MyService_onLoc;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void MyService_onLoc(object sender, OnLocationChangedEventArgs e)
{
BroadcastStarted(e.Location);
}
public override void OnDestroy()
{
base.OnDestroy();
locationManager.RemoveUpdates(locationListener);
}
private void InitializeLocationManager()
{
if (locationManager == null)
{
locationManager = (LocationManager)GetSystemService(LocationService);
}
}
}
}
UPDATE:
This is what I told in 6th comment:
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == GRID_STARTED)
{
try
{
Toast.MakeText(context, "Grid Started", ToastLength.Short).Show();
a = new LatLng(intent.GetDoubleExtra("latitude",0),intent.GetDoubleExtra("longitude",0));
mOnLocationChanged.Invoke(this, new OnLatLngChangedEventArgs(a)); // NULL EXCEPTION LINE
}
catch (Exception ex)
{
Toast.MakeText(context, ex.Message, ToastLength.Short).Show();
}
}
}
Why is event handler mOnLocationChanged equal to null?
And service's part:
private void BroadcastStarted(Location location)
{
Intent BroadcastIntent = new Intent(this, typeof(MyBroadcastReceiver));
BroadcastIntent.PutExtra("latitude",location.Latitude);
BroadcastIntent.PutExtra("longitude", location.Longitude);
BroadcastIntent.SetAction(MyBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
}
Send data (not object) from Service (using SendBroadcast) to BroadcastReceiver (in MainActivity):
Android-java Gist here. (100% working and tested code).
C# equivalent Service Class code:
(see import statements in a gist for required namespaces/classes)
[Service]
public class BackgroundService : Service
{
private static LocationReceiver mTickReceiver;
public BackgroundService()
{
}
public override IBinder OnBind(Intent arg0)
{
return null;
}
public override StartCommandResult OnStartCommand (Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
return StartCommandResult.Sticky;
}
public override void OnCreate()
{
registerReceiver();
}
public override void OnDestroy()
{
UnregisterReceiver(mTickReceiver);
mTickReceiver = null;
}
private void registerReceiver()
{
mTickReceiver = new LocationReceiver();
IntentFilter filter = new IntentFilter(Android.Content.Intent.ActionTimeTick); // this will broadcast Intent every minute
RegisterReceiver(mTickReceiver, filter);
}
// you can write this class in separate cs file
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionTimeTick })]
public class LocationReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// sample data, you should get your location here,
// one way is to implement location logic in this class
double SampleLatitude=52.01566;
double SampleLongitude=65.00487;
// assuming above coordinates are from some location manager code
Intent I = new Intent();
i.SetAction("LocationData");
i.PutExtra("Latitude", SampleLatitude);
i.PutExtra("Longitude", SampleLongitude);
// PREPARE BROADCAST FOR MAINACTIVITY
SendBroadcast(i); // this broadcast will be received by mainactivity
}
}
}
C# equivalent MainActivity Class code:
(see import statements in a gist for required namespaces/classes)
public class MainActivity : AppCompatActivity
{
protected override Void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(R.layout.activity_main);
Intent i = new Intent(this, typeof(BackgroundService));
StartService(i);
IntentFilter filter = new IntentFilter("LocationData");
RegisterReceiver(new MyBroadcastReceiver(), filter);
}
// public static variables of MainActivty can be accessed and manipulated in this class
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "LocationData" })]
class MyBroadcastReceiver : BroadcastReceiver
{
public override Void OnReceive(Context context, Intent intent)
{
// GET BROADCAST FROM RECEIVER IN THE BACKGROUND SERVICE CLASS
if (intent.GetAction() == "LocationData")
{
double lat=intent.GetDoubleExtra("Latitude", 0);
double lng=intent.GetDoubleExtra("Longitude", 1);
String LocationDataFromService=lat+","+lng;
// REPLACE this with console.writeline
Log.d("LocationDataFromService",LocationDataFromService);
}
}
}
}
In AndroidManifest.xml declare the service as:
<service android:name=".BackgroundService">
</service>
It may still throw some errors. Hope this helps.
You can also implement interface in MyBroadcastReceiver.cs.I think its easier way.
Here is the code:
MyBroadcastReceiver.cs
[BroadcastReceiver]
class MyBroadcastReceiver : BroadcastReceiver
{
public interface LocationDataInterface
{
void OnLocationChanged(LatLng point);
}
public static readonly string GRID_STARTED = "GRID_STARTED";
private LocationDataInterface mInterface;
private LatLng a;
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == GRID_STARTED)
{
try
{
// data you got from background service
a = new LatLng(intent.GetDoubleExtra("latitude",0), intent.GetDoubleExtra("longitude",0));
mInterface = (LocationDataInterface)context;
mInterface.OnLocationChanged(a);
}
catch (Exception ex)
{
Toast.MakeText(context, ex.Message, ToastLength.Short).Show();
}
}
}
}
MainActivity.cs
public class MainActivity : Activity, MyBroadcastReceiver.LocationDataInterface
{
...
public void OnLocationChanged(LatLng point)
{
// textview where you want to show location data
locationText.Text += point.Latitude + "," + point.Longitude;
// things that you want to do with location point
}
}
If there are some problems with this approach, feel free to comment it.

Categories

Resources