2

I am receiving this error when using the Dependency Service on a Xamarin.Forms. I have seen answers to this error that involve iOS and the Linker. However, I am running this on Android and the Linker is off.

The constructor it is telling me it cannot find the default constructor for the Interface in the PCL.

I have been searching and debugging this for hours. What are some things that could be causing this error? I am pretty sure my DependencyService Implementations are correct so I feel like it is something different.

Here is my related code.

Android

[assembly: Xamarin.Forms.Dependency(typeof(TextRecognition))]
namespace DiabetesAPP.Droid
{
    [Preserve(AllMembers = true)]
    [Activity(Label = "TextRecognition", Theme = "@style/Theme.AppCompat.Light.NoActionBar", MainLauncher = true)]
    public class TextRecognition : AppCompatActivity, ISurfaceHolderCallback, IProcessor, ITextRecognition
    {
        private SurfaceView cameraView;
        private TextView textView;
        private CameraSource cameraSource;
        public string Resultados;
        private const int RequestCameraPermissionID = 1001;

        protected override void OnCreate(Bundle savedInstanceState)
        {

            base.OnCreate(savedInstanceState);

            SetContentView(Resource.Layout.Main);
            cameraView = FindViewById<SurfaceView>(Resource.Id.surface_view);
            textView = FindViewById<TextView>(Resource.Id.txtview);

            TextRecognizer textRecognizer = new TextRecognizer.Builder(ApplicationContext).Build();
            if (!textRecognizer.IsOperational)
            {
                Log.Error("Main Activity", "Detector dependencies are not yet available");
            }
            else
            {
                cameraSource = new CameraSource.Builder(ApplicationContext, textRecognizer)
                    .SetFacing(CameraFacing.Back)
                    .SetRequestedFps(2.0f)
                    .SetRequestedPreviewSize(1280, 1024)
                    .SetAutoFocusEnabled(true)
                    .Build();

                cameraView.Holder.AddCallback(this);
                 textRecognizer.SetProcessor(this);
            }

            Android.Widget.Button logonButton = FindViewById<Android.Widget.Button>(Resource.Id.button_send);
            logonButton.Click += LogonButton_Click;
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            switch (requestCode)
            {
                case RequestCameraPermissionID:
                    {
                        if (grantResults[0] == Android.Content.PM.Permission.Granted)
                        {
                           cameraSource.Start(cameraView.Holder);
                        }
                    }
                    break;
            }
        }

        public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
        {

        }

        public void SurfaceCreated(ISurfaceHolder holder)
        {
            if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
            {
                ActivityCompat.RequestPermissions(this, new string[]
                {
                    Android.Manifest.Permission.Camera
                }, RequestCameraPermissionID);
                return;
            }
           cameraSource.Start(cameraView.Holder);
        }

        public void SurfaceDestroyed(ISurfaceHolder holder)
        {
            cameraSource.Stop();
        }

        public void ReceiveDetections(Detections detections)
        {
            SparseArray items = detections.DetectedItems;
            if (items.Size() != 0)
            {
                textView.Post(() =>
                {
                    StringBuilder strBuilder = new StringBuilder();
                    for (int i = 0; i < items.Size(); i++)
                    {
                        strBuilder.Append(((TextBlock)items.ValueAt(i)).Value);
                        strBuilder.Append("\n");
                    }
                    textView.Text = strBuilder.ToString();
                    Resultados = strBuilder.ToString();
                });
            }
        }

        private void LogonButton_Click(object sender, EventArgs e)
        {
            //Toast.MakeText(this, "Hello from " + Resultados, ToastLength.Long).Show();
            //Intent data = new Intent(this, typeof(TextRecognition));
            //SetResult(Result.Ok, data);
            //// MessagingCenter.Send((DiabetesAPP.App)Xamarin.Forms.Application.Current, "OpenPage", "You send message:" + Resultados);
            //// MessagingCenter.Send<DiabetesAPP.App, string>(DiabetesAPP.App.Current as App, "OpenPage", "You send message:" + Resultados);
            //MessagingCenter.Send((DiabetesAPP.App)Xamarin.Forms.Application.Current, "OpenPage", "You send message:" + Resultados);
            Toast.MakeText(this, Resultados, ToastLength.Short).Show();

            MessagingCenter.Send<App, string>(App.Current as App, "OpenPage", "You send message:" + Resultados);


            Finish();
        }

        public void Release()
        {

        }

        public void LaunchActivityInAndroid()
        {
            Activity activity = Forms.Context as Activity;
            var intent = new Intent(Forms.Context, typeof(TextRecognition));
            activity.StartActivity(intent);
        }

        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);


            switch (resultCode)
            {
                case Result.Ok:
                    break;
            }

            Finish();
        }



        public interface ITextRecognition
        {

        }

//Update code - 16/09/2020
        public TextRecognition()
        {

        }


    }
}

Implementation in a Xamarin.Form Page

[assembly: Xamarin.Forms.Dependency(typeof(ITextRecognition))]
namespace DiabetesAPP.Views.FoodMenu
{

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FoodMenu : ContentPage
    {
        public FoodMenu()
        {
            InitializeComponent();
        }

        async void Food_ManualEntry(object sender, EventArgs e)
        {
            await Navigation.PushAsync(new SearchFood());
        }

        public void Food_CameraEntry(object sender, EventArgs e)
        {
            Xamarin.Forms.DependencyService.Register<ITextRecognition>();
            DependencyService.Get<ITextRecognition>().LaunchActivityInAndroid();

        }

        public interface ITextRecognition
        {
            void LaunchActivityInAndroid();
        }

    }
}

Error: System.MissingMethodException: Default constructor not found for type DiabetesAPP.Views.FoodMenu.FoodMenu+ITextRecognition

What is going wrong?

2 Answers2

0

this is exactly what the error says it is. For DependencyService to instantiate a class, the class MUST have a default (empty) constructor. Yours does not.

Jason
  • 86,222
  • 15
  • 131
  • 146
0

You don't need to create a new ITextRecognition interface in Android project, you should use the interface which you created in the Xamarin.forms projet.

Also, it's better not to create the interface inside the FoodMenu class.

Here is the code example:

In Xamarin.Forms:

namespace App384
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FoodMenu : ContentPage
    {
        public FoodMenu()
        {
            InitializeComponent();
        }

        public void Food_CameraEntry(object sender, EventArgs e)
        {
            Xamarin.Forms.DependencyService.Register<ITextRecognition>();
            DependencyService.Get<ITextRecognition>().LaunchActivityInAndroid();

        }
    }

    public interface ITextRecognition
    {
        void LaunchActivityInAndroid();
    }
}

In Xamarin.Android project:

[assembly: Xamarin.Forms.Dependency(typeof(TextRecognition))]
namespace App384.Droid
{
    [Preserve(AllMembers = true)]
    [Activity(Label = "TextRecognition", Theme = "@style/Theme.AppCompat.Light.NoActionBar", MainLauncher = true)]
    public class TextRecognition : AppCompatActivity, ITextRecognition
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
        }

        public void LaunchActivityInAndroid()
        {
            Console.WriteLine("LaunchActivityInAndroid");
        }

    }
}

I have uploaded test demo here and you can check.

Refer: Xamarin.Forms DependencyService Introduction

nevermore
  • 15,432
  • 1
  • 12
  • 30