I am developing a xamarin forms application which access device camera and gallery to take pictures. I am using the following code
CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
SaveToAlbum = true,
Name = string.Format(TDJGolfConstants.ProfileImageName, Guid.NewGuid()),
//AllowCropping = true,
//CompressionQuality = 60,
PhotoSize= PhotoSize.Medium,
But it is not asking the user for permission , and directly opens the camera and gallery. Is there anything to add for asking permisision?
I use CrossPermissions from the PermissionsPlugin for this
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Camera))
{
await UserNotificationService.Current.Show("Camera required", "justification");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Camera);
Related
I am using the CrossGeolocator.Current.StartListeningAsync method in my xamarin app to be able to listen to location updates in background for iOS.
I am using essentials to request permissions.
On first run we get location permission (in app only) and location using essentials and then we use StartListeningAsync for ios to be able to track location if the app is in background or foreground.
When the callback is hit we get a popup saying this app uses background location and gives you the option to use it or change back to use in app only option. On selection of any option the callback never completes and subsequent code isnt run.
Here is the popup I get after I have permission for when in use and then start listening:
Popup on ios
On subsequent runs once permissions are set manually the callback works.
Xamarin Forms Version: 5.0.0.1931
Xamarin Essential Version: 1.6.1
Geolocator Plugin Version: 4.6.2-beta
Code example:
private async Task StartListening()
{
if (CrossGeolocator.Current.IsListening)
return;
try
{
var settings = new ListenerSettings
{
ActivityType = ActivityType.Other,
DeferLocationUpdates = true,
DeferralDistanceMeters = 15,
DeferralTime = TimeSpan.FromSeconds(10),
ListenForSignificantChanges = false,
PauseLocationUpdatesAutomatically = false,
AllowBackgroundUpdates = true,
};
await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(15), 5, true, settings);
CrossGeolocator.Current.PositionChanged += PositionChanged;
CrossGeolocator.Current.PositionError += PositionError;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
You need to make sure the permission is ok before starting to listen to location updates. Have a try with following code:
public async Task GetLocationAsync()
{
var status = await CheckAndRequestPermissionAsync(new Permissions.LocationAlways());
if (status != PermissionStatus.Granted)
{
// Notify user permission was denied
return;
}else{
await StartListening();
}
}
public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
where T : BasePermission
{
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
I am using a camera on button click, but when user press the button second time the application get crashed. This is only happening on Ipad, its working smoothly on Iphone and android phones. I am using below code to initiate the camera.
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await App.Current.MainPage.DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Small,
DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Rear,
Directory = "Sample",
Name = "test.jpg"
});
if (file == null)
return;
var lStream = file.GetStream();
i have xamarin forms app that support notification, i have done it in android with broadcast receiver now i have to do notification in ios ! , my service is depending on API REST so i want every 60 second ios app run HTTP request and get data then show it as notification, i searched for many days but i can't reach to my approach ?
if this is impossible can i use nuget or something like that in ios project only "in xamarin forms solution " or not ?
content = new UNMutableNotificationContent();
content.Title = "Notification Title";
content.Subtitle = "Notification Subtitle";
content.Body = "This is the message body of the notification.";
content.Badge = 1;
content.CategoryIdentifier = "message";
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(60, true);
var requestID = "sampleRequest";
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
// Do something with error...
}
});
Here is my code for generating a local notification on iOS
var alertsAllowed = false;
UNUserNotificationCenter.Current.GetNotificationSettings((settings) =>
{
alertsAllowed = (settings.AlertSetting == UNNotificationSetting.Enabled);
});
if (alertsAllowed)
{
var content = new UNMutableNotificationContent();
content.Title = "Incident Recorder";
content.Subtitle = "Not Synchronised";
content.Body = "There are one or more new incidents that have not been synchronised to the server.";
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(5, false);
var requestID = "sampleRequest";
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
Console.WriteLine(err.LocalizedFailureReason);
}
});
}
The first parameter in CreateTrigger is how long before the notification is generated. I notice you have 60 in yours. Also bear in mind a notification will not appear if your app is foregrounded.
On the App.xaml.cs I have the following code
private async void OnCommandsRequested(SettingsPane settingsPane, SettingsPaneCommandsRequestedEventArgs e)
{
var loader = ResourceLoader.GetForCurrentView();
var generalCommand = new SettingsCommand("General Settings", "General Settings", handler =>
{
var generalSettings = new GeneralSettingsFlyout();
generalSettings.Show();
});
e.Request.ApplicationCommands.Add(generalCommand);
object data;
IAuthService _authService = new AuthService();
if (Global.UserId == 0)
data = await _authService.GetSettingValueBySettingName(DatabaseType.GeneralDb, ApplicationConstants.GeneralDbSettingNames.ShowSupportInfo);
else
data = await _authService.GetSettingValueBySettingName(DatabaseType.UserDb, ApplicationConstants.UserDbSettingNames.ShowSupportInfo);
if (data != null && data.ToString().Equals("1"))
{
var supportCommand = new SettingsCommand("Support", "Support", handler =>
{
var supportPane = new SupportFlyout();
supportPane.Show();
});
e.Request.ApplicationCommands.Add(supportCommand);
}
var aboutCommand = new SettingsCommand("About", loader.GetString("Settings_OptionLabels_About"), handler =>
{
var aboutPane = new About();
aboutPane.Show();
});
e.Request.ApplicationCommands.Add(aboutCommand);
}
This code adds the setting "General Settings" but neither "Support" or "About" commands. Can anyone advice what's wrong with this code?
Instead of querying the commands from your service when they are requested you'll need to query them ahead of time and then add the already known commands.
You cannot use await in OnCommandsRequested.
A method returns when it gets to the first await, so only commands added to the request before the await will be used.
Since the SettingsPaneCommandsRequestedEventArgs doesn't provide a deferral there is no way to tell the requester to wait for internal async calls to complete.
Note also that SettingsPane is deprecated and not recommended for new app development for Windows 10.
i am uploading my image by using plugins.media but the problem is it redirect to another photoimage page and upload it there.
var profiletap = new TapGestureRecognizer();
profiletap.Tapped += async (s, e) =>
{
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
ImageSource im = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
await Navigation.PushModalAsync(new PhotoPage(im));
};
profile.GestureRecognizers.Add(profiletap);
ant here is photopage content
public class PhotoPage : demopage
{
public PhotoPage(ImageSource img)
{
Content = new Image
{
VerticalOptions =LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Source =img
};
}
}
Instead of doing
await Navigation.PushModalAsync(new PhotoPage(im));
you can do something like
var img = new Image
{
Source =im
};
then add the new img control to the same container as where the "profile" control has already been added (probably some Stacklayout or Grid or some other layout control like that)
Be aware that you are struggling with the most basic concept of building out your app UI, which is a strong indicator you should read some getting started tutorials for xamarin.forms and really understand how the UI is built.