Unable to Select files from Xmarin.Essentials.FilePicker . All files are disable - xamarin

When try to pick up the file all files are showing as disable. I am unable select the files. I am using below code.
var options = new PickOptions
{
PickerTitle = "Please select a pdf file",
FileTypes = FilePickerFileType.Pdf
};
var fileResult = await FilePicker.PickAsync(options);
var file = await Constants.ValidateFileNew(fileResult);
if (file.IsValid )
{
var fileName = file.FileName;
var data = file.fileData;
Stream stream = new MemoryStream(data);
fileID += 1;
ListNursingAssessmentFileNames.Add(new FileEntity { FileName = fileName, FileID = fileID, File = data });
DependencyService.Get<IJsonFileService>().SaveToLibrary<ObservableCollection<FileEntity>>(ListNursingAssessmentFileNames, "NursingInitialAssessmentFiles.json");
stackDigitalForm.IsVisible = false;
}
I have provide exteral storage permission.
Storage Permission SS

You need specify custom files types when creating the PickOptions and they can be customized per platform.
Per docs,PickOptions.FileTypes has many types in each platform,
On Android and iOS the files not matching this list is only displayed grayed out. When the array is null or empty, all file types can be selected while picking. The contents of this array is platform specific; every platform has its own way to specify the file types. On Android you can specify one or more MIME types, e.g. "image/png"; also wild card characters can be used, e.g. "image/*". On iOS you can specify UTType constants, e.g. UTType.Image. On UWP, specify a list of extensions, like this: ".jpg", ".png".
You can refer to the following sample code:
I add a button to trigger the selection event,
private void PickFileButton_Clicked(object sender, EventArgs e)
{
Task<FileResult> results = PickAndShow();
}
//for custom types
async Task<FileResult> PickAndShow()
{
var customFileType = new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
{
{ DevicePlatform.iOS, new[] { "com.adobe.pdf", "UTType.Image" } }, // or general UTType values
{ DevicePlatform.Android, new[] { "application/pdf", "image/*" } },
{ DevicePlatform.UWP, new[] { ".pdf", ".jpg", ".png" } },
{ DevicePlatform.Tizen, new[] { "*/*" , ".png" } },
{ DevicePlatform.macOS, new[] { "pdf" , "public.image" } },
});
try
{
var result = await FilePicker.PickAsync(new PickOptions
{
PickerTitle = "Please select files",
FileTypes = customFileType,
});
if (result != null)
{
FileName.Text = $"File Name: {result.FileName}";
if (result.FileName.EndsWith("jpg", StringComparison.OrdinalIgnoreCase) ||
result.FileName.EndsWith("png", StringComparison.OrdinalIgnoreCase))
{
var stream = await result.OpenReadAsync();
FileImage.Source = ImageSource.FromStream(() => stream);
}
}
return result;
}
catch (Exception ex)
{
// The user canceled or something went wrong
}
return null;
}
Note:Don't forget to add WRITE_EXTERNAL_STORAGE and RAED_EXTERNAL_STORAGEin your manifest file.
Official reference docs:
https://learn.microsoft.com/en-us/xamarin/essentials/file-picker?context=xamarin%2Fxamarin-forms&tabs=android

Related

Change DisplayImage while playing Mp3 file using CrossMediaManager in Xamarin forms IOS

