I tried to make my device vibrating using the Windows.Devices.Haptics class.
Unfortunately it does not return any vibration device. The value is always null, although my device has a vibrator.
I tried it with:
Windows.Devices.Haptics.VibrationAccessStatus vibState = await Windows.Devices.Haptics.VibrationDevice.RequestAccessAsync();
if (vibState == Windows.Devices.Haptics.VibrationAccessStatus.Allowed)
{
Windows.Devices.Haptics.VibrationDevice vibrator = await Windows.Devices.Haptics.VibrationDevice.GetDefaultAsync();
}
The code enters the if sequence, as the access status is allowed, but vibrator is null.
I also tried with:
Windows.Devices.Haptics.VibrationAccessStatus vibState = await Windows.Devices.Haptics.VibrationDevice.RequestAccessAsync();
if (vibState == Windows.Devices.Haptics.VibrationAccessStatus.Allowed)
{
IReadOnlyList<Windows.Devices.Haptics.VibrationDevice> devs = await Windows.Devices.Haptics.VibrationDevice.FindAllAsync();
}
as I thougth, there is no default vibrator requesting by GetDefaultAsync, but the list is empty.
I thought, there is a permission rule to enable the vibrator, but I tried with some of them without success. I also read some post and all of them say, there should be no permission rule allowed in the manifest.
So I don't know what's the problem.
Related
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
}
}
}
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.
I have an app where I want to select a person from contacts and then send a text to that person. It works as expected for the first user, but after that the app never receives control after the contact is selected. I've isolated the problem to the Nativescript-phone plugin. If you simply call phone.sms() to send a text, and then call contacts.getContact(), the problem occurs. I see this on both Android and iOS.
I've created a sample app that demos the problem at https://github.com/dlcole/contactTester. The sample app is Android only. I've spent a couple days on this and welcome any insights.
Edit 4/21/2020:
I've spent more time on this and can see what's happening. Both plugins have the same event handler and same request codes:
nativescript-phone:
var SEND_SMS = 1001;
activity.onActivityResult = function(requestCode, resultCode, data) {
nativescript-contacts:
var PICK_CONTACT = 1001;
appModule.android.on("activityResult", function(eventData) {
What happens is that after invoking phone.sms, calling contacts.getContact causes control to return to the phone plugin, and NOT the contacts plugin. I tried changing phone's request code to 1002 but had the same results.
So, the next step is to determine how to avoid the collision of the event handlers.
Instead of using activityResult event, nativescript-phone plugin overwrites the default activity result callback.
A workaround is to set the callback to it's original value after you are done with nativescript-phone.
exports.sendText = function (args) {
console.log("entering sendText");
const activity = appModule.android.foregroundActivity || appModule.android.startActivity;
const onActivityResult = activity.onActivityResult;
permissions.requestPermissions([android.Manifest.permission.CALL_PHONE],
"Permission needed to send text")
.then(() => {
console.log("permission granted");
phone.sms()
.then((result) => {
console.log(JSON.stringify(result, null, 4));
activity.onActivityResult = onActivityResult;
})
})
}
I am making an app in xamarin forms of which I will have a login similar to that of whatapp web, an on-screen qr that will be scanned by the phone, in the emulator with visual studio 2017 I have no problems, but when I export the app to an apk and the I install on a mobile device, the app reads the qr and returns to the previous login screen, not showing any reaction, which should be to go to the next screen where I have a dashboard.
What can be? I enclose my code used.
btnScanQRCode.IsEnabled = false;
var scan = new ZXingScannerPage();
scan.OnScanResult += (result) =>
{
scan.IsScanning = false;
Device.BeginInvokeOnMainThread(async () =>
{
await Application.Current.MainPage.Navigation.PopAsync();
var resultado = JsonConvert.DeserializeObject<QrCode>(result.Text);
JObject qrObject = JObject.Parse(JsonConvert.SerializeObject(resultado));
JsonSchema schema = JsonSchema.Parse(SettingHelper.SchemaJson);
bool valid = qrObject.IsValid(schema);
if (valid == true)
{
App.Database.InsertQrCode(resultado);
QrCode qr = App.Database.GetQrCode();
await _viewModel.Login();
await Navigation.PushAsync(new Organization());
}
else
{
await DisplayAlert("False", JsonConvert.SerializeObject(resultado), "ok");
}
});
};
await Application.Current.MainPage.Navigation.PushAsync(scan);
btnScanQRCode.IsEnabled = true;
This was originally a comment, but through the writing i realized this is the answer.
You need to debug your code. Attach a device and deploy the app in Debug config. Step through your code and see where it fails.
It sounds like it's crashing silently and probably on the line where you Deserialize result.Text in a QrCode. result.Text is just a string and will never deserialize into an object. You probably need a constructor that takes a string like QrCode(result.Text).
First scan then use the result to do other things in your app.
var scanner = new ZXing.Mobile.MobileBarcodeScanner();
var result = await scanner.Scan();
Check for proper camera permissions. I bet your problem is there.
I'm opening a file via:
await Windows.System.Launcher.LaunchFileAsync(storageFile, options);
The documentation for LaunchFileAsync says:
When the launch fails for any of the above reasons, the API succeeds
and returns FALSE from its asynchronous operation. Since it has no
ability to query whether the above restrictions apply to the current
launch, the calling app should not assume that the launch succeeded,
and should provide fallback mechanism in case it failed. A possible
solution would be to ask the user to save the file and direct the user
to open it in the desktop.
What's the most straightforward way to do that?
I tried:
var picker = new FolderPicker();
var pfolder = await picker.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.Add(pfolder);
var folder = await StorageFolder.GetFolderFromPathAsync(pfolder.Path);
var file = await folder.CreateFileAsync(storageFile.Name);
using (var writer = await file.OpenStreamForWriteAsync())
{
await writer.WriteAsync(storageFile,0,0);
}
But unfortuantely writer.WriteAsync only takes Bytes[] and not the StorageFile. How do I get my StorageFile saved?