Xamarin.Forms android check whether user clicked Deny and Don't ask again - xamarin

In my xamarin.forms app. I am using xamarin.Essentials to check and request permissions. I can check whether a permission is granted or not in android. The problem I am facing is when user clicks "Deny and Don't ask again" the status still shows Denied. How can we know whether user selected Deny and Dont ask so that I can show a warning message according to that. Any help is appreciated.

For check and request permission in Xamarin.Forms you could also use the plugin Permission.Plugin from nuget .
The option Deny and Don't ask again will only appear when you deny the request the second time . However , there is no such a specific status to tag it .
As a workaround , we could define a custom property to save the time that we deny .
int DenyCount = 0;
private async void FabOnClick(object sender, EventArgs eventArgs)
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync<LocationPermission>();
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
//await DisplayAlert("Need location", "Gunna need that location", "OK");
DenyCount++;
if(DenyCount>=2)
{
//...
}
}
status = await CrossPermissions.Current.RequestPermissionAsync<LocationPermission>();
}
if (status == PermissionStatus.Granted)
{
//Query permission
DenyCount = 0; // reset the value of DenyCount
}
else if (status == PermissionStatus.Restricted)
{
//location denied
}
}

Xamarin.Essentials provides a method for detecting whether the user has clicked to "don't ask again". You can check if a dialog should be shown by calling ShouldShowRationale:
var canAskAgain = Xamarin.Essentials.Permissions.ShouldShowRationale<Permission_Type>();
var didCheckDontAskAgain = !canAskAgain;
If this is true, that means the user did not click "Deny and Don't Ask Again".
Also, note that on Android 12 (and maybe 11, not sure), if you click "Deny" mulitple times, Android assumes that you mean "Don't ask again". The user may never explicitly check that option, but it may be inferred by Android.

Related

Deluge- how to prevent a user who is already signed in from signing in again

I have written a simple deluge script for a Sign In app.
Is there a way to prevent a user who is already signed in from signing in again?
Likewise, is there a way to prevent a user who is already signed out from signing out again?
What I have below populates the Staus with either Sign In or Sign Out but the user can manually override this is and sign In/Out twice
var = Sign_in_out[UserName == input.UserName] sort by Added_Time Desc;
if(var.Status == "Sign In")
{
Status.select("Sign Out");
}
else if(var.Status == "Sign Out")
{
Status.select("Sign In");
}
else
{
Status.select("Sign In");
}
In Zoho-Creator, the login state of a user can be checked with either zoho.loginuser or zoho.loginuserid. If either of these is null then the user is logged out. If they are not-null, then the user is logged in.
Deluge probably has the same behavior in other Zoho tools, but give it a try in-order to verify the behavior.
Example:
if (zoho.loginuserid == null)
{
info "Login-Status: Signed-Out:[" + zoho.loginuserid + "]";
}
else
{
info "Login-Status: Signed-In:[" + zoho.loginuserid + "]";
}
10-26-2022, Additional note after comments:
Try automatically refreshing the page. Here is a few example methods. These methods should work for Pages, Forms and Reports.
Example:
// Refresh a page using a full path url
openUrl("https://<zoho-url-path/#Page:<page-name>", "same window");
// Refresh a form with Zoho short path
openUrl("#Form:<login-form-name>", "same window");

Camera and location permission at runtime in Xamarin forms

I have created a Xamarin forms application and it requires two permission i.e i)Location and ii)Camera.
I need to get both permissions at runtime but unfortunately I am able to get only one permission at a time when app starts.
Is there any solution to request both permission simultaneously at runtime.
It's a good advice not to ask for permissions when the application starts, just because the user might not know what is it for.
Also check and ask for permission when you need it. For example, ask for Camera permission just before opening the camera.
You can do all this using Xamarin.Essentials. If your project does not have it, follow the documentation instructions to set it up.
And then you can do everything in your shared code (for all platforms!)
There are tons of examples, I will write one. You can ask for the permissions one after the other, or in two different moments
public async void GoToCameraPage()
{
var status = await Permissions.CheckStatusAsync<Permissions.Camera>();
if (status == PermissionStatus.Granted)
{
//We have permission!
await Navigation.PushAsync(new CameraPage());
}
else
{
//Let the user know why
await DisplayAlert("Permission needed", "I will need Camera permission for this action", "Ok");
//Ask for the permission
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
if (status == PermissionStatus.Granted)
{
//YES, now we have permission
}
else
{
//Ok, maybe I will ask again
}
}
}

Cannot navigate to page which was called once before

