xamarin IllegalStateException activity has been destroyed on app closing - android

I get an IllegalStateException with "activity has been destroyed" when I close my app.
In my App.cs I declare a public static MasterPage:
protected override void OnStart()
{
// Handle when your app starts
if (Device.OS == TargetPlatform.Android)
{
Device.BeginInvokeOnMainThread(() =>
{
masterdetail = new MasterPage();
MainPage = masterdetail;
});
}
else
{
masterdetail = new MasterPage();
MainPage = masterdetail;
}
}
And in the MasterPage.cs I declare the Master and the DetilPage:
public partial class MasterPage : MasterDetailPage
{
public MasterPage()
{
var IsLoggedIn = false;
if (CrossSecureStorage.Current.HasKey("isLoggedIn"))
{
IsLoggedIn = string.Equals(CrossSecureStorage.Current.GetValue("isLoggedIn"), "true", System.StringComparison.CurrentCultureIgnoreCase);
}
Master = SetMasterContentPage();
if (IsLoggedIn)
{
Detail = new NavigationPage(new TaxonomyOverviewPage());
}
else {
Detail = new NavigationPage(new LoginPage());
}
}
ContentPage SetMasterContentPage()
{
var masterPage = new ContentPage { Title = "Test"};
masterPage.Content = new StackLayout
{
Children = {
new Label{Text="Label1"},
new Label{Text="Label2"},
new Label{Text="Label3"}
}
};
return masterPage;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
GC.Collect();
}
}

Ok, that was a bug in Xamarin.Forms Version 2.3.3.175. To fix this bug install an earlier version of Xamarin.Forms. I get my app running with version 2.3.0.107.
The bug in version 2.3.3.175 should be fixed in version 2.3.4-pre1.

Related

Custom renderer for Tabbed page in Android: Xamarin Forms

I am working on a Xamarin.Forms application. I have this tabbed page renderer in iOS:
public class TabbedPageRenderer : TabbedRenderer
{
private MainPage _page;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
_page = (MainPage)e.NewElement;
}
else
{
_page = (MainPage)e.OldElement;
}
try
{
var tabbarController = (UITabBarController)this.ViewController;
if (null != tabbarController)
{
tabbarController.ViewControllerSelected += OnTabBarReselected;
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private void OnTabBarReselected(object sender, UITabBarSelectionEventArgs e)
{
var tabs = Element as TabbedPage;
var playTab = tabs.Children[4];
if (TabBar.SelectedItem.Title == "Play")
{
if (tabs != null)
{
playTab.Title = "Pause";
playTab.Icon = "pause.png";
}
App.pauseCard = false;
}
else
{
if (tabs != null)
{
playTab.Title = "Play";
playTab.Icon = "play.png";
}
App.pauseCard = true;
}
}
}
This basically changes the icon on my Play tab to pause and play. This is working good in iOS. But I am struggling on how to have the same function (basically convert this to Android) in Android side.
Can any point me to the right direction? Basically help me? :-)
Note: I am pretty new with Android development.
EDIT: This is what it would look like in iOS.
Pause Mode:
Play Mode:
There is a blog post by Xamarin's James Montemagno which explains how to achieve this requirement.
Basically, it uses Custom Tab which inherits from TabbedPage which initialize an event UpdateIcons to be fired on Tab Current Page Changed event CurrentPageChanged
public class MyTabs : TabbedPage
{
//always save a reference to the current page
Page currentPage;
public MyTabs()
{
//create the pages and set the view models
//you could also do this in the page code behind
Children.Add(new TabIconsPage
{
BindingContext = new Tab1ViewModel
{
IsSelected = true
}
});
Children.Add(new TabIconsPage2
{
BindingContext = new Tab2ViewModel()
});
currentPage = Children[0];
//Register for page changes
this.CurrentPageChanged += Handle_CurrentPageChanged;
}
//Update the IsSelected state and trigger an Event that anyone can loop into.
public event EventHandler UpdateIcons;
void Handle_CurrentPageChanged(object sender, EventArgs e)
{
var currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = false;
currentPage = CurrentPage;
currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = true;
UpdateIcons?.Invoke(this, EventArgs.Empty);
}
}
Now Android needs a custom renderer to subscribe to the UpdateIcons event and perform icon changes
public class MyTabs : TabbedPage
{
//always save a reference to the current page
Page currentPage;
public MyTabs()
{
//create the pages and set the view models
//you could also do this in the page code behind
Children.Add(new TabIconsPage
{
BindingContext = new Tab1ViewModel
{
IsSelected = true
}
});
Children.Add(new TabIconsPage2
{
BindingContext = new Tab2ViewModel()
});
currentPage = Children[0];
//Register for page changes
this.CurrentPageChanged += Handle_CurrentPageChanged;
}
//Update the IsSelected state and trigger an Event that anyone can loop into.
public event EventHandler UpdateIcons;
void Handle_CurrentPageChanged(object sender, EventArgs e)
{
var currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = false;
currentPage = CurrentPage;
currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = true;
UpdateIcons?.Invoke(this, EventArgs.Empty);
}
}

