Xam.Plugin.Media wont work on Huawei devices - xamarin

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);
}

Related

Xamarin Forms throws Plugin.Media.Abstractions.MediaPermissionException while taking photo

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.

Get image stream from TakePhotoAsync()

I am getting an image stream from TakePhotoAsync Method? Where do I need to change the code?
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Alert", "No camera is available!", "OK");
return;
}
camreaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Small,
//SaveToAlbum = true,
Directory = "Sample",
Name = "test.jpg"
});
//mediaFile = await CrossMedia.Current.TakePhotoAsync();
if (camreaFile == null)
return;
fileName.Text = camreaFile.AlbumPath;
await DisplayAlert("File Location", camreaFile.Path, "OK");
image.Source = ImageSource.FromStream(() =>
{
var stream = camreaFile.GetStream();
//camreaFile.Dispose();
return stream;
});
--Pass parameter for server
if(mediaFile !=null)
{
MultipartFormDataContent content = new
MultipartFormDataContent();
content.Add(new StringContent(AppSetting.UserName),
"userId");
content.Add(new StringContent(remark), "remarks");
content.Add(new StringContent(AppSetting.ConsignmentNumebr), "consignmentNo");
content.Add(new StringContent(AppSetting.TaskId), "jobId");
content.Add(new StreamContent(cameraFile.GetStream()),"\"file\"",$"\"{AppSetting.ConsignmentNumebr + ".png"}\"");
var httpClient = new HttpClient();
var uploadServiceBaseAddress = "myserver/api/UploadContainerImage/"; var uploadResponseMessage = await httpClient.PostAsync(uploadServiceBaseAddress, content);uploadResponseMessage.Content.ReadAsStringAsync(); }
--I expect the output that successfully reaches the server.
Dispose of the Media file after you send it to the server to avoid this exception.
If you do that before you are sending it to the server, of course, it will give you an ObjectDisposedException
If you want to dispose of this variable just do it after the service call something like below:
FooServiceMethod();
mediaFile.Dispose();

File Image size increases while uploading to firebase through expo image picker react native using XMLHttpRequest

I am facing a very strange issue that my Image size increases while uploading to firebase.
I have logged the file size before uploading, it is showing the same size but after uploading the file size gets increased. Also the image is not corrupted. Please help..
Uploading to firebase code :
async uploadImageAsync(uri, passedParameter, ItemName) {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(xhr.response);
};
xhr.onerror = function(e) {
console.log(e);
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", uri, true);
xhr.send(null);
});
const ref = firebase
.storage()
.ref()
.child("CategoryDescription" + "/" + passedParameter + "/" + ItemName);
const snapshot = await ref.put(blob);
blob.close();
const downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
}
**Pick Image code : **
async _pickImage() {
const { CAMERA, CAMERA_ROLL } = Permissions;
const permissions = {
[CAMERA]: await Permissions.askAsync(CAMERA),
[CAMERA_ROLL]: await Permissions.askAsync(CAMERA_ROLL)
};
if (
permissions[CAMERA].status === "granted" &&
permissions[CAMERA_ROLL].status === "granted"
) {
var pickerResult = await ImagePicker.launchImageLibraryAsync({
quality: 0.1
});
if (!pickerResult.cancelled) {
console.log(pickerResult);
this.setState({
itemImage: pickerResult.uri
});
** On button pressed code**
handleConfirmAddItems = () => {
var passedParameter = this.params.item.key;
const { ItemName, ItemPrice, ItemDesc, ItemWeight, itemImage } = this.state;
{
itemImage !== "" &&
this._handleImagePicked(itemImage, passedParameter, ItemName);
}
writeUrlToDB(
itemImage,
passedParameter,
ItemName,
ItemDesc,
ItemPrice,
ItemWeight
);
}
};
** handle image picked **
async _handleImagePicked(itemImage, passedParameter, ItemName) {
try {
const uploadUrl = await this.uploadImageAsync(
itemImage,
passedParameter,
ItemName
);
this.setState({ itemImage: uploadUrl });
console.log("itemIma", uploadUrl);
} catch (e) {
console.log(e);
alert("Upload failed, sorry :(");
}
}
Please help.. I am in great stress
A bug in Image picker.. This is the issue in the case of iOS Simulator, in Android device its working fine : )

How to set directory of Xam.Plugin.Media to external storage in Xamarin Forms

I added the Xam.Plugin.Media to capture image. The problem is I want to save the picture to my SD Card if there is a SD Card and if not stick to the internal storage. How can I check if there is an sd card present? and if so, how can I get the directory?
My code below is the function to capture the image
try
{
var cafNo = entCafNo.Text;
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", "No Camera Available", "Ok");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(
new StoreCameraMediaOptions
{
SaveToAlbum = true,
Name = cafNo + "_IMG_01.png",
CompressionQuality = 80,
PhotoSize = PhotoSize.Medium,
DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Front
}
);
entPhoto1Url.Text = file.Path;
}
catch (Exception ex)
{
Console.Write(ex.Message);
}

Ajax request to pages within a windows phone app

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

Resources