I am trying to change the Display Image while playing mp3 file using CrossMediaManager, but It seems it doesn't change the image. It does change the title, id and so on, but I don't know why it can't change the display image.
async Task ExecutePlayChapterCommand()
{
if (IsBusy) return;
IsBusy = true;
try
{
await Task.Delay(TimeSpan.FromMilliseconds(10));
var reciter = Reciters.FirstOrDefault();
Device.BeginInvokeOnMainThread(async() => {
var mediaItem = await CrossMediaManager.Current.Play(reciter.DownloadURL);
CrossMediaManager.Current.Queue.Current.IsMetadataExtracted = false;
mediaItem.Title = reciter.Name;
var image = new Image() { Source = ImageSource.FromUri(new Uri(reciter.ImagePath)) };
CrossMediaManager.Current.Queue.Current.Title = string.Format("{0} - {1} ({2})", "1", "ChName", "English");
CrossMediaManager.Current.Queue.Current.Album = reciter.Name;
CrossMediaManager.Current.Queue.Current.Artist = reciter.Name;
CrossMediaManager.Current.Queue.Current.AlbumImage = image;
CrossMediaManager.Current.Queue.Current.AlbumImageUri = reciter.ImagePath;
CrossMediaManager.Current.Queue.Current.DisplayImage = image;
CrossMediaManager.Current.Queue.Current.DisplayImageUri = reciter.ImagePath;
CrossMediaManager.Current.Queue.Current.Image = image;
CrossMediaManager.Current.Queue.Current.ImageUri = reciter.ImagePath;
CrossMediaManager.Current.Notification.UpdateNotification();
});
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
finally { IsBusy = false; }
}
}
A sample project is uploaded in here
This answer might be a little bit late, but it worked for me perfectly.
First, the "Image, DisplayImage" properties of the media items are objects, that contain native representations of the cover image (UIImage and Bitmap) in the platform specific projects, so do not assign them any value.
Create your media item like this, without assigning the properties mentioned above.
new MediaItem(chapter.MediaUrl)
{
ImageUri = item.ImageUrl,
DisplayImageUri = item.ImageUrl,
AlbumImageUri = item.ImageUrl,
DisplayTitle = item.Title,
Title = item.Title,
Artist = item.Author,
Author = item.Author,
};
Then, on iOS, after setting the Queue items of the media items, in the platform specific project, create a method that takes the media item. This method will be called from the shared project.
Here is the method.
public void SetMediaImages(IMediaManager mediaManager)
{
if (mediaManager.Queue != null && mediaManager.Queue.Any())
{
foreach (var mediaItem in mediaManager.Queue)
{
if (!string.IsNullOrEmpty(mediaItem.ImageUri))
{
mediaItem.Image = UIImage.LoadFromData(NSData.FromUrl(new NSUrl(mediaItem.ImageUri)));
mediaItem.AlbumImage = mediaItem.Image;
}
}
}
}
Call this method in your shared project using Xamarin.Form's dependency service.

Xamarin Forms File Picker not showing camera roll or image gallery on ios

I"m using the xamarin.plugin.filepicker nuget in a Xamarin Forms project. The picker does not show the user's camera roll or local image gallery on iOS
It only shows 'Icloud Drive' and 'Recently Deleted' folder locations instead. I need to show the camera roll location if possible
private async void PickImage_Clicked(object sender, EventArgs args)
{
string[] fileTypes = null;
if (Device.RuntimePlatform == Device.Android)
{
fileTypes = new string[] { "image/png", "image/jpeg" };
}
if (Device.RuntimePlatform == Device.iOS)
{
fileTypes = new string[] { "public.image" }; // same as iOS constant UTType.Image
}
if (Device.RuntimePlatform == Device.UWP)
{
fileTypes = new string[] { ".jpg", ".png" };
}
if (Device.RuntimePlatform == Device.WPF)
{
fileTypes = new string[] { "JPEG files (*.jpg)|*.jpg", "PNG files (*.png)|*.png" };
}
await PickAndShowFile(fileTypes);
}
private async Task PickAndShowFile(string[] fileTypes)
{
try
{
var pickedFile = await CrossFilePicker.Current.PickFile(fileTypes);
if (pickedFile != null)
{
FileNameLabel.Text = pickedFile.FileName;
FilePathLabel.Text = pickedFile.FilePath;
if (pickedFile.FileName.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
|| pickedFile.FileName.EndsWith("png", StringComparison.OrdinalIgnoreCase))
{
FileImagePreview.Source = ImageSource.FromStream(() => pickedFile.GetStream());
chosenImageBytes = GetImageStreamAsBytes(pickedFile.GetStream());
FileImagePreview.IsVisible = true;
}
else
{
FileImagePreview.IsVisible = false;
}
}
}
catch (Exception ex)
{
FileNameLabel.Text = ex.ToString();
FilePathLabel.Text = string.Empty;
FileImagePreview.IsVisible = false;
}
}
You should use Xamarin Media Plugin for that purpose.

How to select multiple picture from gallery using GMImagePicker in xamarin IOS?