Getting error "Java.Lang.IllegalStateException" with FirebaseDatabase app

I was following a tutorial online on how to create an android chat app with Xamarin that was implemented in Visual Studio 2015 and I was using Visual Studio 2017. I also tried to InitializeApp to see if that would fix it, but it did not work. What could be the problem? There was a couple of changes that I implemented, but I have one problem. I am getting an error "Java.Lang.IllegalStateException: " on line FirebaseDatabase.Instance.GetReference("chats").AddValueEventListener(this);
This is how I implented the OnCreate method:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
FirebaseApp.InitializeApp(this);
firebase = new FirebaseClient(FirebaseURL);
//firebase = new FirebaseClient(GetString(Resource.String.firebase_url)); //not working
FirebaseDatabase.Instance.GetReference("chats").AddValueEventListener(this);
fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
edtChat = FindViewById<EditText>(Resource.Id.input);
lstChat = FindViewById<ListView>(Resource.Id.list_of_messages);
fab.Click += delegate
{
PostMessage();
};
if (FirebaseAuth.Instance.CurrentUser == null)
{
StartActivityForResult(new Android.Content.Intent(this, typeof(Signin)), MyResultCode);
}
else
{
Toast.MakeText(this, "Welcome " + FirebaseAuth.Instance.CurrentUser.Email, ToastLength.Short).Show();
DisplayChatMessage();
}
}
private async void PostMessage()
{
var items = await firebase.Child("chats").PostAsync(new MessageContent(FirebaseAuth.Instance.CurrentUser.Email, edtChat.Text));
edtChat.Text = "";
}
public void OnCancelled(DatabaseError error)
{
}
public void OnDataChange(DataSnapshot snapshot)
{
DisplayChatMessage();
}
private async void DisplayChatMessage()
{
lstMessage.Clear();
var items = await firebase.Child("chats")
.OnceAsync<MessageContent>();
foreach (var item in items)
lstMessage.Add(item.Object);
ListViewAdapter adapter = new ListViewAdapter(this, lstMessage);
lstChat.Adapter = adapter;
}

Xamarin Forms Java.Lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY

