コード例 #1
0
        private Android.Net.Uri GetFileForBrowser(Android.Net.Uri dataFromActivityResult)
        {
            try
            {
                string TempfileName = Guid.NewGuid().ToString("N") + ".file";

                string outputFolder = FileCachingHelper.GetFileCacheFolder();
                if (!System.IO.Directory.Exists(outputFolder))
                {
                    System.IO.Directory.CreateDirectory(outputFolder);
                }

                var backingFile = System.IO.Path.Combine(outputFolder, TempfileName);
                using (var output = System.IO.File.Create(backingFile))
                {
                    using (System.IO.Stream inputStream = BlazorWebViewService.GetCurrentActivity().ContentResolver.OpenInputStream(dataFromActivityResult))
                    {
                        inputStream.CopyTo(output);
                    }
                }

                return(Android.Net.Uri.Parse("file://" + backingFile));
            }
            catch (System.Exception e)
            {
                ConsoleHelper.WriteException(e);
                throw;
            }
        }
コード例 #2
0
        protected override void OnElementChanged(ElementChangedEventArgs <GeckoViewForms> e)
        {
            base.OnElementChanged(e);

            if (keyboardHelper == null)
            {
                keyboardHelper = new KeyboardUtil(BlazorWebViewService.GetCurrentActivity(), Control);
            }
        }
コード例 #3
0
        private void GetContentCompatibleIntents(int type, out List <IntentMetadata> intentList, out List <ResolveInfo> info)
        {
            Intent camIntent        = new Intent("android.media.action.IMAGE_CAPTURE");
            Intent getActionIntents = new Intent(Intent.ActionGetContent);

            getActionIntents.SetType("*/*");
            getActionIntents.AddCategory(Intent.CategoryOpenable);

            //We must manage multiple file selection too
            if (type == FilePromptType.MULTIPLE)
            {
                getActionIntents.PutExtra(Intent.ExtraAllowMultiple, true);
            }

            // look for available intents
            info       = new List <ResolveInfo>();
            intentList = new List <IntentMetadata>();
            PackageManager     packageManager = BlazorWebViewService.GetCurrentActivity().PackageManager;
            List <ResolveInfo> listCam        = packageManager.QueryIntentActivities(camIntent, 0).ToList();

            //Required permissions for camera intents
            string[] permissionsForCamera = new string[] {
                Android.Manifest.Permission.WriteExternalStorage,
                Android.Manifest.Permission.Camera
            };

            //Required permissions for read content intents
            string[] permissionsForGetContent = new string[] {
                Android.Manifest.Permission.ReadExternalStorage
            };

            foreach (ResolveInfo res in listCam)
            {
                Intent finalIntent = new Intent(camIntent);
                finalIntent.SetComponent(new ComponentName(res.ActivityInfo.PackageName, res.ActivityInfo.Name));
                intentList.Add(new IntentMetadata(finalIntent, permissionsForCamera));
                info.Add(res);
            }

            List <ResolveInfo> listGall = packageManager.QueryIntentActivities(getActionIntents, 0).ToList();

            foreach (ResolveInfo res in listGall)
            {
                Intent finalIntent = new Intent(getActionIntents);
                finalIntent.SetComponent(new ComponentName(res.ActivityInfo.PackageName, res.ActivityInfo.Name));
                intentList.Add(new IntentMetadata(finalIntent, permissionsForGetContent));
                info.Add(res);
            }
        }
コード例 #4
0
            public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
            {
                Android.Views.View view  = base.GetView(position, convertView, parent);
                ResolveInfo        res   = ActivitiesInfo.ElementAt(position);
                ImageView          image = (ImageView)view.FindViewById(
                    BlazorWebViewService.GetResourceId("intent_listview_icon", AndroidResourceType.Identifier)
                    );

                image.SetImageDrawable(res.LoadIcon(BlazorWebViewService.GetCurrentActivity().PackageManager));
                TextView textview = (TextView)view.FindViewById(
                    BlazorWebViewService.GetResourceId("intent_listview_title", AndroidResourceType.Identifier)
                    );

                textview.Text = res.LoadLabel(BlazorWebViewService.GetCurrentActivity().PackageManager);
                return(view);
            }
コード例 #5
0
        /// <summary>
        /// Check for a permission available in <seealso cref="Android.Manifest.Permission"/> namespace
        /// </summary>
        /// <param name="permission"></param>
        ///
        public static void CheckForPermission(string[] permission, System.Action onGranted, System.Action onDenied)
        {
            string[] needAdditionalPermissions = permission.Where(p => BlazorWebViewService.GetCurrentActivity().CheckSelfPermission(p) != Android.Content.PM.Permission.Granted).ToArray();

            if (Build.VERSION.SdkInt >= BuildVersionCodes.M && needAdditionalPermissions != null && needAdditionalPermissions.Length > 0)
            {
                BlazorWebViewService.GetCurrentActivity().RequestPermissions(needAdditionalPermissions, BLAZORMOBILE_REQUESTCODE);

                //TODO: We must forward event directly from an async result OR at least show a toast in order to ask to repeat the action again

                //We must dismiss the result, and the user have to retry after validating the permission
                onDenied?.Invoke();
            }
            else
            {
                //We already have the permission
                onGranted?.Invoke();
            }
        }
