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.
Related
Whenever I try to register a user through the app, it always fails even if the all the requirements are met. I included in the manifest but that didn't fix anything. The email/password sign-in method is also enabled.
I'm really lost as to what to do because this is my first time using xamarin and there seems to be more help when it comes to xamarin forms vs xamarin android.
public class registerActivity : AppCompatActivity
{
TextInputLayout fullNameText;
TextInputLayout phoneText;
TextInputLayout emailtext;
TextInputLayout passwordText;
Button registerButton;
FirebaseAuth firebaseAuth;
FirebaseDatabase userCredentials;
taskCompletetionListener taskCompletetionListener = new taskCompletetionListener();
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.registerPage);
Typeface tf = Typeface.CreateFromAsset(Assets, "Tw_Cen_MT.TTF");
var signUpTxt = FindViewById<TextView>(Resource.Id.signUpTxt);
signUpTxt.SetTypeface(tf, TypefaceStyle.Bold);
var signUpLink = FindViewById<TextView>(Resource.Id.signInLink);
signUpLink.SetTypeface(tf, TypefaceStyle.Bold);
var alreadyMemberTxt = FindViewById<TextView>(Resource.Id.haveAccTxt);
signUpTxt.SetTypeface(tf, TypefaceStyle.Bold);
Button signUpBtn = (Button)FindViewById(Resource.Id.registerBtn);
signUpBtn.SetTypeface(tf, TypefaceStyle.Bold);
InitializedFirebase();
firebaseAuth = FirebaseAuth.Instance;
ConnectControl();
}
void InitializedFirebase()
{
var app = FirebaseApp.InitializeApp(this);
if (app == null)
{
var options = new FirebaseOptions.Builder()
.SetApplicationId("semoto-4b53b")
.SetApiKey("AIzaSyBiGjJQwDewsyWxviBjIimw7pQBHkbHkiA")
.SetDatabaseUrl("https://semoto-4b53b.firebaseio.com")
.SetStorageBucket("semoto-4b53b.appspot.com")
.Build();
app = FirebaseApp.InitializeApp(this, options);
userCredentials = FirebaseDatabase.GetInstance(app);
}
else
{
userCredentials = FirebaseDatabase.GetInstance(app);
}
}
void ConnectControl()
{
fullNameText = (TextInputLayout)FindViewById(Resource.Id.nameField);
emailtext = (TextInputLayout)FindViewById(Resource.Id.emailField);
phoneText = (TextInputLayout)FindViewById(Resource.Id.phoneNumField);
passwordText = (TextInputLayout)FindViewById(Resource.Id.passwordField);
registerButton = (Button)FindViewById(Resource.Id.registerBtn);
registerButton.Click += RegisterButton_Click;
}
private void RegisterButton_Click(object sender, EventArgs e)
{
string fullName, phoneNum, email, password;
fullName = fullNameText.EditText.Text;
phoneNum = phoneText.EditText.Text;
email = emailtext.EditText.Text;
password = passwordText.EditText.Text;
if(fullName.Length <= 3)
{
fullNameText.ErrorEnabled = true;
fullNameText.Error = "Please enter a valid name";
return;
}
else if (!email.Contains("#"))
{
emailtext.ErrorEnabled = true;
emailtext.Error = "Please enter a valid email";
return;
}
else if(phoneNum.Length < 9)
{
phoneText.ErrorEnabled = true;
phoneText.Error = "Please enter a valid phone number";
return;
}
else if (password.Length < 8)
{
passwordText.ErrorEnabled = true;
passwordText.Error = "Password should be at least 8 characters long";
return;
}
registerUser(fullName, phoneNum, email, password);
}
void registerUser(string name, string phone, string email, string password)
{
taskCompletetionListener.success += TaskCompletetionListener_success;
taskCompletetionListener.failure += TaskCompletetionListener_failure;
firebaseAuth.CreateUserWithEmailAndPassword(email, password)
.AddOnSuccessListener(this, taskCompletetionListener)
.AddOnFailureListener(this, taskCompletetionListener);
}
private void TaskCompletetionListener_failure(object sender, EventArgs e)
{
Android.Support.V7.App.AlertDialog.Builder alert = new Android.Support.V7.App.AlertDialog.Builder(this);
alert.SetTitle("Registration Failed!");
alert.SetMessage("Ensure that you meet all of the requirements. ");
alert.SetNeutralButton("OK", delegate
{
alert.Dispose();
});
alert.Show();
}
//reishinishite kudasai
private void TaskCompletetionListener_success(object sender, EventArgs e)
{
Android.Support.V7.App.AlertDialog.Builder alert = new Android.Support.V7.App.AlertDialog.Builder(this);
alert.SetTitle("Registration Successful");
alert.SetMessage("Welcome!");
alert.SetNeutralButton("OK", delegate
{
alert.Dispose();
});
alert.Show();
}
}
}
I made a class for the task completion listener
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Gms.Tasks;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace Semoto.eventListeners
{
public class taskCompletetionListener : Java.Lang.Object, IOnSuccessListener, IOnFailureListener
{
public event EventHandler success;
public event EventHandler failure;
public void OnFailure(Java.Lang.Exception e)
{
failure?.Invoke(this, new EventArgs());
}
public void OnSuccess(Java.Lang.Object result)
{
success?.Invoke(this, new EventArgs());
}
}
}
This is not an answer,just to make it easier for you to troubleshoot.
First step you need to know what caused the failure.
Change your OnFailure listener like:
public void OnFailure(Java.Lang.Exception e)
{
failure?.Invoke(e, new EventArgs());
}
then in your activity,print the erro message,here use your Dialog to display:
private void TaskCompletetionListener_failure(object sender, EventArgs e)
{
Android.Support.V7.App.AlertDialog.Builder alert = new Android.Support.V7.App.AlertDialog.Builder(this);
alert.SetTitle("Registration Failed!");
alert.SetMessage(((Java.Lang.Exception)sender).Message);
alert.SetNeutralButton("OK", delegate
{
alert.Dispose();
});
alert.Show();
}
then you could show your error message that we can help you find a solution faster.(Ps:I use your code to test with my account,it works well).
I have a problem with the Facebook SDK. It works fine in Editor and in apk(if i check the development build option in Unity), but on release build it doesn't work.
Here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Facebook.Unity;
using UnityEngine.UI;
using Facebook.MiniJSON;
public class FBManager : MonoBehaviour {
[SerializeField]private Text FBErrorText;
public RawImage FBProfilePicture;
public Image DefaultAvatar;
public Text UsernameText;
public Text WelcomeMessage;
public Button FacebookButton;
private Color fbProfilePictureColor;
private Color defaultAvatarColor;
private string getData;
private string FBUserName;
void Awake()
{
if (!FB.IsInitialized)
{ FBErrorText.text = "fb not ini, initializing";
FB.Init(InitCallBack, OnHideUnity);
FBErrorText.text = "called fb.init";
}
else
{ FBErrorText.text += "initialized";
FB.ActivateApp();
FBErrorText.text += "called fb.activateApp";
}
fbProfilePictureColor = FBProfilePicture.color;
defaultAvatarColor = DefaultAvatar.color;
fbProfilePictureColor.a = 0f;
FBProfilePicture.color = fbProfilePictureColor;
}
void Start()
{
//StartCoroutine (FbLoginWait ());
}
IEnumerator FbLoginWait()
{
yield return new WaitUntil (()=> FB.IsInitialized);
FBLogin ();
}
//auto logare
private void InitCallBack()
{
if (FB.IsInitialized)
{
//UsernameText.text = "Initialized FB SDK";
FBErrorText.text = "fb is initialized";
FB.ActivateApp ();
FBErrorText.text = "fb activated app";
}
else
{
FBErrorText.text = "Failed to initialize the Facebook SDK";
Debug.Log ("Failed to initialize the Facebook SDK");
}
}
private void OnHideUnity(bool isGameShown)
{
if (!isGameShown)
{
Time.timeScale = 0;
}
else
{
Time.timeScale = 1;
}
}
private void HandleLoginFB(bool IsLogged)
{
if (IsLogged)
{
FBErrorText.text = "user logged in";
Debug.Log ("User logged in");
}
else
{
FBErrorText.text = "user cancelled login";
Debug.Log ("User cancelled login");
}
}
private void AuthCallback(IResult result)
{
FBErrorText.text = "called authcallback";
HandleLoginFB (FB.IsLoggedIn);
FBErrorText.text = "handling fb";
if (FB.IsLoggedIn)
{
var aToken = Facebook.Unity.AccessToken.CurrentAccessToken;
Debug.Log (aToken.UserId);
foreach (string perm in aToken.Permissions) {
Debug.Log (perm);
}
FB.API ("/me/picture?type=square&height=50&width=50", HttpMethod.GET, UpdateProfileImage);
FB.API ("me?fields=name", HttpMethod.GET, GetUsername);
FBErrorText.text = "fb is logged in";
}
else
{
FBErrorText.text = "fb is not logged in";
}
}
public void FBLogin()
{
FBErrorText.text = "called fblogin";
List<string> perms = new List<string> () { "public_profile, email", "user_friends" };
FBErrorText.text = "created perms";
FB.LogInWithReadPermissions (perms, AuthCallback);
FBErrorText.text = "ended fblogin";
}
private void UpdateProfileImage(IGraphResult result)
{
if(result.Texture != null)
{
FBProfilePicture.texture = result.Texture;
defaultAvatarColor.a = 0f;
fbProfilePictureColor.a = 255f;
DefaultAvatar.color = defaultAvatarColor;
FBProfilePicture.color = fbProfilePictureColor;
}
}
private void GetUsername(IGraphResult result)
{
FBUserName = result.ResultDictionary ["name"].ToString ();
UsernameText.text = FBUserName;
WelcomeMessage.text = FBUserName + "'s NET WORTH";
}
}
(or the same code here https://hastebin.com/osatiketij.cs)
The last error text on the screen which appears is : "created perms", so right before the FB.LogInWithReadPermissions method is called, no error text appears after that, but no login also.
Any idea what it might be ?
For everyone coming to this thread : how I manage to fix this was by using Android Studio to see with the Logcat why it doesn't work, and it was "missing" a class. For anyone coming here, I fixed it by adding "-keep class com.facebook.** {*;}" to my proguard-user file.
I had a Xamarin.Android app FB native login working few days back but now it's all broke. It works smooth on Genymotion but on devices, it takes so much time to show Facebook app authentication and worst of all, when it comes back, nothing happens. Page is still as it was before clicking on FB button.
Below is the code snippet:
Initialization:
[assembly: MetaData ("com.facebook.sdk.ApplicationId", Value = "#string/app_id")]
[assembly: MetaData ("com.facebook.sdk.ApplicationName", Value = "#string/app_name")]
internal TaskCompletionSource FacebookLoginTask = new TaskCompletionSource ();
Then in Oncreate:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
#region Fb Native Login
FacebookSdk.SdkInitialize (this.ApplicationContext);
callbackManager = CallbackManagerFactory.Create ();
FacebookLoginTask = new TaskCompletionSource<string> ();
var loginCallback = new FacebookCallback<LoginResult> {
HandleSuccess = loginResult => FacebookLoginTask.SetResult (loginResult.AccessToken.Token),
HandleCancel = FacebookLoginTask.SetCanceled,
HandleError = FacebookLoginTask.SetException
};
LoginManager.Instance.RegisterCallback (callbackManager, loginCallback);
#endregion
InitializeComponents ();
}
On FB Button Click:
private async void btnFB_Onclick (object sender, EventArgs e)
{
//TODO : Set permission in global values
if (AccessToken.CurrentAccessToken != null && !string.IsNullOrEmpty (AccessToken.CurrentAccessToken.Token)) {
//LoginManager.Instance.LogOut ();
LoginManager.Instance.LogInWithReadPermissions (this, new string[] {
"user_birthday",
"read_stream",
"email",
"user_location"
});
await GetAccessToken ();
} else {
LoginManager.Instance.LogInWithReadPermissions (this, new string[] {
"user_birthday",
"read_stream",
"email",
"user_location"
});
await GetAccessToken ();
}
And finally:
async Task GetAccessToken ()
{
try {
IsContainEmail = true;
string accessToken = string.Empty;
if (AccessToken.CurrentAccessToken != null && !string.IsNullOrEmpty (AccessToken.CurrentAccessToken.Token))
accessToken = AccessToken.CurrentAccessToken.Token;
else {
if (!ControllerHelper.IsOnline (this))
return;
ActivityView = ProgressDialog.Show (this, "Please wait", "Authenticating...", true);
accessToken = await FacebookLoginTask.Task;
//It does not fallback here
Console.WriteLine (accessToken);
try {
FacebookClient fb = new FacebookClient (accessToken);
var me = await fb.GetTaskAsync ("me");
var result = (IDictionary<string, object>)me;
Console.WriteLine (result.ToString ());
if (!result.ContainsKey ("email") || string.IsNullOrEmpty ((string)result ["email"])) {
IsContainEmail = false;
}
if (IsContainEmail) {
await CreateFBRegistration (result);
}
ActivityView.Dismiss ();
ActivityView.Dispose ();
} catch (Exception e) {
IsContainEmail = false;
Console.WriteLine (e.Message);
ActivityView.Dismiss ();
ActivityView.Dispose ();
}
}
} catch (Exception ex) {
ActivityView.Dismiss ();
ActivityView.Dispose ();
Console.WriteLine (ex.Message);
}
}
It got stuck at await FacebookLoginTask.Task; Although I got callback hit:
//Must include to trigger the callback
protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult (requestCode, resultCode, data);
callbackManager.OnActivityResult (requestCode, (int)resultCode, data);
}
Don't know whats wrong. It was working few days back. Any suggestions??
We have a xamarin android app that contains a httplistener that serves up html, js, css and json calls, to a single page app running in a full screen webview. As of Xamarin 3.5 onwards the webview fails to retrieve this localhost address which we run on port 31316. Prior to this release this was functioning correctly.
From what i can see, the httplistener seems healthy, as we can call it with the WebRequest library correctly, which leads me tb believe that something has changed to the webview.
Any assistance would be greatly appreciated.
Below is a sample app demonstrating the behaviour:
using System;
using System.Net;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Webkit;
using Android.Widget;
using System.IO;
using System.Text;
namespace HttpListenerTest
{
[Activity (Label = "HttpListenerTest", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
StartService(new Intent(this, typeof(HttpListenerTestService)));
var webView = (WebView)this.FindViewById<WebView>(Resource.Id.webview);
webView.Settings.AllowFileAccess = true;
webView.Settings.BlockNetworkLoads = false;
webView.LoadUrl("http://localhost:31316/");
//webView.LoadData (Activities.html, "text/html", "UTF-8");
var button = FindViewById<Button>(Resource.Id.button1);
button.Click += delegate
{
AlertDialog.Builder alert1;
alert1 = new AlertDialog.Builder(this);
try
{
if(!Activities.httpListener.IsListening)
{
alert1.SetMessage("Listener has stopped listening");
alert1.Show();
return;
}
string url = "http://localhost:31316/" + DateTime.Now.ToString("O");
var request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.Method = "GET";
string responseString = "";
using (WebResponse response = request.GetResponse())
{
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
responseString = reader.ReadToEnd();
response.Close();
reader.Close();
}
alert1.SetMessage(responseString);
}
catch (Exception e)
{
alert1.SetMessage(e.Message + " " + e.StackTrace);
}
alert1.Show();
};
}
}
[Service(Label = "HttpListenerTest Service")]
public class HttpListenerTestService : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
base.OnCreate();
Activities.InitRest();
}
public override void OnDestroy()
{
}
public override void OnStart(Intent intent, int startId)
{
base.OnStart(intent, startId);
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}
}
public static class Activities
{
public static HttpListener httpListener { get; set; }
public static Thread RestThread { get; set; }
public const string html = "<html>hello world</html>";
public static void InitRest()
{
RestThread = new Thread(StartRest) { Name = "Rest Service" };
RestThread.Start();
}
private static void StartRest()
{
httpListener = new HttpListener { IgnoreWriteExceptions = true };
httpListener.Prefixes.Add(#"http://localhost:31316/");
httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
httpListener.Start();
httpListener.BeginGetContext(HandleRequest, httpListener);
}
public static void HandleRequest(IAsyncResult result)
{
Console.WriteLine ("==========================HandleRequest==========================");
var context = httpListener.EndGetContext(result);
var unescapedUrl = Uri.UnescapeDataString(context.Request.RawUrl);
var bytes = new byte[html.Length * sizeof(char)];
Buffer.BlockCopy(html.ToCharArray(), 0, bytes, 0, bytes.Length);
context.Response.ContentLength64 = bytes.Length;
context.Response.OutputStream.Write(bytes, 0, bytes.Length);
context.Response.ContentType = "text/html";
//context.Response.ContentEncoding = "UTF-8";
context.Response.OutputStream.Close();
context.Response.OutputStream.Dispose();
context.Response.StatusCode = 200;
httpListener.BeginGetContext(HandleRequest, httpListener);
}
}
}
I am developing android application which requires user to Login. This application relies on web server to verify the user details so that user can logged in. My problem starts here, there is no problem for logging in user, but when ever user press home button and goes back to the app, login screen is displayed which is very bad.
I have heard of SharedPrefrences but i don't know how can i save user details using this, so that user can directly move to main activity.
I have included my source code here. If anybody familiar with SharedPrefrences can help me to solve this. Example with my cod will be helpful.
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")]
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));
};
}
}
}
public void savePrefrences(String key, String value)
{
SharedPreferences prefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), 0);
prefs.edit().putString(key, value).commit();
}
public String getPrefrences(String key)
{
SharedPreferences prefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), 0);
return prefs.getString(key, "");
}
This way your info will be available from anywhere in the app even after you close and reopen it.
On your login screen - when a user does a successful login call savePrefrences("hasLoggenInPref", "true");
Now, whenever the user reenters the login screen - call getPrefrences("hasLoggenInPref") and check if its equals "true", if so, jump to your main screen, if not, show the login screen.
You should probably call the getPrefrences function from a splash screen or something and if it returns true open your app, and if not, open the login screen.
When a user logs out just call savePrefrences("hasLoggenInPref", "false");
Hope this helps.
Not sure about monodroid, but generally in your application all Activities which requare authorization must be subclassed from one activity which checks in onResume that the user has valid session (You store flag about successfully login or session id after login in memory, for instance in your Application class or any appropriate singleton). Then
if check failed - return user to login screen
if successfull - do nothing, just show them activity what he wants
To avoid problem with activity stack (pressing home button returns to login screen) and remove LoginActivity from it use android:noHistory="true" inside your manifest or related property via Intent