How to enable/disable barcode scanner using Datawedge in Xamarin Forms

1.9k views Asked by At

I am developing an inventory management app in xamarin forms using Zebra TC20 model. Right now I am able to retrieve barcode data using datawedge. Now I am trying to disable and enable barcode scanner using datawedge as well. I have surfed and found out we can broadcast to datawedge for enable and disable the barcode scanner. Now I am having the issue when I want to enable or disable the the scanner from a page I am retrieving an error message Java.Lang.NullPointerException: 'Attempt to invoke virtual method 'void android.content.Context.sendBroadcast(android.content.Intent)' on a null object reference . The scanner functions are implemented in Android file. I am using dependency service to call the scanner functions. I have attached the code I have done.

MainActivity.cs

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IKeyboardListener, IScannerConnection
    {

        private static string ACTION_DATAWEDGE_FROM_6_2 = "com.symbol.datawedge.api.ACTION";

        private static string EXTRA_CREATE_PROFILE = "com.symbol.datawedge.api.CREATE_PROFILE";

        private static string EXTRA_SET_CONFIG = "com.symbol.datawedge.api.SET_CONFIG";

        private static string EXTRA_PROFILE_NAME = "Barcode Scan";

        private DataWedgeReceiver _broadcastReceiver = null;

        protected override void OnCreate(Bundle bundle)
        {

            base.Window.RequestFeature(WindowFeatures.ActionBar);
            // Name of the MainActivity theme you had there before.
            // Or you can use global::Android.Resource.Style.ThemeHoloLight
            base.SetTheme(Resource.Style.MainTheme);

            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;
            base.OnCreate(bundle);

            DependencyService.Register<ToastNotification>(); // Register your dependency
            ToastNotification.Init(this);

            var container = new SimpleContainer(); // Create a SimpleCOntainer
            container.Register<IGeolocator, Geolocator>(); // Register the Geolocator
            container.Register<IDevice>(t => AndroidDevice.CurrentDevice); // Register the Device
            Resolver.ResetResolver();   // Reset the resolver
            Resolver.SetResolver(container.GetResolver()); // Resolve it

            FFImageLoading.Forms.Platform.CachedImageRenderer.Init(enableFastRenderer: true);

            UserDialogs.Init(this);

            Rg.Plugins.Popup.Popup.Init(this, bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            global::ZXing.Net.Mobile.Forms.Android.Platform.Init();

             _broadcastReceiver = new DataWedgeReceiver();
            App inventoryApp = new App(OnSaveSignature);

            _broadcastReceiver.scanDataReceived += (s, scanData) =>
            {
                MessagingCenter.Send<App, string>(inventoryApp, "ScanBarcode", scanData);
            };

            CreateProfile();

            //DependencyService.Register<ToastNotification>();
            //ToastNotification.Init(this, new PlatformOptions() { SmallIconDrawable = Android.Resource.Drawable.IcDialogInfo });

            LoadApplication(inventoryApp);
        }

        public override void OnBackPressed()
        {
            if (Rg.Plugins.Popup.Popup.SendBackPressed(base.OnBackPressed))
            {
                // Do something if there are some pages in the `PopupStack`
            }
            else
            {
                // Do something if there are not any pages in the `PopupStack`
            }
        }

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            // check if the current item id 
            // is equals to the back button id
            if (item.ItemId == 16908332 && !RFIDStockCountViewModel.IsPosted && RFIDStockCountViewModel.IsStockCounting)
            {

                return false;

                /*
               if (Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack.Count > 0)
               {
                   //LIFO is the only game in town! - so send back the last page

                   int index = Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack.Count - 1;

                   var currPage = (CustomContentPage)Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack[index];

                   // check if the page has subscribed to 
                   // the custom back button event
                   if (currPage?.CustomBackButtonAction != null)
                   {
                       // invoke the Custom back button action
                       currPage?.CustomBackButtonAction.Invoke();
                       // and disable the default back button action
                       return false;
                   }
               }
               // if its not subscribed then go ahead 
               // with the default back button action
               return base.OnOptionsItemSelected(item);
               */
            }
            else
            {
                // since its not the back button 
                //click, pass the event to the base
                return base.OnOptionsItemSelected(item);
            }
        }

        private async Task<bool> OnSaveSignature(Stream bitmap, string filename)
        {
            var path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).AbsolutePath;
            var file = Path.Combine(path, "signature.png");

            using (var dest = File.OpenWrite(file))
            {
                await bitmap.CopyToAsync(dest);
            }

            return true;
        }

        //public override void OnBackPressed()
        //{

        //    if (Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack.Count > 0)
        //    {
        //        //LIFO is the only game in town! - so send back the last page

        //        int index = Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack.Count - 1;

        //        var currentpage = (CustomContentPage)Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack[index];

        //        // check if the page has subscribed to 
        //        // the custom back button event
        //        if (currentpage?.CustomBackButtonAction != null)
        //        {
        //            currentpage?.CustomBackButtonAction.Invoke();
        //        }
        //        else
        //        {
        //            base.OnBackPressed();
        //        }
        //    }
        //}

        public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
        {
            if (e.KeyCode.GetHashCode() == 139 || e.KeyCode.GetHashCode() == 280)
            {

                MessagingCenter.Send<IKeyboardListener, string>(this, "KeyboardListener", "TRUE");
            }
            return base.OnKeyDown(keyCode, e);
        }

        public override bool OnKeyUp(Keycode keyCode, KeyEvent e)
        {
            if (e.KeyCode.GetHashCode() == 139 || e.KeyCode.GetHashCode() == 280)
            {
                MessagingCenter.Send<IKeyboardListener, string>(this, "KeyboardListener", "FALSE");
            }
            return base.OnKeyDown(keyCode, e);
        }

        protected override void OnResume()
        {
            base.OnResume();

            if (null != _broadcastReceiver)
            {
                // Register the broadcast receiver
                IntentFilter filter = new IntentFilter(DataWedgeReceiver.IntentAction);
                filter.AddCategory(DataWedgeReceiver.IntentCategory);
                Android.App.Application.Context.RegisterReceiver(_broadcastReceiver, filter);
            }
        }

        protected override void OnPause()
        {
            if (null != _broadcastReceiver)
            {
                // Unregister the broadcast receiver
                Android.App.Application.Context.UnregisterReceiver(_broadcastReceiver);
            }
            base.OnStop();
        }

        private void CreateProfile()
        {
            String profileName = EXTRA_PROFILE_NAME;
            SendDataWedgeIntentWithExtra(ACTION_DATAWEDGE_FROM_6_2, EXTRA_CREATE_PROFILE, profileName);

            //  Now configure that created profile to apply to our application
            Bundle profileConfig = new Bundle();
            profileConfig.PutString("PROFILE_NAME", EXTRA_PROFILE_NAME);
            profileConfig.PutString("PROFILE_ENABLED", "true"); //  Seems these are all strings
            profileConfig.PutString("CONFIG_MODE", "CREATE_IF_NOT_EXIST");
            Bundle barcodeConfig = new Bundle();
            barcodeConfig.PutString("PLUGIN_NAME", "BARCODE");
            //barcodeConfig.PutString("RESET_CONFIG", "true"); //  This is the default but never hurts to specify

            Bundle barcodeProps = new Bundle();
            barcodeProps.PutString("scanner_input_enabled", "true"); //  This is the default but never hurts to specify
            barcodeProps.PutString("scanner_selection_by_identifier", "AUTO ");
            barcodeProps.PutString("scanner_selection", "auto ");
            barcodeProps.PutString("aim_mode", "off ");
            barcodeProps.PutString("illumination_mode", "off ");
            barcodeConfig.PutBundle("PARAM_LIST", barcodeProps);
            profileConfig.PutBundle("PLUGIN_CONFIG", barcodeConfig);
            Bundle appConfig = new Bundle();
            appConfig.PutString("PACKAGE_NAME", this.PackageName);      //  Associate the profile with this app
            appConfig.PutStringArray("ACTIVITY_LIST", new String[] { "*" });
            profileConfig.PutParcelableArray("APP_LIST", new Bundle[] { appConfig });
            SendDataWedgeIntentWithExtra(ACTION_DATAWEDGE_FROM_6_2, EXTRA_SET_CONFIG, profileConfig);
            //  You can only configure one plugin at a time, we have done the barcode input, now do the intent output
            profileConfig.Remove("PLUGIN_CONFIG");
            Bundle intentConfig = new Bundle();
            intentConfig.PutString("PLUGIN_NAME", "INTENT");
            intentConfig.PutString("RESET_CONFIG", "true");
            Bundle intentProps = new Bundle();
            intentProps.PutString("intent_output_enabled", "true");
            intentProps.PutString("intent_action", DataWedgeReceiver.IntentAction);
            intentProps.PutString("intent_delivery", "2");
            intentConfig.PutBundle("PARAM_LIST", intentProps);
            profileConfig.PutBundle("PLUGIN_CONFIG", intentConfig);
            SendDataWedgeIntentWithExtra(ACTION_DATAWEDGE_FROM_6_2, EXTRA_SET_CONFIG, profileConfig);
        }

        private void SendDataWedgeIntentWithExtra(String action, String extraKey, Bundle extras)
        {
            Intent dwIntent = new Intent();
            dwIntent.SetAction(action);
            dwIntent.PutExtra(extraKey, extras);
            SendBroadcast(dwIntent);
        }

        private void SendDataWedgeIntentWithExtra(String action, String extraKey, String extraValue)
        {
            Intent dwIntent = new Intent();
            dwIntent.SetAction(action);
            dwIntent.PutExtra(extraKey, extraValue);
            SendBroadcast(dwIntent);
        }

        public void SendScannerEnable()
        {
            SendDataWedgeIntentWithExtra(ACTION_DATAWEDGE_FROM_6_2, EXTRA_SET_CONFIG, "ENABLE_PLUGIN");
        }

        public void SendScannerDisable()
        {
            SendDataWedgeIntentWithExtra(ACTION_DATAWEDGE_FROM_6_2, EXTRA_SET_CONFIG, "DISABLE_PLUGIN");
        }
   }
}

Snip from Page.cs

 protected override void OnAppearing()
 {
      DependencyService.Get<IScannerConnection>().SendScannerEnable();
      MessagingCenter.Subscribe<App, string>(this, "ScanBarcode", (sender, arg) =>
      {
          ScanBarcode(arg);
      });
            
      base.OnAppearing();
}

I have searched through internet but I didn't get any resource on how to fix it.

Thank you.

1

There are 1 answers

0
Sashi Kumar On BEST ANSWER

The url below helped me to fix my problem. I had to create a new scanner class which enables and disables datawedge profile by triggering events. https://developer.zebra.com/community/home/blog/2018/07/11/xamarinforms-freshmvvm-datawedge-take-2