コード例 #6
0
        public virtual void OnFilePrompt(GeckoSession session, string title, int type, string[] mimeTypes, GeckoSession.PromptDelegateClassFileCallback callback)
        {
            var currentActivity = BlazorWebViewService.GetCurrentActivity();

            AlertDialog _futureDialog = null; //Workaround dismiss method not available on AlertDialog.Builder before Show();

            bool shouldDismiss = true;

            var dialogBuilder = new Android.App.AlertDialog.Builder(_renderer.Context);
            BlazorFileDialogDismissListener onDismissEvent = new BlazorFileDialogDismissListener();

            onDismissEvent.SetDismissHandler(() =>
            {
                if (shouldDismiss)
                {
                    callback.Dismiss();
                }

                dialogBuilder.Dispose();
            });

            dialogBuilder.SetOnDismissListener(onDismissEvent);

            GetContentCompatibleIntents(type, out List <IntentMetadata> intentList, out List <ResolveInfo> activitiesInfo);
            dialogBuilder.SetAdapter(BuilderAdapter(currentActivity, activitiesInfo),
                                     (sender, e) =>
            {
                //On Intent click

                shouldDismiss = false;
                IntentMetadata selectedIntent = intentList.ElementAt(e.Which);

                //Check for Android permissions for intents
                RequestPermissionHelper.CheckForPermission(selectedIntent.RequiredPermissions, () =>
                {
                    //On Intent permission availables

                    //We must manage multiple file selection too

                    //TODO: Even by adding this intent
                    //this seem to not working yet. Not sure if possible through launching external intents
                    if (type == FilePromptType.MULTIPLE)
                    {
                        selectedIntent.Intent.PutExtra(Intent.ExtraAllowMultiple, true);
                    }

                    currentActivity.StartActivityForResult(selectedIntent.Intent, 1, (int requestCode, Result resultCode, Intent data) =>
                    {
                        if (resultCode != Result.Ok)
                        {
                            //Do nothing as the user is still now on the Intent dialog box chooser

                            //As on Permission not granted, see comment below =>
                            //We should reset this value to true if denied, as the user may don't click on Cancel but use a back button instead
                            //As the back button will call the Dialog dismiss internally, we should emulate the cancel behavior (see SetNeutralButton code)
                            shouldDismiss = true;
                        }
                        else
                        {
                            try
                            {
                                callback.Confirm(currentActivity, GetFileForBrowser(data.Data));
                            }
                            catch (System.Exception e)
                            {
                                ConsoleHelper.WriteException(e);
                                callback.Dismiss();
                            }

                            _futureDialog.Dismiss();
                        }
                    });
                }, () =>
                {
                    //On Intent permission unavailable

                    //We should reset this value to true if denied, as the user may don't click on Cancel but use a back button instead
                    //As the back button will call the Dialog dismiss internally, we should emulate the cancel behavior (see SetNeutralButton code)
                    shouldDismiss = true;
                });
            });


            dialogBuilder.SetNeutralButton(currentActivity.Resources.GetString(Android.Resource.String.Cancel),
                                           (sender, e) =>
            {
                shouldDismiss = true;
                _futureDialog.Dismiss();
            });
            shouldDismiss = true;
            _futureDialog = dialogBuilder.Show();
        }
