Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How to await for Share.RequestAsync is completed?

Hello,

Is there any way to check if share dialog (from Xamarin.Essentials) is already closed?

await Share.RequestAsync(new ShareFileRequest()
{
 Title = title,
 File = new ShareFile(path)
});

tokenSource.Cancel();

I would like to cancel token after share dialog is closed, not just after it is open.

Is it possible without any custom platform share implementation?

Thanks in advance for any help!

Best Answer

  • RadoslawKubasRadoslawKubas USMember ✭✭
    Accepted Answer

    OK, I think I created solution myself, on Android little more complicated, not optimized, but seems to work fine. Solution below in case anyone need it. If someone can propose better solution or upgrade this on it will be great.

    public class FormsAppCompatActivityEx : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            public event Action<int, Result, Intent> ActivityResult;
    
            protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
            {
                ActivityResult?.Invoke(requestCode, resultCode, data);
            }
        }
    

    and in platform implementation

    public Task Show(string title, string message, string filePath, DelegateCommand okCommand = null, DelegateCommand cancelCommand=null)
            {
                _okCommand = okCommand;
                _cancelCommand = cancelCommand;
    
                var extension = filePath.Substring(filePath.LastIndexOf(".") + 1).ToLower();
                var contentType = string.Empty;
    
            switch (extension)
            {
                case "pdf":
                    contentType = "application/pdf";
                    break;
                case "png":
                    contentType = "image/png";
                    break;
                default:
                    contentType = "application/octetstream";
                    break;
            }
    
            var intent = new Intent(Intent.ActionSend);
            intent.SetType(contentType);
    
            File file = new File(filePath);
    
            var apkURI = FileProvider.GetUriForFile(
                Activity,
                Activity.ApplicationContext.PackageName + ".provider", file);
    
            intent.PutExtra(Intent.ExtraStream, apkURI);
            intent.PutExtra(Intent.ExtraText, string.Empty);
            intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);
    
            var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
    
            chooserIntent.SetFlags(ActivityFlags.ClearTop);
    
            Activity.ActivityResult -= Activity_ActivityResult;
            Activity.ActivityResult += Activity_ActivityResult;
    
            Activity.StartActivityForResult(chooserIntent, 0);
    
            return Task.FromResult(true);
        }
    
        private void Activity_ActivityResult(int request, Result result, Intent intent)
        {
            Activity.ActivityResult -= Activity_ActivityResult;
    
            if (result == Result.Ok)
            {
                _okCommand?.Execute();
            }
            else
            {
                _cancelCommand?.Execute();
            }
        }
    

Answers

  • RadoslawKubasRadoslawKubas USMember ✭✭

    On iOS I created custom share implementation and it works fine:

    public Task Show(string title, string message, string filePath, 
            DelegateCommand okCommand = null,
            DelegateCommand cancelCommand = null)
        {
            var items = new NSObject[] { NSObject.FromObject(title), NSUrl.FromFilename(filePath) };
            var activityController = new UIActivityViewController(items, null);
            var vc = GetVisibleViewController();
    
            activityController.CompletionWithItemsHandler = (type, completed, returnedItems, error) =>
            {
                if (completed)
                {
                    okCommand?.Execute();
                }
                else
                {
                    cancelCommand?.Execute();
                }
            };
    
            NSString[] excludedActivityTypes = null;
    
            if (excludedActivityTypes != null && excludedActivityTypes.Length > 0)
                activityController.ExcludedActivityTypes = excludedActivityTypes;
    
            if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
            {
                if (activityController.PopoverPresentationController != null)
                {
                    activityController.PopoverPresentationController.SourceView = vc.View;
                }
            }
    
            return vc.PresentViewControllerAsync(activityController, true);
        }
    

    How to modify this Android share implementation to do similar job?

    public Task Show(string title, string message, string filePath,
            DelegateCommand okCommand = null,
            DelegateCommand cancelCommand = null)
            {
                var extension = filePath.Substring(filePath.LastIndexOf(".") + 1).ToLower();
                var contentType = string.Empty;
    
                switch (extension)
                {
                    case "pdf":
                        contentType = "application/pdf";
                        break;
                    case "png":
                        contentType = "image/png";
                        break;
                    default:
                        contentType = "application/octetstream";
                        break;
                }
    
                var intent = new Intent(Intent.ActionSend);
                intent.SetType(contentType);
    
                File file = new File(filePath);
                var length=file.Length();
    
                var apkURI = FileProvider.GetUriForFile(
                    _context,
                    _context.ApplicationContext.PackageName + ".provider", file);
    
                intent.PutExtra(Intent.ExtraStream, apkURI);
    
                intent.PutExtra(Intent.ExtraText, string.Empty);
                intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);
    
    
                var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
    
                chooserIntent.SetFlags(ActivityFlags.ClearTop);
                chooserIntent.SetFlags(ActivityFlags.NewTask);
                _context.StartActivity(chooserIntent);
    
                return Task.FromResult(true);
            }
    
  • RadoslawKubasRadoslawKubas USMember ✭✭
    Accepted Answer

    OK, I think I created solution myself, on Android little more complicated, not optimized, but seems to work fine. Solution below in case anyone need it. If someone can propose better solution or upgrade this on it will be great.

    public class FormsAppCompatActivityEx : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            public event Action<int, Result, Intent> ActivityResult;
    
            protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
            {
                ActivityResult?.Invoke(requestCode, resultCode, data);
            }
        }
    

    and in platform implementation

    public Task Show(string title, string message, string filePath, DelegateCommand okCommand = null, DelegateCommand cancelCommand=null)
            {
                _okCommand = okCommand;
                _cancelCommand = cancelCommand;
    
                var extension = filePath.Substring(filePath.LastIndexOf(".") + 1).ToLower();
                var contentType = string.Empty;
    
            switch (extension)
            {
                case "pdf":
                    contentType = "application/pdf";
                    break;
                case "png":
                    contentType = "image/png";
                    break;
                default:
                    contentType = "application/octetstream";
                    break;
            }
    
            var intent = new Intent(Intent.ActionSend);
            intent.SetType(contentType);
    
            File file = new File(filePath);
    
            var apkURI = FileProvider.GetUriForFile(
                Activity,
                Activity.ApplicationContext.PackageName + ".provider", file);
    
            intent.PutExtra(Intent.ExtraStream, apkURI);
            intent.PutExtra(Intent.ExtraText, string.Empty);
            intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);
    
            var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
    
            chooserIntent.SetFlags(ActivityFlags.ClearTop);
    
            Activity.ActivityResult -= Activity_ActivityResult;
            Activity.ActivityResult += Activity_ActivityResult;
    
            Activity.StartActivityForResult(chooserIntent, 0);
    
            return Task.FromResult(true);
        }
    
        private void Activity_ActivityResult(int request, Result result, Intent intent)
        {
            Activity.ActivityResult -= Activity_ActivityResult;
    
            if (result == Result.Ok)
            {
                _okCommand?.Execute();
            }
            else
            {
                _cancelCommand?.Execute();
            }
        }
    
Sign In or Register to comment.