I'm using Auth0 with Xamarin Forms PCL Library.
I have following MainPage class :
namespace LoginPattern
{
public class MainPage : MasterDetailPage
{
public MainPage ()
{
Master = new MenuPage ();
Detail = new DetailPage ();
}
}
}
And following in Application class
public App ()
{
Current = this;
Login ();
}
public void ShowMainPage ()
{
MainPage = new MainPage ();
}
public async void Login ()
{
await DependencyService.Get<IAuth0WidgetLogin>().LoginUseAuth0EmbeddedWidget();
App.Current.Properties["IsLoggedIn"] = true;
ShowMainPage ();
}
Hence upon login, I initially I'm not loading any page except the Auth0 Login Widget. Upon the successful login I would like to display the MasterDetailPage. But am getting the following error :
Java.Lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.
Please advise if I need to load the Widget in an NavigationPage and how to do so.
EDIT 17/7 :
public class MenuPage : ContentPage
{
MasterDetailPage master;
TableView tableView;
public MenuPage ()
{
Title = "LoginPattern";
Icon = "slideout.png";
var section = new TableSection () {
new TextCell {Text = "Sessions"},
new TextCell {Text = "Speakers"},
new TextCell {Text = "Favorites"},
new TextCell {Text = "Room Plan"},
new TextCell {Text = "Map"},
};
var root = new TableRoot () {section} ;
tableView = new TableView ()
{
Root = root,
Intent = TableIntent.Menu,
};
var logoutButton = new Button { Text = "Logout" };
logoutButton.Clicked += (sender, e) => {
App.Current.Logout();
};
Content = new StackLayout {
BackgroundColor = Color.Gray,
VerticalOptions = LayoutOptions.FillAndExpand,
Children = {
tableView,
logoutButton
}
};
}
}
public class DetailPage : ContentPage
{
public DetailPage ()
{
BackgroundColor = new Color (0, 0, 1, 0.2);
var text = "Slide > to see the master / menu";
if (Device.OS == TargetPlatform.Android) {
text = #"Click the action bar dots to see the master / menu";
} else if (Device.OS == TargetPlatform.WinPhone) {
text = #"Click button \/ to see the master / menu ";
}
Content = new StackLayout {
HorizontalOptions = LayoutOptions.Center,
Padding = new Thickness (10, 40, 10, 10),
Children = {
new Label { Text = text }
}
};
}
}
I would try doing two things:
Setting the MainPage of your Application to a blank page (or something like a splash page) before you attempt to display the authentication widget.
Setting an explicit width request on your MenuPage.
Just for assistance to others, following is my final solution :
public class MainPage : MasterDetailPage
{
public MainPage ()
{
Master = new MenuPage (this);
Detail = new DetailPage ();
ShowLoginDialog ();
}
async void ShowLoginDialog()
{
var page = new LoginPage();
await Navigation.PushModalAsync(page);
App.Current.Login ();
await Navigation.PopModalAsync();
}
}
PS: LoginPage is just an empty ContentPage.

Floating Action Button in Xamarin.Forms