Short intro into my application's-logic:
My application is using a REST-Api and needs a token for all requests but a specific one (let's call it "pairing-page").
Before I navigate to any of my pages I'm checking the target location. If my target is the page where I'm requesting the token, no checking for a existing token is made.
For every other page a token is necessary. If no token exists the user should navigate back to the "pairing-page".
My start-Page is my paring-page.
What's the problem?:
When starting the app (pairing-page) and getting the token and navigating to the 2nd page - let's call it "overview" - everything is ok. The overview has a button which calls a method that removes my token and navigates back to the pairing-page. That's working as well.
Now the interesting part:
When I try to pair & navigate to the overview again (2nd time), no navigation is done. By this I mean my overview is not popping up.
I'm using Xamarin's Shell Navigation and overriding the OnNavigating-Method.
Code:
protected override void OnNavigating(ShellNavigatingEventArgs args)
{
// check if BearerToken exist. If so, navigate to Overview
if (args.Target.Location.ToString() != "//Admission.Event.Pair"
&& args.Target.Location.ToString() != "Admission.Event.Pair")
{
App app = App.Current as App;
string bearerToken = RestServiceCalls.GetBearerToken(app._dependencyService);
// if a the token is missing call the Pairing-Page
if (string.IsNullOrEmpty(bearerToken)
|| string.IsNullOrWhiteSpace(bearerToken))
{
Device.BeginInvokeOnMainThread(async () => { await NavigateToPageAsync("Admission.Event.Pair"); });
return;
}
}
base.OnNavigating(args);
}
async Task NavigateToPageAsync(object pageName, bool animate = true)
{
await Xamarin.Forms.Shell.Current.GoToAsync($"{pageName.ToString()}", animate);
Xamarin.Forms.Shell.Current.FlyoutIsPresented = false;
}
Let's take a look into the args:
Application start, pairing-page:
args.Target.Location: //Admission.Event.Pair
args.Current.Location: null
The Pairing-Page is popping up, everything is ok.
Click on the Button which processes getting a token and after that navigating to the overview:
args.Target.Location: Admission.Event
args.Current.Location: //Admission.Event.Pair
The overview page is popping up, everything is ok. Got a valid token as well.
Click on Button which processes removing the token and navigating to the pairing-page:
args.Target.Location: Admission.Event.Pair
args.Current.Location: //Admission.Event.Pair/Admission.Event
The token is removed correctly (is null) and the pairing-page pops up. Everything is ok.
Now the problem occurs:
When I'm now trying to get a token and navigate to the overview again my args have this content and my overview wont show up:
args.Target.Location: Admission.Event
args.Current.Location: //Admission.Event.Pair/Admission.Event/Admission.Event.Pair
Any idea about that?
My first thought was it might be an issue with the target-location.
Like I said in my comment:
For me I could simple use:
if(shell != null){
INavigation navigation = shell.Navigation;
navigation.PopToRootAsync();
}

Logout Display alert xamarin.forms

I've been trying to allow a user to confirm logout by using DisplayAlert. If they click "No" it should remain in their profile page else they should be redirected back to the login page. I haven't managed to get this done, if I click Yes or No, both options remain in the profile page
public async void LogoutBtn(object sender, EventArgs e)
{
var answer = await DisplayAlert("Exit", "Do you wan't to exit the App?", "Yes", "No");
if(answer.Equals("Yes"))
{
Settings.FirstName = string.Empty;
Settings.LastName = string.Empty;
Settings.Email = string.Empty;
await Navigation.PushAsync(new MainPage());
}
else
{
App.Current.MainPage = new Profile();
}
}
DisplayAlert returns a boolean (true / false):
var answer = await DisplayAlert("Exit", "Do you wan't to exit the App?", "Yes", "No");
if (answer)
{
// User choose Yes
}
else
{
// User choose No
}
As SushiHangover point out DisplayAlert returns a bool. You should replace it with DisplayActionSheet or stay with it and correct the if.
Your else clause seems to be incorrect.
If the user choose No you should do nothing. Why do you assign a new Profile to the MainPage?
Beside that, it seems that you have problems with navigation in general. Looking at your code, logout will push a page on a top of the executing page. Seems a bit weird. I would recommend to get familiar wit the Navigation topic firs of all:
Official doc
There is a free course on Xamarin University on Navigation

How to show different pages when app launches time in windows phone 7?

When app launches time need to show the registration page.once user registered it shouldn't goes to registration page need to go log in page.
How to achieve this?
You can navigate to the start page of a Windows Phone app from code.
Remove the "DefaultTask" entry from the WMAppManifest
Remove the NavigationPage attribute from the "DefaultTask" in WMAppManifest, and in the Launching event of your app use the something like the example below to navigate to the page of choice upon launch.
private void Application_Launching(object sender, LaunchingEventArgs e)
{
if (registered)
{
((App)Application.Current).RootFrame.Navigate(new Uri("/<your start page>.xaml", UriKind.Relative));
}
else
{
((App)Application.Current).RootFrame.Navigate(new Uri("/<your registration page>.xaml", UriKind.Relative));
}
}
You just have to decide how you want to determine that someone already registered.
I guess you haven't put a lot of thought to this, the setup is pretty easy! When a user registers you could set a variable in the settings defining that a user already has registered. When the application starts, evaluate this setting and if the user registered you show the register-page, otherwise the login-page. Example:
//After (succesful) registration
Properties.Settings.Default.HasRegistered = true;
Properties.Settings.Default.Save();
//Check the value
var hasRegistered = Properties.Settings.Default.HasRegistered;
if(hasRegistered)
//show Login
else
//show Registration
You can also use the IsolatedStorageSettings.ApplcationSettings to do this. The code below is just sample code, you'll have to provide validation if the settings already exist on the first startup of the app and set a default value 'false' for the setting if no registration has occured yet.
//After registration
var settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains("HasRegistered"))
settings["HasRegistered"] = true;
settings.Save();
//Check value
var settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains("HasRegistered"))
{
var registered = bool.Parse(settings["HasRegistered"]);
if(registered)
//show login
else
//show registration
}
Hope this helps!

Resources