I am following this blog for selecting multiple pictures from the gallery. For IOS I am Using GMImagePicker for selecting multiple pictures from the gallery.(In the blog suggesting elcimagepicker, but that is not available in Nuget Store now)
I go through the GMImagePicker usage part but didn't find how to add the selected images to List and pass that value in MessagingCenter(like the android implementation). In that usage part only telling about the picker settings. Anyone please give me any sample code for doing this feature?
Hi Lucas Zhang - MSFT, I tried your code but one question. Here you are passing only one file path through the messagecenter, so should I use a List for sending multiple file paths?
I am passing the picture paths as a string List from android. Please have a look at the android part code added below. Should I do like this in IOS?
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
Android.Net.Uri uri = item.Uri;
var path = GetRealPathFromURI(uri);
if (path != null)
{
//Rotate Image
var imageRotated = ImageHelpers.RotateImage(path);
var newPath = ImageHelpers.SaveFile("TmpPictures", imageRotated, System.DateTime.Now.ToString("yyyyMMddHHmmssfff"));
images.Add(newPath);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetRealPathFromURI(uri);
if (path != null)
{
//Rotate Image
var imageRotated = ImageHelpers.RotateImage(path);
var newPath = ImageHelpers.SaveFile("TmpPictures", imageRotated, System.DateTime.Now.ToString("yyyyMMddHHmmssfff"));
images.Add(newPath);
}
}
MessagingCenter.Send<App, List<string>>((App)Xamarin.Forms.Application.Current, "ImagesSelected", images);
}
}
}
Also, I am getting an error, screenshot adding below:
GMImagePicker will return a list contains PHAsset .So you could firstly get the filePath of the images and then pass them to forms by using MessagingCenter and DependencyService.Refer the following code.
in Forms, create an interface
using System;
namespace app1
{
public interface ISelectMultiImage
{
void SelectedImage();
}
}
in iOS project
using System;
using Xamarin.Forms;
using UIKit;
using GMImagePicker;
using Photos;
using Foundation;
[assembly:Dependency(typeof(SelectMultiImageImplementation))]
namespace xxx.iOS
{
public class SelectMultiImageImplementation:ISelectMultiImage
{
public SelectMultiImageImplementation()
{
}
string Save(UIImage image, string name)
{
var documentsDirectory = Environment.GetFolderPath
(Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, name); // hardcoded filename, overwritten each time
NSData imgData = image.AsJPEG();
if (imgData.Save(jpgFilename, false, out NSError err))
{
return jpgFilename;
}
else
{
Console.WriteLine("NOT saved as " + jpgFilename + " because" + err.LocalizedDescription);
return null;
}
}
public void SelectedImage()
{
var picker = new GMImagePickerController();
picker.FinishedPickingAssets += (s, args) => {
PHAsset[] assets = args.Assets;
foreach (PHAsset asset in assets)
{
PHImageManager.DefaultManager.RequestImageData(asset, null, (NSData data, NSString dataUti, UIImageOrientation orientation, NSDictionary info) =>
{
NSUrl url = NSUrl.FromString(info.ValueForKey(new NSString("PHImageFileURLKey")).ToString());
string[] strs = url.Split("/");
UIImage image = UIImage.LoadFromData(data);
string file = Save(UIImage.LoadFromData(data), strs[strs.Length - 1]);
MessagingCenter.Send<Object, string>(this, "ImagesSelected", file);
}
);
}
};
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(picker, true,null);
}
}
}
in your contentPages
...
List<string> selectedImages;
...
public MyPage()
{
selectedImages = new List<string>();
InitializeComponent();
MessagingCenter.Subscribe<Object,string>(this, "ImagesSelected",(object arg1,string arg2) =>
{
string source = arg2;
selectedImages.Add(source);
});
}
If you want to select the images ,call the method
DependencyService.Get<ISelectMultiImage>().SelectedImage();

Is there any plugin or way to show 'new version of app available' alert when user opens app

