Hosting Activity is getting destroyed as soon as permission dialog is appearing on fragment.
On click of Submit button of fragment:
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.RECEIVE_SMS)!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), "Please allow permission so we can retrieve the OTP.", Toast.LENGTH_SHORT).show();
requestPermissions(new String[]{android.Manifest.permission.RECEIVE_SMS}, 441);
}
I tried with ActivityCompat.requestPermissions still hosting activity is getting destroyed and showing permission dialog only.
Remove this line from AndroidManifest for that activity:
android:noHistory="true"
solved issue.
Related
Hello guys i make a xamarin.forms app. I need to ask the user to allow app use his location. This is my code:
var location = await Geolocation.GetLastKnownLocationAsync();
if (location == null)
{
location = await Geolocation.GetLocationAsync(new GeolocationRequest
{
DesiredAccuracy = GeolocationAccuracy.Medium,
Timeout = TimeSpan.FromSeconds(30)
}); ;
}
if (location == null)
LabelLocation.Text = " NO GPS LOCATION";
else
LabelLocation.Text = $"{location.Latitude} {location.Longitude}";
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu());
}
catch (FeatureNotEnabledException fneEx)
{
// Handle not enabled on device exception
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu());
}
catch (PermissionException pEx)
{
// Handle permission exception
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu());
}
catch (Exception ex)
{
// Unable to get location
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu());
}
when user click never show again , everytime open the page it goes on PermissionException which is ok. But i want to show again the permission dialog because without location can't show data. Is it possible to do this?
The short answer again is, no you can't. As you can see in the Requesting permissions documentation (when the user denies a permission and checks that no prompt should be shown from this moment forward):
Explain to the user that the feature is unavailable because the features requires a permission that the user has denied. At the same time, respect the user's decision. Don't link to system settings in an effort to convince the user to change their decision.
The best practice is to explain in detail to the user before you ask for the permission. If the user still decided to deny you this permission, then display a message describing that this particular logic simply won't work. It is against the best practices, but if you wish, you can redirect the user to Settings where the user can enable the permission. However, I strongly advise you not to do so.
One important side note, again from the documentation:
If the ContextCompat.checkSelfPermission() method returns PERMISSION_DENIED, call shouldShowRequestPermissionRationale(). If this method returns true, show an educational UI to the user. In this UI, describe why the feature, which the user wants to enable, needs a particular permission.
Also, use Xamarin.Essentials for permission checking. Everything is very well documented there.
P.S. I strongly suggest you read App permissions best practices where you will find other useful practices from the official Android team.
I would like to know if there is a way to find out if an app is launched because of a notification opened event.
Currently when a user taps on an incoming notification, OneSignal will resume/launch my application and it will call the handleNotificationOpened handler of the app where I can process the notification without any problems as well as redirect the user to specific page in my app based on the notification's payload.
The issue that I want to solve is that if my application is not running, then OneSignal will launch the app and it will show the default root page of my app for less than a second and then the user will be redirected to the proper page. What I would like to achieve is to prevent showing the app's root page and only show the notification handling page upon clicking on the notification, thus I need to know if there is a way to identify the fact that the app was launched because of a notification tap.
Does anybody have an idea on how to achieve this?
Thanks
As I wasn't able to find a way to check launch parameters or anything like that to verify that the application was launched for processing a notification tap I tried tackling the problem from another angle.
For anyone interested in a possible "workaround" I have posted a possible solution. Please do not assume this is a definite solution but rather treat it as a suggestion and by no means do not push this onto your production environment without exhaustive testing.
constructor (platform: Platform, private statusBar: StatusBar, private oneSignal: OneSignal) {
var isNotification = false;
platform.ready().then(() => {
this.statusBar.styleDefault();
setTimeout(() => {
if (! isNotification) {
this.rootPage = FirstRunPage;
}
},3000);
var iosSettings = {
kOSSettingsKeyAutoPrompt: false,
kOSSettingsKeyInAppLaunchURL: false
};
this.oneSignal.startInit('replace with Onesignal id');
this.oneSignal.inFocusDisplaying(this.oneSignal.OSInFocusDisplayOption.Notification);
this.oneSignal.iOSSettings(iosSettings);
this.oneSignal.handleNotificationOpened().subscribe((data) => {
isNotification = true;
this.nav.push("NotifyHandlerPage");
});
this.oneSignal.endInit();
});
}
I am successfuly able to login using Google but now I want to logout the user when he changes his Google account password.
I have tried the code below:
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
// If the user's cached credentials are valid, the OptionalPendingResult will be "done"
// and the GoogleSignInResult will be available instantly.
Log.d("TAG", "Got cached sign-in");
GoogleSignInResult result = opr.get();
} else {
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently. Cross-device
// single sign-on will occur in this branch.
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
#Override
public void onResult(GoogleSignInResult googleSignInResult) {
}
});
}
...but even after changing password and revoking access, I was able to silently login. I can't find anything else.
Can someone help me to detect if user has changed his password, so I can log him out?
I found an issue reported for the same.
https://github.com/googlesamples/google-services/issues/196
According to them it is expected behavior and you might need to explicitly call signOut or revokeAccess from your application to achieve that.
For both 'SendVerificationEmail()' and 'sendResetPasswordEmail()' - once the email that is sent is clicked, a new instance of the application is opened in another window. I don't want this to happen. I just want to continue from where the 'sends' originated. Any ideas?
I'm following the Facebook Auth tutorial on the Firebase website. You can see it here: https://www.firebase.com/docs/web/libraries/ionic/guide.html
$scope.login = function() {
Auth.$authWithOAuthRedirect("facebook").then(function(authData) {
// User successfully logged in
}).catch(function(error) {
if (error.code === "TRANSPORT_UNAVAILABLE") {
Auth.$authWithOAuthPopup("facebook").then(function(authData) {
// User successfully logged in. We can log to the console
// since we’re using a popup here
console.log(authData);
});
} else {
// Another error occurred
console.log(error);
}
});
};
My issue is that I am correctly receiving the TRANSPORT_UNAVAILABLE error and I am getting to the following line of code
Auth.$authWithOAuthPopup("facebook").then(function(authData) {
// do stuff with the authData
})
But, when I run on my device or in emulator, the popup window that is coming from the InAppBrowser Plugin closes immediately and doesn't allow me to enter any of my credentials.
EDIT
Two things to note. First, with the above code auth does not work when done via the browser. So, if I do ionic serve and try to login nothing happens except that I see the url change briefly to http://localhost:8100/#/login&__firebase_request_key=0wRrfF07Ojg1PmJXNX1OsvrRFR2Q1LGj
but then it goes back to http://localhost:8100/#/login
Secondly, when I build the project via Xocde and run on my device, the InAppBrowser plugin seems to no longer be closing right away but instead freezes with a white screen. The logs in Xcode show the following
THREAD WARNING: ['InAppBrowser'] took '79.103027' ms. Plugin should use a background thread.
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
webView:didFailLoadWithError - -1200: An SSL error has occurred and a secure connection to the server cannot be made.
EDIT 2
Looks like the above issues with SSL error was because of an unrelated bug with upgrading to ios 9. I've since corrected those issues and now I'm back to the original. Except now the InAppBrowser window doesn't even open, I'm still hitting the catch block with TRANSPORT_UNAVAILABLE.
Not sure exactly how I fixed this issue. Hard to isolate what was breaking originally and what was breaking due to ios 9 upgrades. But, I've been able to fix the issue. I started by blowing away the /ios and /android folders inside of /platforms. I also deleted all the plugins from the /plugins folder.
Then I added back ios and android platforms. Then I added back the plugins. Then I followed the steps found in these 2 blog posts modifying your app to be ios 9 compliment.
http://blog.ionic.io/ios-9-potential-breaking-change/
http://blog.ionic.io/preparing-for-ios-9/