diff --git a/README.md b/README.md index 1c8d8ca..a43f20b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ BarcodeScanner ============== +Added version that runs with windows mobile devices. +To run on those devices, the zxing.net library must be added to the project (Install as nuget packet - more information on http://www.nuget.org/packages/ZXing.Net) + +Windows Phone currently only supports Scaning for codes, feel free to extend it that it can also encode. + Cross-platform BarcodeScanner for Cordova / PhoneGap. Follows the [Cordova Plugin spec](https://github.com/apache/cordova-plugman/blob/master/plugin_spec.md), so that it works with [Plugman](https://github.com/apache/cordova-plugman). diff --git a/plugin.xml b/plugin.xml index 0d0ccfa..8a38ed6 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,7 +1,7 @@ + version="1.2.0"> BarcodeScanner Scans Barcodes. @@ -15,6 +15,8 @@ + + @@ -37,6 +39,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wp/BarcodeScanner.cs b/src/wp/BarcodeScanner.cs new file mode 100644 index 0000000..a685de9 --- /dev/null +++ b/src/wp/BarcodeScanner.cs @@ -0,0 +1,46 @@ +using BarcodeScanner; +using Microsoft.Phone.Controls; +using System; +using System.Windows; +using System.Windows.Navigation; +using WPCordovaClassLib.Cordova; +using WPCordovaClassLib.Cordova.Commands; +using WPCordovaClassLib.Cordova.JSON; + +namespace Cordova.Extension.Commands +{ + public class BarcodeScanner : BaseCommand + { + private PhoneApplicationFrame currentRootVisual; + + public void scan(string options) + { + Deployment.Current.Dispatcher.BeginInvoke(() => + { + currentRootVisual = Application.Current.RootVisual as PhoneApplicationFrame; + currentRootVisual.Navigated += OnFrameNavigated; + currentRootVisual.Navigate(new Uri("/Plugins/com.phonegap.plugins.barcodescanner/Scan.xaml", UriKind.Relative)); + }); + } + + private void OnFrameNavigated(object sender, NavigationEventArgs e) + { + var scanPage = e.Content as Scan; + if (scanPage != null) + { + scanPage.BarcodeScannerPlugin = this; + } + } + + public void OnScanFailed(string error) + { + DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, error)); + } + + public void OnScanSucceeded(BarcodeScannerResult scanResult) + { + var resultString = JsonHelper.Serialize(scanResult); + DispatchCommandResult(new PluginResult(PluginResult.Status.OK, resultString)); + } + } +} diff --git a/src/wp/BarcodeScannerResult.cs b/src/wp/BarcodeScannerResult.cs new file mode 100644 index 0000000..33115db --- /dev/null +++ b/src/wp/BarcodeScannerResult.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BarcodeScanner +{ + public class BarcodeScannerResult + { + public string format + { + get; + set; + } + + public string text + { + get; + set; + } + } +} diff --git a/src/wp/Scan.xaml b/src/wp/Scan.xaml new file mode 100644 index 0000000..af9f5ef --- /dev/null +++ b/src/wp/Scan.xaml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/wp/Scan.xaml.cs b/src/wp/Scan.xaml.cs new file mode 100644 index 0000000..d9bc14d --- /dev/null +++ b/src/wp/Scan.xaml.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Navigation; +using Microsoft.Phone.Controls; +using Microsoft.Phone.Shell; +using Microsoft.Devices; +using System.Windows.Threading; +using System.Windows.Media.Imaging; +using ZXing; + +namespace BarcodeScanner +{ + public partial class Scan : PhoneApplicationPage + { + private PhotoCamera phoneCamera; + private IBarcodeReader barcodeReader; + private DispatcherTimer scanTimer; + private WriteableBitmap previewBuffer; + + private string scannedCode = string.Empty; + + private bool scanSucceeded; + + public Scan() + { + InitializeComponent(); + } + + public Cordova.Extension.Commands.BarcodeScanner BarcodeScannerPlugin + { + get; + set; + } + + protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) + { + // Initialize the camera object + phoneCamera = new PhotoCamera(); + phoneCamera.Initialized += OnCameraInitialized; + + CameraButtons.ShutterKeyHalfPressed += OnCameraButtonShutterKeyHalfPressed; + + //Display the camera feed in the UI + viewfinderBrush.SetSource(phoneCamera); + + + // This timer will be used to scan the camera buffer every 250ms and scan for any barcodes + scanTimer = new DispatcherTimer(); + scanTimer.Interval = TimeSpan.FromMilliseconds(250); + scanTimer.Tick += (o, arg) => ScanForBarcode(); + + base.OnNavigatedTo(e); + } + + private void OnCameraButtonShutterKeyHalfPressed(object sender, EventArgs e) + { + phoneCamera.Focus(); + } + + protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e) + { + scanTimer.Stop(); + + if (phoneCamera != null) + { + phoneCamera.Dispose(); + phoneCamera.Initialized -= OnCameraInitialized; + CameraButtons.ShutterKeyHalfPressed -= OnCameraButtonShutterKeyHalfPressed; + } + + if (!scanSucceeded) + { + BarcodeScannerPlugin.OnScanFailed("Cancelled by user"); + } + } + + void OnCameraInitialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e) + { + if (e.Succeeded) + { + this.Dispatcher.BeginInvoke(delegate() + { + phoneCamera.FlashMode = FlashMode.Off; + previewBuffer = new WriteableBitmap((int)phoneCamera.PreviewResolution.Width, (int)phoneCamera.PreviewResolution.Height); + + barcodeReader = new BarcodeReader(); + + // By default, BarcodeReader will scan every supported barcode type + // If we want to limit the type of barcodes our app can read, + // we can do it by adding each format to this list object + + //var supportedBarcodeFormats = new List(); + //supportedBarcodeFormats.Add(BarcodeFormat.QR_CODE); + //supportedBarcodeFormats.Add(BarcodeFormat.DATA_MATRIX); + //_bcReader.PossibleFormats = supportedBarcodeFormats; + + barcodeReader.Options.TryHarder = true; + + barcodeReader.ResultFound += OnBarcodeResultFound; + scanTimer.Start(); + }); + } + else + { + Dispatcher.BeginInvoke(() => + { + BarcodeScannerPlugin.OnScanFailed("Unable to initialize the camera"); + }); + } + } + + private void OnBarcodeResultFound(Result obj) + { + if (BarcodeIsValid(obj.Text)) + { + var barcodeScannerResult = new BarcodeScannerResult(); + barcodeScannerResult.format = obj.BarcodeFormat.ToString(); + barcodeScannerResult.text = obj.Text; + scanSucceeded = true; + + BarcodeScannerPlugin.OnScanSucceeded(barcodeScannerResult); + NavigationService.GoBack(); + } + } + + private bool BarcodeIsValid(string barcode) + { + if (barcode.Equals(scannedCode)) + { + return false; + } + + return true; + } + + private void ScanForBarcode() + { + //grab a camera snapshot + phoneCamera.GetPreviewBufferArgb32(previewBuffer.Pixels); + previewBuffer.Invalidate(); + + //scan the captured snapshot for barcodes + //if a barcode is found, the ResultFound event will fire + barcodeReader.Decode(previewBuffer); + } + } +} \ No newline at end of file diff --git a/www/barcodescanner.js b/www/barcodescanner.js index 42b587c..a86990a 100644 --- a/www/barcodescanner.js +++ b/www/barcodescanner.js @@ -6,6 +6,7 @@ * Copyright (c) 2011, IBM Corporation */ + var ScannerLoader = function (require, exports, module) { var exec = require("cordova/exec"); @@ -85,3 +86,12 @@ var barcodeScanner = new BarcodeScanner(); module.exports = barcodeScanner; + } + + ScannerLoader(require, exports, module); + + cordova.define("cordova/plugin/BarcodeScanner", ScannerLoader); + + + +