I have Xamarin.Android app, I want to show alert to user (when user opens app) that please download latest version. Like other apps. How can I do that?
I have tried few ways but didn't get succeed. I have tried this. This is quite different from Android. I need it for Xamarin.
I already asked this question but existing functionality broke down due to having some changes in play store policies, consequently I am not getting specific string "itemprop=\"softwareVersion\">" from play store so I asked new question. Thank you
Working answer. I have used plugin for that Plugin.LatestVersion for Xam.Android to get latest version of app from Google play store. below line of code was returning latest app version.
var appStoreVersionString = await CrossLatestVersion.Current.GetLatestVersionNumber();
Then this is the further implementation
private void CompareVersion()
{
double currentVersion = 0d;
double appStoreversion = 0d;
bool IsUpdateRequired = false;
if (Context.PackageName != null)
{
PackageInfo info = Context.PackageManager.GetPackageInfo(Context.PackageName, PackageInfoFlags.Activities);
string currentVersionStrig = info.VersionName;
currentVersion = Convert.ToDouble(currentVersionStrig);
}
try
{
if (IsUpdateRequired == false)
{
string appStoreVersionString = string.Empty;
if (CheckNetConnection.IsNetConnected())
{
Task.Run(async () => { appStoreVersionString = await CrossLatestVersion.Current.GetLatestVersionNumber();}).Wait();
if (!string.IsNullOrEmpty(appStoreVersionString))
{
appStoreversion = Convert.ToDouble(appStoreVersionString);
if ((appStoreversion.ToString() != currentVersion.ToString() && (appStoreversion > currentVersion)))
{
IsUpdateRequired = true;
}
}
}
}
if (IsUpdateRequired)
{
Activity.RunOnUiThread(() =>
{
AlertDialog dialog = null;
var Alertdialog = new Android.App.AlertDialog.Builder(Context);
Alertdialog.SetTitle("Update Available");
Alertdialog.SetMessage($"A new version of [" + appStoreversion + "] is available. Please update to version [" + appStoreversion + "] now.");
Alertdialog.SetNegativeButton("Cancel", (sender, e) =>
{
if (dialog == null)
{
dialog = Alertdialog.Create();
}
dialog.Dismiss();
});
Alertdialog.SetPositiveButton("Update", (sender, e) =>
{
string appPackage = string.Empty;
try
{
appPackage = Application.Context.PackageName;
Utilities.Logout(Activity);
var ints = new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=" + appPackage));
ints.SetFlags(ActivityFlags.ClearTop);
ints.SetFlags(ActivityFlags.NoAnimation);
ints.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(ints);
}
catch (ActivityNotFoundException)
{
var apppack = Application.Context.PackageName;
Utilities.Logout(Activity);
var ints = new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=" + appPackage));
ints.SetFlags(ActivityFlags.ClearTop);
ints.SetFlags(ActivityFlags.NoAnimation);
ints.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(ints);
}
//this kills the app?
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
System.Environment.Exit(1);
});
if (dialog == null)
dialog = Alertdialog.Create();
dialog.Show();
});
}
}
catch (Exception ex)
{
var objLog = new LogService();
objLog.MobileLog(ex, SISConst.UserName);
}
}

How to share contact data of my app with whtsapp in .vcf /vcard format using xamarin forms

I have an application that creates a .vcf file after you input data. it stores storage provided by the phone, I want to click on a list view item and get the vcf file and share it via Email, SMS, WhatsApp, Skype etc how do I implement this in IOS and Android.
Thank you
I have got the answer of creating .vcf file which is given below. and for share that file follow this link : https://github.com/adamped/ShareDialog
private void Share_Clicked(object sender, EventArgs e)
{
try
{
var _btn = sender as Button;
var record = _btn.BindingContext as Contact;
int tempcontactID = record.ContactID;
if (record.CardFrontImage == null)
{
record.CardImage = record.CardBackImage;
}
else
{
record.CardImage = record.CardFrontImage;
}
string baseimage = Convert.ToBase64String(record.CardImage);
var vcf = new StringBuilder(); //vcf code start
vcf.AppendLine("BEGIN:VCARD");
vcf.AppendLine("VERSION:3.0");
vcf.AppendLine($"N:{record.ContactName};{string.Empty}; ;;");
vcf.AppendLine($"FN:{record.ContactName}");
vcf.AppendLine($"ORG:{record.CompanyName}");
vcf.AppendLine($"TITLE:{record.Designation}");
vcf.AppendLine($"PHOTO;ENCODING=BASE64;TYPE=PNG:{baseimage}");
vcf.AppendLine($"TEL;TYPE=work,voice;VALUE=uri:tel:{record.PhoneNumber}");
vcf.AppendLine("END:VCARD");
string fileName = Path.Combine("/storage/emulated/0/Android/data/com.Gamma.GammaNetworkingApp/files/", record.ContactID + record.ContactName + ".vcf");
using (var writer = new StreamWriter(fileName))
{
writer.Write(vcf.ToString());
}
string text = File.ReadAllText(fileName);
bool doesExist = File.Exists(fileName);
if (doesExist == true)
{
var share = DependencyService.Get<IShare>();
share.Show("Contact share", record.ContactName, fileName);
}
}
catch (Exception ex)
{
string test = ex.ToString();
Navigation.PushAsync(new HomePage());
}
}

Resources