コード例 #7
0
        public virtual void OnChoicePrompt(GeckoSession session, string title, string msg, int type, GeckoSession.romptDelegateClassChoice[] choices, GeckoSession.PromptDelegateClassChoiceCallback prompt)
        {
            //This code is highly inspired of https://github.com/mozilla-mobile/focus-android/blob/f5b22ff78fca22765b8b873b4f70693943ae559a/app/src/main/java/org/mozilla/focus/gecko/GeckoViewPrompt.java#L265

            var currentActivity = BlazorWebViewService.GetCurrentActivity();

            if (currentActivity == null)
            {
                prompt.Dismiss();
                return;
            }

            var builder = new Android.App.AlertDialog.Builder(currentActivity);

            AddStandardLayout(builder, title, msg);

            Android.Widget.ListView list = new Android.Widget.ListView(builder.Context);
            if (type == GeckoSession.romptDelegateClassChoice.ChoiceTypeMultiple)
            {
                list.ChoiceMode = ChoiceMode.Multiple;
            }

            ModifiableChoiceArrayAdapter <ModifiableChoice> adapter = new ModifiableChoiceArrayAdapter <ModifiableChoice>(builder.Context, Android.Resource.Layout.SimpleListItem1, type, builder, list);

            AddChoiceItems(type, adapter, choices, /* indent */ null);

            list.SetAdapter(adapter);
            builder.SetView(list);

            AlertDialog dialog;

            if (type == GeckoSession.romptDelegateClassChoice.ChoiceTypeSingle || type == GeckoSession.romptDelegateClassChoice.ChoiceTypeMenu)
            {
                dialog = CreateStandardDialog(builder, prompt);

                list.ItemClick += (sender, e) =>
                {
                    ModifiableChoice item = adapter.GetItem(e.Position);
                    if (type == GeckoSession.romptDelegateClassChoice.ChoiceTypeMenu)
                    {
                        GeckoSession.romptDelegateClassChoice[] children = item.Choice.Items?.ToArray();
                        if (children != null)
                        {
                            // Show sub-menu.
                            dialog.SetOnDismissListener(null);
                            dialog.Dismiss();
                            OnChoicePrompt(session, item.ModifiableLabel, /* msg */ null,
                                           type, children, prompt);
                            return;
                        }
                    }
                    prompt.Confirm(item.Choice);
                    dialog.Dismiss();
                };
            }
            else if (type == GeckoSession.romptDelegateClassChoice.ChoiceTypeMultiple)
            {
                list.ItemClick += (sender, e) =>
                {
                    ModifiableChoice item = adapter.GetItem(e.Position);
                    item.ModifiableSelected = ((CheckedTextView)e.View).Checked;
                };
                builder
                .SetNegativeButton(Android.Resource.String.Cancel, /* listener */ (IDialogInterfaceOnClickListener)null)
                .SetPositiveButton(Android.Resource.String.Ok, (sender, e) =>
                {
                    int len             = adapter.Count;
                    List <string> items = new List <string>(len);
                    for (int i = 0; i < len; i++)
                    {
                        ModifiableChoice item = adapter.GetItem(i);
                        if (item.ModifiableSelected)
                        {
                            items.Add(item.Choice.Id);
                        }
                    }
                    prompt.Confirm(items.ToArray());
                });
                dialog = CreateStandardDialog(builder, prompt);
            }
            else
            {
                throw new UnsupportedOperationException();
            }
            dialog.Show();

            //TODO: Don't forget to Dispose dialogbuilder
        }
コード例 #8
0
        public override Android.Views.View GetView(int position, Android.Views.View view, ViewGroup parent)
        {
            var context = BlazorWebViewService.GetCurrentActivity();

            int itemType = GetItemViewType(position);
            int layoutId;

            if (itemType == TYPE_SEPARATOR)
            {
                if (mSeparator == null)
                {
                    mSeparator = new Android.Views.View(context);
                    mSeparator.LayoutParameters = new Android.Widget.ListView.LayoutParams(ViewGroup.LayoutParams.MatchParent, 2, itemType);
                    TypedArray attr = context.ObtainStyledAttributes(
                        new int[] { Android.Resource.Attribute.ListDivider });
                    mSeparator.SetBackgroundResource(attr.GetResourceId(0, 0));
                    attr.Recycle();
                }
                return(mSeparator);
            }
            else if (itemType == TYPE_MENU_ITEM)
            {
                layoutId = Android.Resource.Layout.SimpleListItem1;
            }
            else if (itemType == TYPE_MENU_CHECK)
            {
                layoutId = Android.Resource.Layout.SimpleListItemChecked;
            }
            else if (itemType == TYPE_GROUP)
            {
                layoutId = Android.Resource.Layout.PreferenceCategory;
            }
            else if (itemType == TYPE_SINGLE)
            {
                layoutId = Android.Resource.Layout.SimpleListItemSingleChoice;
            }
            else if (itemType == TYPE_MULTIPLE)
            {
                layoutId = Android.Resource.Layout.SimpleListItemMultipleChoice;
            }
            else
            {
                throw new UnsupportedOperationException();
            }

            if (view == null)
            {
                if (mInflater == null)
                {
                    mInflater = LayoutInflater.From(_builder.Context);
                }
                view = mInflater.Inflate(layoutId, parent, false);
            }

            ModifiableChoice item = GetItem(position);
            TextView         text = (TextView)view;

            text.Enabled = !item.Choice.Disabled;
            text.Text    = item.ModifiableLabel;
            if (view is CheckedTextView)
            {
                bool selected = item.ModifiableSelected;
                if (itemType == TYPE_MULTIPLE)
                {
                    _list.SetItemChecked(position, selected);
                }
                else
                {
                    ((CheckedTextView)view).Checked = selected;
                }
            }
            return(view);
        }