I had completed my App's home page in Xamarin.Forms Portable.
Now i want to add a Flotation Action Button In my Android Project !
Is there any way to add FAB for Android in my existing home page, which was coded in Xamarin.Forms Portable.
OR
I want to create a separate home page for Android and add call it as a MainPage for android ?
Thanks and Regards.
Before the official support library came out I ported the FAB over.
There is now a Xamarin.Forms sample in my GitHub repo that you can use: https://github.com/jamesmontemagno/FloatingActionButton-for-Xamarin.Android
Build a Custom Control
For the FAB's properties to be bindable in Xamarin.Forms, we need a custom control with bindable properties.
public class FloatingActionButtonView : View
{
public static readonly BindableProperty ImageNameProperty = BindableProperty.Create<FloatingActionButtonView,string>( p => p.ImageName, string.Empty);
public string ImageName
{
get { return (string)GetValue (ImageNameProperty); }
set { SetValue (ImageNameProperty, value); }
}
public static readonly BindableProperty ColorNormalProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorNormal, Color.White);
public Color ColorNormal
{
get { return (Color)GetValue (ColorNormalProperty); }
set { SetValue (ColorNormalProperty, value); }
}
public static readonly BindableProperty ColorPressedProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorPressed, Color.White);
public Color ColorPressed
{
get { return (Color)GetValue (ColorPressedProperty); }
set { SetValue (ColorPressedProperty, value); }
}
public static readonly BindableProperty ColorRippleProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorRipple, Color.White);
public Color ColorRipple
{
get { return (Color)GetValue (ColorRippleProperty); }
set { SetValue (ColorRippleProperty, value); }
}
...
}
We will then map each property to a corresponding property on the native FAB control.
Attach a Renderer
If we want to use a native control in Xamarin.Forms, we need a renderer. For simplicity, lets use a ViewRenderer. This renderer will map our custom FloatingActionButtonView to an Android.Widget.FrameLayout.
public class FloatingActionButtonViewRenderer : ViewRenderer<FloatingActionButtonView, FrameLayout>
{
...
private readonly Android.Content.Context context;
private readonly FloatingActionButton fab;
public FloatingActionButtonViewRenderer()
{
context = Xamarin.Forms.Forms.Context;
fab = new FloatingActionButton(context);
...
}
protected override void OnElementChanged(ElementChangedEventArgs<FloatingActionButtonView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
return;
if (e.OldElement != null)
e.OldElement.PropertyChanged -= HandlePropertyChanged;
if (this.Element != null) {
//UpdateContent ();
this.Element.PropertyChanged += HandlePropertyChanged;
}
Element.Show = Show;
Element.Hide = Hide;
SetFabImage(Element.ImageName);
fab.ColorNormal = Element.ColorNormal.ToAndroid();
fab.ColorPressed = Element.ColorPressed.ToAndroid();
fab.ColorRipple = Element.ColorRipple.ToAndroid();
var frame = new FrameLayout(Forms.Context);
frame.RemoveAllViews();
frame.AddView(fab);
SetNativeControl (frame);
}
public void Show(bool animate = true)
{
fab.Show(animate);
}
public void Hide(bool animate = true)
{
fab.Hide(animate);
}
void HandlePropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "Content") {
Tracker.UpdateLayout ();
}
else if (e.PropertyName == FloatingActionButtonView.ColorNormalProperty.PropertyName)
{
fab.ColorNormal = Element.ColorNormal.ToAndroid();
}
else if (e.PropertyName == FloatingActionButtonView.ColorPressedProperty.PropertyName)
{
fab.ColorPressed = Element.ColorPressed.ToAndroid();
}
else if (e.PropertyName == FloatingActionButtonView.ColorRippleProperty.PropertyName)
{
fab.ColorRipple = Element.ColorRipple.ToAndroid();
}
...
}
void SetFabImage(string imageName)
{
if(!string.IsNullOrWhiteSpace(imageName))
{
try
{
var drawableNameWithoutExtension = Path.GetFileNameWithoutExtension(imageName);
var resources = context.Resources;
var imageResourceName = resources.GetIdentifier(drawableNameWithoutExtension, "drawable", context.PackageName);
fab.SetImageBitmap(Android.Graphics.BitmapFactory.DecodeResource(context.Resources, imageResourceName));
}
catch(Exception ex)
{
throw new FileNotFoundException("There was no Android Drawable by that name.", ex);
}
}
}
}
Pull it all Together
OK! We've built the custom control, and mapped it to a renderer. The last step is laying out the control in our view.
public class MainPage : ContentPage
{
public MainPage()
{
var fab = new FloatingActionButtonView() {
ImageName = "ic_add.png",
ColorNormal = Color.FromHex("ff3498db"),
ColorPressed = Color.Black,
ColorRipple = Color.FromHex("ff3498db")
};
// Main page layout
var pageLayout = new StackLayout {
Children =
{
new Label {
VerticalOptions = LayoutOptions.CenterAndExpand,
XAlign = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}};
var absolute = new AbsoluteLayout() {
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand };
// Position the pageLayout to fill the entire screen.
// Manage positioning of child elements on the page by editing the pageLayout.
AbsoluteLayout.SetLayoutFlags(pageLayout, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(pageLayout, new Rectangle(0f, 0f, 1f, 1f));
absolute.Children.Add(pageLayout);
// Overlay the FAB in the bottom-right corner
AbsoluteLayout.SetLayoutFlags(fab, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(fab, new Rectangle(1f, 1f, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
absolute.Children.Add(fab);
Content = absolute;
}
}
Complete code on Github : Floating Action Button Xamarin.Forms

Creating User Session in MonoDroid

I am developing and android application which required user to login. I am using Monodroid to develop this application. In my application there are bunch of activities that will be started as the user logs in. I have set up Login Activity as main launcher and when user is successfully logged in , user will be sent to main activity.
I some how want to save session for the user so that user do not need to login every time they start the application.
As monodroid is very new to me, i am not able to make that work. People recommended me using SharedPrefrencs to create session, but tried lot to make it work, application always crashed.
The reason for crashing is null value of user, when user is in mainactivity. As recommended by many users i create Main Activity as main laucher and check if user is logged in or not from there. But nothing worked for me.
I have included my whole code for Login Activity and Main Activity. I want to save "driverId" in prefrences and when ever app is relauched main activity will retrieve "driverId" from the prefrences.
Please some body who is familiar with monodroid enviroment can help me to fix this.
Login Activity Code
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Locations;
using RestSharp;
using TheNorthStar.Api.Requests;
using TheNorthStar.Api.Results;
using NorthStar.Driver.Application;
using Android.Preferences;
using Object = Java.Lang.Object;
namespace NorthStar.Driver
{
public class DriverLogonAsync : AsyncTask
{
private ProgressDialog processDialog;
private Context m_context;
private DriverLogon m_driver;
private bool _resterror;
public DriverLogonAsync( Context context, DriverLogon driver )
{
m_context = context;
m_driver = driver;
_resterror = false;
}
/*
* throws
* should separate out logic and use MyMessagebox..
*/
private void SetComfirmAlertBox(string carNum, DriverLogonResult result)
{
var api = new ConnectToSever(Helper.GetServer(m_context));
string resultOfCarDetail; CarDetails res;
try
{
resultOfCarDetail = api.ComfirmLogginOn(m_driver);
}
catch
{
Android.Util.Log.Info("EXC_conflogon1", "confirm logging on failed");
throw;
}
try
{
res = Newtonsoft.Json.JsonConvert.DeserializeObject<CarDetails>(resultOfCarDetail);
}
catch (Exception ex)
{
Android.Util.Log.Info("EXC_conflogon2", "deserialize confirm logging on failed\n" + ex.Message);
throw;
}
if (res.carExists != true)
{
MyMessageBox.SetAlertBox("Opps!!!!!!!!", "This Car Number Was Wrong!!!!", "OK", m_context);
}
else
{
string carType = res.carType;
string seatNum = res.numOfSeats.ToString();
// MainActivity act = new MainActivity( result.driverId );
var mact = new Intent(m_context,typeof(MainActivity) );
mact.PutExtra( "driverID", result.driverId.ToString() );
MyMessageBox.SetAlertBox("Comfirm!", "Your car is a: " + carType + " with " + seatNum + " seats??", "Yes", "No", mact,m_context);
}
}
/*private void ChangeDriverStatues()
{
}*/
protected override void OnPreExecute()
{
base.OnPreExecute();
processDialog = ProgressDialog.Show( m_context, "Driver Loging On...", "Please Wait...", true, true);
}
protected override Object DoInBackground(params Object[] #params)
{
var api = new ConnectToSever(Helper.GetServer(m_context));
string res = string.Empty;
try
{
res = api.DriverLogingOn(m_driver);
}
catch
{
_resterror = true;
Android.Util.Log.Info("EXC_dlogon1", "driver logon failed");
return -1;
}
return res;
}
protected override void OnPostExecute(Object result)
{
base.OnPostExecute(result);
//hide and kill the progress dialog
processDialog.Hide();
processDialog.Cancel();
if (_resterror == true)
{
Android.Util.Log.Info("EXC_dlogon2", "logon connection has failed, noop");
return;
}
DriverLogonResult resDriverDetail;
try
{
resDriverDetail = Newtonsoft.Json.JsonConvert.DeserializeObject<DriverLogonResult>(result.ToString());
}
catch (Exception ex)
{
Android.Util.Log.Info("EXC_dlogon3", "logon deser has failed, noop\n" + ex.Message);
return;
}
if (resDriverDetail.logonSuccess)
{
this.SetComfirmAlertBox( m_driver.carNum, resDriverDetail );
}
else
{
MyMessageBox.SetAlertBox("Wrong!", "Wrong username or password!!!", "OK!",m_context);
}
}
}
[Activity(Label = "MyDriver-Driver", MainLauncher = true, Icon = "#drawable/icon", NoHistory = true)]
public class Activity1 : Activity
{
private void CreateAlert()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.SetTitle("GPS is Off")
.SetMessage("You need GPS to you this application."+ "\n" +
"Do you want to go to settings menu?")
.SetPositiveButton("Setting",
(sender, e) =>
{
Intent intent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings);
StartActivity(intent);
this.Finish();
})
.SetNegativeButton("No", (sender, e) => this.Finish());
AlertDialog alert = builder.Create();
alert.Show();
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
Android.Util.Log.Info("EXC_logstart", "**************** starting driver module ****************");
Boolean isGPSEnabled = false;
Boolean isNetworkEnabled = false;
LocationManager _locationManager;
_locationManager = (LocationManager)GetSystemService(LocationService);
isGPSEnabled = _locationManager.IsProviderEnabled(LocationManager.GpsProvider);
// getting network status
isNetworkEnabled = _locationManager.IsProviderEnabled(LocationManager.NetworkProvider);
if (!isGPSEnabled && !isNetworkEnabled)
{
CreateAlert();
}
// Get our button from the layout resource,
// and attach an event to it
EditText eTextUsername = FindViewById<EditText>(Resource.Id.UserNameBox);
EditText eTextPassword = FindViewById<EditText>(Resource.Id.PasswordBox);
EditText eTextCarNum = FindViewById<EditText>(Resource.Id.CarNumBox);
Button viewPrefsBtn = FindViewById<Button>(Resource.Id.BtnViewPrefs);
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate
{
if (eTextCarNum.Text != "" && eTextPassword.Text != "" && eTextUsername.Text != "")
{
DriverLogon driver = new DriverLogon();
driver.userName = eTextUsername.Text;
driver.password = eTextPassword.Text;
driver.carNum = eTextCarNum.Text;
DriverLogonAsync asyDriver = new DriverLogonAsync(this, driver);
asyDriver.Execute();
}
};
viewPrefsBtn.Click += (sender, e) =>
{
StartActivity(typeof(PreferencesActivity));
};
}
}
}
So when user is successfully logged in "driverId" should be saved and can be retrived from main activity when re launching app.
Main Activity Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Android.Preferences;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using RestSharp;
using Android.Locations;
using TheNorthStar.Api.Requests;
using TheNorthStar.Api.Results;
using NorthStar.Driver.Application;
using System.Timers;
using AutoMapper;
using Object = Java.Lang.Object;
using Timer = System.Timers.Timer;
namespace NorthStar.Driver
{
[Activity(Label = "Home")]
public class MainActivity : Activity
{
string m_driverId;
string m_bookingId;
string m_address;
int i = 1;
private Timer _requestWorkTimer;
/*
* throws
*/
private void SetDriverStatues(string status)
{
m_driverId = Intent.GetStringExtra("driverID");
var api = new ConnectToSever(Helper.GetServer(ApplicationContext));
DriverLogon driver = new DriverLogon();
//Booking booking = RequestToSever();
driver.driverID = Int32.Parse(m_driverId);
driver.driverStatus = status;
try
{
api.SetDriverStatus(driver);
}
catch
{
Android.Util.Log.Info("EXC_setdstat1", "set driver status failed");
throw;
}
}
protected override void OnDestroy()
{
base.OnDestroy();
_requestWorkTimer.Stop();
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Mainpage);
//EditText messageBox = FindViewById<EditText>( Resource.Id.MessagesBox );
Button button = FindViewById<Button>(Resource.Id.LogOutButton);
m_driverId = Intent.GetStringExtra("driverID");
var service = new Intent(this, typeof(NorthStarBackgroundService));
service.PutExtra("driverId",m_driverId);
StartService(service);
ThreadPool.QueueUserWorkItem(state => SetDriverStatues("Available"));
// this.SetDriverStatues( "Available" );
_requestWorkTimer = new Timer(15000);
_requestWorkTimer.Elapsed += (sender, e) =>
{
ThreadPool.QueueUserWorkItem(x => RequestWork());
};
_requestWorkTimer.Start();
button.Click += (sender, args) =>
{
try
{
SetDriverStatues("Logoff");
}
catch
{
Android.Util.Log.Info("EXC_setdstat2", "set driver status failed");
return;
}
var mact = new Intent(this, typeof(Activity1));
mact.AddFlags(ActivityFlags.ClearTop);
StartActivity(mact);
};
}
private void CheckMessage()
{
/* if ( )
{
//timeout so return home
}
/* else
{
timerCount--;
RunOnUiThread(() => { jobTimerLabel.Text = string.Format("{0} seconds to respond", timerCount); });
}*/
}
protected override void OnResume()
{
base.OnResume();
_requestWorkTimer.Start();
}
private void CreateAlert()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.SetTitle("GPS is Off")
.SetMessage("Do you want to go to settings menu?")
.SetPositiveButton("Setting",
(sender, e) =>
{
Intent intent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings);
StartActivity(intent);
this.Finish();
})
.SetNegativeButton("No", (sender, e) => this.Finish());
AlertDialog alert = builder.Create();
alert.Show();
}
/*
* throws
*/
private void RequestWork()
{
_requestWorkTimer.Stop();
var api = new ConnectToSever(Helper.GetServer(ApplicationContext));
DriverMoreWorkRequest driver = new DriverMoreWorkRequest();
driver.driverID = Int32.Parse(m_driverId);
NorthStarBackgroundService n = new NorthStarBackgroundService();
driver.Lat = n.currentLattitude;
driver.Lng = n.currentLongtitude;
Object result; Booking booking;
try
{
result = api.RequestWork(driver);
}
catch
{
Android.Util.Log.Info("EXC_reqwork1", "request work failed");
throw;
}
try
{
booking = Newtonsoft.Json.JsonConvert.DeserializeObject<Booking>(result.ToString());
}
catch (Exception ex)
{
Android.Util.Log.Info("EXC_reqwork1", "deserialize request work failed\n" + ex.Message);
throw;
}
if (booking != null)
{
m_bookingId = booking.BookingId.ToString();
//string add = api.GetCustomerAddress(booking);
RunOnUiThread(() =>
{
var mact = new Intent(this, typeof(NewWorkAvailableActivity));
mact.PutExtra("driverID", m_driverId);
mact.PutExtra("bookingId", m_bookingId);
mact.PutExtra("fullAddress", booking.Address);
mact.PutExtra("jobLocation", booking.PickupSuburb);
mact.PutExtra("customerPhoneNumber", booking.PassengerPhoneNumber);
StartActivity(mact);
});
}
else
{
_requestWorkTimer.Start();
}
}
public object even { get; set; }
}
}
I'm exactly sure what you are trying to do here but to get driver ID from Shared Preferences try (from the login activity):
var prefs = GetSharedPreferences("MyApp",Android.Content.FileCreationMode.Private);
var driverID = 0;
if (prefs.Contains("DriverID"))
{
driverID = prefs.GetInt("DriverID", 0);
}
else
{
//Call the Async Task to get the Driver or whatever and when you've got it:
var prefsEdit = prefs.Edit();
prefsEdit.PutInt("DriverID", driver.ID);
prefsEdit.Commit();
driverID = prefs.GetInt("DriverID", 0);
}
var mact = new Intent(this, typeof(MainActivity))
.PutExtra("driverID", driverID);
StartActivity(mact);
Alternatively I would stick the whole Driver object in a sqlite db and get it back every time you come in but obviously I don't know your requirements.

Categories

Resources