I am trying to capture an image/pick up an image from gallery in Xamarin Forms app. I have installed the nuget manager > Birdie.MediaPlugin. During On click on the button in the Register page throws below error;
Plugin.Media.Abstractions.MediaPermissionException: <Timeout exceeded getting exception details Could someone please advise where should we add persmission in Xamarin.Forms app ?
// Register.xaml:
<Image x:Name="imageDisplay" />
<Button x:Name="uploadButton"
Text="Upload Image" Clicked="UploadButton_Clicked"/>
// PlayerDetails.cs
public ImageSource Source { get; internal set; }
//Register.xaml.cs
PlayerDetails myDetails;
public Register(PlayerDetails playD)
{
InitializeComponent();
BindingContext = myDetails;
}
private async void UploadButton_Clicked(object sender, EventArgs e)
{
//myDetails.Image = new Image();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
return;
}
var status = await GetPermissions();
if(status == true)
{
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "Sample",
Name = "flower1.jpg"
});
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
myDetails.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
else
{
await DisplayAlert("Permissions Denied", "Unable to take photos.", "OK");
//On iOS you may want to send your user to the settings screen.
if (Device.RuntimePlatform == Device.iOS)
CrossPermissions.Current.OpenAppSettings();
}
}
//I have split the permission function as below;
public static async Task<bool> GetPermissions()
{
bool permissionsGranted = true;
var permissionsStartList = new List<Permission>()
{
Permission.Location,
Permission.LocationAlways,
Permission.LocationWhenInUse,
Permission.Storage,
Permission.Camera
};
var permissionsNeededList = new List<Permission>();
try
{
foreach (var permission in permissionsStartList)
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
if (status != PermissionStatus.Granted)
{
permissionsNeededList.Add(permission);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Nice, exception! " + ex);
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(permissionsNeededList.ToArray());
try
{
foreach (var permission in permissionsNeededList)
{
var status = PermissionStatus.Unknown;
//Best practice to always check that the key exists
if (results.ContainsKey(permission))
status = results[permission];
if (status == PermissionStatus.Granted || status == PermissionStatus.Unknown)
{
permissionsGranted = true;
}
else
{
permissionsGranted = false;
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Last, exception! " + ex);
}
return permissionsGranted;
}
You can update your OnClick event code to add the permissions logic as well:
var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync<CameraPermission>();
var storageStatus = await CrossPermissions.Current.CheckPermissionStatusAsync<StoragePermission>();
if (cameraStatus != PermissionStatus.Granted || storageStatus != PermissionStatus.Granted)
{
cameraStatus = await CrossPermissions.Current.RequestPermissionAsync<CameraPermission>();
storageStatus = await CrossPermissions.Current.RequestPermissionAsync<StoragePermission>();
}
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
return;
}
if (cameraStatus == PermissionStatus.Granted && storageStatus == PermissionStatus.Granted)
{
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "Sample",
Name = "flower1.jpg"
});
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
myDetails.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
else
{
await DisplayAlert("Permissions Denied", "Unable to take photos.", "OK");
//On iOS you may want to send your user to the settings screen.
if (Device.RuntimePlatform == Device.iOS)
CrossPermissions.Current.OpenAppSettings();
}
Note:It will become a long function so I recommend breaking it up into different functions.
Related
Here is the code that works but it doesn't wait until the completion. How do I make sure the file has been saved?
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
ExecutablePath = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
Headless = false,
});
var page = (await browser.PagesAsync()).First();
page.Response += async (object sender, ResponseCreatedEventArgs e) =>
{
if (e.Response.Url.Contains(".mp4"))
{
byte[] buff = await e.Response.BufferAsync();
File.WriteAllBytes($"{DateTime.UtcNow.ToFileTime()}.mp4", buff);
}
};
await page.GoToAsync("https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_480_1_5MG.mp4");
await Task.Delay(30000);
Here, just wrote it:
public static async Task<FileInfo> DownloadFileAsync(string url)
{
try
{
await _page.GoToAsync(url);
}
catch (NavigationException)
{
// Trying to open a file page throws navigation exception, should be ignored
}
await _page.WaitForNetworkIdleAsync();
while (Directory.GetFiles(_downloadDirectory, "*.crdownload", SearchOption.AllDirectories).Length > 0)
{
await Task.Delay(250);
}
for (int i = 0; i < 100; i++)
{
var finishedFiles = (new DirectoryInfo(_downloadDirectory)).GetFiles();
var downloadedFile = finishedFiles.OrderByDescending(f => f.LastWriteTime).FirstOrDefault();
if (downloadedFile != null)
{
return downloadedFile!;
}
await Task.Delay(250);
}
throw new Exception($"Download failed for: {url}");
}
I am trying to capture a photo but the camera won't open on my device. Huawei P9 with the latest version of Android. I am also using the latest version of the package. The package is working on my other phone but not on my Huawei phone.
var cafNo = entCafNo.Text;
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", "No Camera Available", "Ok");
return;
}
try
{
var file = await CrossMedia.Current.TakePhotoAsync(
new StoreCameraMediaOptions
{
SaveToAlbum = false,
Name = cafNo + "_IMG_01.png",
CompressionQuality = 80,
PhotoSize = PhotoSize.Medium
}
);
entPhoto1Url.Text = file.Path;
if (entPhoto1Url.Text != null)
{
btnCamera1.IsEnabled = false;
btnCamera1.BackgroundColor = Color.FromHex("#27ae60");
photovideovalidator.IsVisible = false;
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
I have implemented SqlBotDataStore for bot storage but the LoadAsync method is silently failing. This is in the MessageController's POST. No exceptions are thrown anywhere, it just stops at this line, the chat bot continues as if nothing ever happened but storage does not work:
var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
var key = Address.FromActivity(activity);
try
{
var userData = await botDataStore.LoadAsync(key, BotStoreType.BotPrivateConversationData, CancellationToken.None);
userData.SetProperty<Translator>("translator", new Translator());
userData.SetProperty<bool>("autoDetectLanguage", true);
userData.SetProperty<bool>("autoTranslateToBot", true);
userData.SetProperty<bool>("autoTranslateToUser", true);
await botDataStore.SaveAsync(key, BotStoreType.BotPrivateConversationData, userData, CancellationToken.None);
}
catch (HttpException e)
{
Debug.WriteLine(e.Message);
}
I cannot seem to get past this and unfortunately don't have any more information because literally no error or anything happens here. When debugging it just never goes to the next line and continues execution silently.
Based on this github sample using Azure Sql Storage to store the bot state, I modify the sample with following updates and do a test, which work for me. You can compare the sample with your implementation to find differences.
In MessagesController:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
if (activity.Text == "savetest")
{
var message = activity as IMessageActivity;
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
var key = Address.FromActivity(activity);
try
{
var userData = await botDataStore.LoadAsync(key, BotStoreType.BotPrivateConversationData, CancellationToken.None);
//userData.SetProperty<Translator>("translator", new Translator());
userData.SetProperty<bool>("autoDetectLanguage", true);
userData.SetProperty<bool>("autoTranslateToBot", true);
userData.SetProperty<bool>("autoTranslateToUser", true);
await botDataStore.SaveAsync(key, BotStoreType.BotPrivateConversationData, userData, CancellationToken.None);
await botDataStore.FlushAsync(key, CancellationToken.None);
}
catch (HttpException e)
{
Debug.WriteLine(e.Message);
}
}
}
await Conversation.SendAsync(activity, () => new Dialogs.EchoDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
In EchoDialog:
var tval = context.PrivateConversationData.GetValueOrDefault<bool>("autoTranslateToBot", false);
await context.PostAsync("You said: " + message.Text + $"; autoTranslateToBot is {tval.ToString()}");
context.Wait(MessageReceivedAsync);
Test result:
I am building a windows phone mobile app with phonegap. I need to get some content from a particular page within the application...This is what I have for now:
function getXMLHTTPRequest() {
try {
req = new XMLHttpRequest();
} catch(err1) {
try {
req = new ActiveXObject('Msxml2.XMLHTTP');
} catch (err2) {
try {
req = new ActiveXObject('Microsoft.XMLHTTP');
} catch (err3) {
req = false;
}
}
}
return req;
}
var first_req = getXMLHTTPRequest();
var firsturl = '/books/Col.xml';
first_req.open('GET', firsturl, true);
first_req.onreadystatechange = createResponse;
first_req.send(null);
function createResponse()
{
if (first_req.readyState == 4) {
if(first_req.status == 200)
{
navigator.notification.alert(
'sucess',
doNot,
'success',
'Worked'
);
}
else {
navigator.notification.alert(
"request.status = "+first_req.status,
doNot,
'Error',
'Try Again'
);
}
it doesn't work, the else block runs and alerts request.status = 0
Any help would be really appreciated
I encounter a problem that when upload file size large than 100kb, web api controller will not be called. I search for a while and found that maybe I should set maxRequestLength in webconfig. But how to set it in self host?
the client
public async Task<bool> Upload(DeviceFile file,string path)
{
var formData = new MultipartFormDataContent();
var request = new HttpRequestMessage();
var md5 = new MD5CryptoServiceProvider();
var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,bufferSize:4096,useAsync:true);
fileStream.Position = 0;
var hash = md5.ComputeHash(fileStream);
fileStream.Position = 0;
formData.Add(
new StreamContent(fileStream),
file.Name,
file.Name,
new {
Info = file.Info,
}
);
request.Method = HttpMethod.Post;
request.Content = formData;
request.RequestUri = new Uri(client.BaseAddress,"api/file/");
try
{
var response = await client.SendAsync(request).ConfigureAwait(false);
await response.Content.ReadAsAsync<bool>().ConfigureAwait(false);
}
catch (Exception ex)
{
this.logger.Log(ex.ToString(), Category.Info, Priority.None);
}
return true;
}
the server controller
public async Task<HttpResponseMessage> Add()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var provider = new MultipartFormDataStreamProvider("D:/");
try
{
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
Console.WriteLine(file.Headers.ContentDisposition.FileName);
Console.WriteLine("Server file path: " + file.LocalFileName);
}
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
Console.WriteLine(string.Format("{0}: {1}", key, val));
}
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
The MaxReceivedMessageSize can be set on the self-host config object.
http://msdn.microsoft.com/en-us/library/system.web.http.selfhost.httpselfhostconfiguration.maxreceivedmessagesize(v=vs.108).aspx#feedback