Xamarin的独特之处在于,它提供了一种单一的语言——c#、类库和运行时,可以在iOS、Android和Windows Phone这三个移动平台上运行(Windows Phone的原生语言已经是c#),同时仍然编译本地(非解释性的)应用程序,即使对要求高的游戏也足够高性能。
这些平台中的每一个都有不同的特性集,而且它们编写本机应用程序的能力也各不相同——也就是说,这些应用程序可以编译成本机代码,并且能够与底层Java子系统流畅地互操作。例如,有些平台只允许用HTML和JavaScript构建应用程序,而有些平台非常低级,只允许C/ c++代码。有些平台甚至不使用本机控制工具包。
Xamarin的独特之处在于,它结合了本地平台的所有功能,并添加了许多强大的功能,包括:
Xamarin提供两种商业产品:Xamarin。iOS和xamarin, android。它们都建在上面莫诺,一个基于已发布的。net ECMA标准的。net框架的开源版本。Mono存在的时间几乎和。net框架本身一样长,并且可以运行在几乎所有可以想象到的平台上,包括Linux、Unix、FreeBSD和Mac OS X。
iOS平台是Xamarin提前(AOT编译器编译Xamarin。iOSapplications directly to native ARM assembly code. On Android, Xamarin’s compiler compiles down to中间语言(伊尔),即当时即时(JIT)在应用程序启动时编译为本机程序集。
在这两种情况下,Xamarin应用程序都利用运行时自动处理内存分配、垃圾收集、底层平台互操作等。
Xamarin的。形式is a framework that allows developers to rapidly create cross platform user interfaces. It provides it's own abstraction for the user interface that will be rendered using native controls on iOS, Android, Windows, or Windows Phone. This means that applications can share a large portion of their user interface code and still retain the native look and feel of the target platform.
Xamarin的。形式allows for rapid prototyping of applications that can evolve over time to complex applications. Because Xamarin.Forms applications are native applications, they don't have the limitations of other toolkits such as browser sandboxing, limited APIs, or poor performance. Applications written using Xamarin.Forms are able to utilize any of the API’s or features of the underlying platform, such as (but not limited to) CoreMotion, PassKit, and StoreKit on iOS; NFC and Google Play Services on Android; and Tiles on Windows. In addition, it's possible to create applications that will have parts of their user interface created with Xamarin.Forms while other parts are created using the native UI toolkit.
Xamarin的。形式applications are architected in the same way as traditional cross-platform applications. The most common approach is to use便携式图书馆或共享项目以容纳共享代码,并创建将使用共享代码的特定于平台的应用程序。
在Xamarin.Forms中有两种创建用户界面的技术。第一种技术是完全使用c#源代码创建ui。第二个技巧是使用可扩展应用程序标记语言(XAML),一种用于描述用户界面的声明性标记语言。有关XAML的更多信息,请参见XAML基础知识.
要开始开发Xamarin应用程序,首先需要安装Visual Studio或Xamarin Studio,并确保包含所有必要的Xamarin组件。在我们的示例中,我们将使用Visual Studio向您展示如何开发Xamarin应用程序并使用我们的SDK。导航到这个链接逐步阅读如何下载和安装Xamarin应用程序的Visual Studio。
在接下来的章节中,我们将解释如何一步一步地开发我们的示例应用程序。
打开Visual Studio,按照以下步骤操作:
1.去File ->新建->项目。
2.创建空白应用(Android)。
加载新项目时,添加对XamarinDataManLibrary.dll文件的引用。
在创建一个空白应用程序后,创建你将使用的所有资源(图标、图像、样式、布局等)。必威随行版官网你可以从我们的样品中复制它们。
接下来右键单击项目文件,然后单击属性,然后进入Android Manifest部分。
设置你的Manifest文件(应用程序名称,应用程序图标,最小和最大安卓版本),确保为这个应用程序启用相机权限。
在设置了一些必要的属性之后,可以创建ScannerActivity这将是MainLauncher,并继承一些接口。
[Activity(Label = "@string/app_name", MainLauncher = true, Icon = "@drawable/ic_launcher", ScreenOrientation = ScreenOrientation. portrait)]公共类ScannerActivity: Activity, IOnConnectionCompletedListener, IReaderDeviceListener, Android.Support.V4.App.ActivityCompat。IOnRequestPermissionsResultCallback {private static int REQUEST_PERMISSION_CODE = 12322;private ListView;private TextView tvConnectionStatus;private Button btnScan;private RelativeLayout rlPreviewContainer;私有ImageView ivPreview;private List resultList;private JavaList< dictionary > resultListData;private ResultListViewAdapter;public static int listViewResultSelectedItem = -1; private bool isScanning = false; private static ReaderDevice readerDevice; private enum DeviceType { MX, PHONE_CAMERA } private static bool isDevicePicked = false; private static DeviceType param_deviceType = DeviceType.PHONE_CAMERA; private static bool dialogAppeared = false; private static string selectedDevice = ""; private bool listeningForUSB = false; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.activity_scanner); ......
在这里,我们将定义一些UI元素和变量,稍后将在活动中使用:
tvConnectionStatus- TextView当前连接状态的UI元素;
listViewResult- ListView一个UI元素的结果将读取;
btnScan-按钮一个UI元素将触发readerDevice。StartScanning或readerDevice。StopScanning;
rlPreviewContainer- ViewGroup (RelativeLayout)容器的相机预览;
ivPreview- ImageView控件与匹配大小作为其父显示预览或扫描会话的最后一帧;
ReaderDevicecmbSDK对象将呈现MX设备或手机摄像头取决于我们的配置;
每次活动开始时,我们都调用initDevice我们在这里配置阅读器设备对象。
如果我们想使用MX设备进行扫描,我们可以使用:
readerDevice = GetMXDevice(此);if (!listeningForUSB) {readerDevice.StartAvailabilityListening();listeningForUSB = true;}
MX设备的可用性可以在设备转动时发生变化在或从,或连接USB线或断开连接,这由IReaderDeviceListener接口。
如果我们想将阅读器设备配置为手机摄像头,我们可以使用:
readerDevice = GetPhoneCameraDevice(这个,CameraMode。NoAimer PreviewOption。违约,rlPreviewContainer);
CameraMode参数为类型CameraMode(定义在CameraMode.java),并接受以下值之一:
PASSIVE_AIMER:初始化阅读器以使用无源瞄准器,无源瞄准器是连接到移动设备或移动设备外壳上的附件,使用移动设备的内置LED闪光灯作为光源,以投射瞄准模式。在这种模式下,设备屏幕上不会显示实时流预览,因为瞄准模式将被投影。
FRONT_CAMERA:初始化阅读器以使用设备的移动前置摄像头(如果可用的话)(并非所有移动设备都有前置摄像头)。这是一种不寻常但可能的结构。大多数前置摄像头没有自动对焦和照明功能,提供的图像分辨率也明显较低。这个选项应该谨慎使用。在这种模式下,照明是不可用的。
以上所有模式都为读者提供以下默认设置:
根据所选择的模式,将设置以下附加选项和行为:
的PreviewOption参数是的类型PreviewOption(定义在PreviewOption.java),并用于更改读取器的默认值或覆盖从选定对象派生的默认值CameraMode.在传递参数时,可以通过OR-ing指定多个选项。可用的选项有:
配置完ReaderDevice我们需要连接到设备上。
在我们建立联系之前ReaderDeviceListener对象的设置是为了接收事件:
readerDevice.SetReaderDeviceListener(这个);
此外,您可以通过以下方式启用从阅读器发送最后触发的图像和SVG:
readerDevice.EnableImage(真正的);readerDevice.EnableImageGraphics(真正的);
然后我们可以连接:
readerDevice.Connect(这个);
将被调用的事件是:
OnConnectionCompleted(ReaderDevice reader, Throwable error)
方法中的参数抛出错误,如果在尝试连接时出现错误OnConnectionCompleted方法,否则,如果没有发生错误,则error参数将为零.
如果连接成功,则语句读者。ConnectionState == ConnectionState。连接将是真的。
有几个API方法可以更改一些公共属性来配置连接的设备,当ConnectionState是连接。
例如,如果移动相机被用作一个ReaderDevice有默认情况下不启用任何符号.控件中要使用的符号必须启用SetSymbologyEnabledAPI方法:
readerDevice.SetSymbologyEnabled(象征。C128, true, null);readerDevice.SetSymbologyEnabled(象征。数据矩阵,true, null);readerDevice.SetSymbologyEnabled(象征。UpcEan, true, null);readerDevice.SetSymbologyEnabled(象征。Qr, true, null);
您可以直接通过向连接的设备发送命令来完成同样的操作:
readerDevice.DataManSystem。SendCommand(“设置标志。MICROPDF417”);
有了正确配置的读取器,现在就可以扫描条形码了。可以通过调用startScanning方法。ReaderDevice对象。
接下来会发生什么是基于类型ReaderDevice以及它是如何配置的,但总的来说
当满足下列条件之一时,扫描停止:
当条形码被成功解码(第一种情况)时,您将收到一个ReadResults对象中的可迭代结果集合对象ReaderDevice侦听器方法。
OnReadResultReceived(ReaderDevice阅读器,ReadResults结果){listViewResultSelectedItem = -1;resultList.Clear ();resultListData.Clear ();ivPreview.SetImageBitmap(空);如果结果。SubResults!= null && results.SubResults.Count > 0) { foreach (ReadResult subResult in results.SubResults) { if (subResult.IsGoodRead) { resultList.Add(subResult); JavaDictionary item = new JavaDictionary(); item.Add("resultText", subResult.ReadString); Symbology sym = subResult.Symbology; if (sym != null) item.Add("resultType", subResult.Symbology.Name); else item.Add("resultType", "UNKNOWN SYMBOLOGY"); resultListData.Add(item); listViewResultSelectedItem = resultListData.Count - 1; } else { resultList.Add(subResult); JavaDictionary item = new JavaDictionary(); item.Add("resultText", "NO READ"); item.Add("resultType", ""); resultListData.Add(item); listViewResultSelectedItem = resultListData.Count - 1; } if (subResult.Image != null) { ivPreview.SetImageBitmap(renderSvg(subResult.ImageGraphics, subResult.Image)); } else { if (subResult.ImageGraphics != null) { ivPreview.SetImageBitmap(renderSvg(subResult.ImageGraphics, ivPreview.Width, ivPreview.Height)); } else ivPreview.SetImageBitmap(null); } } } else if (results.Count > 0) { ReadResult result = results.GetResultAt(0); if (result.IsGoodRead) { resultList.Add(result); JavaDictionary item = new JavaDictionary(); item.Add("resultText", result.ReadString); Symbology sym = result.Symbology; if (sym != null) item.Add("resultType", result.Symbology.Name); else item.Add("resultType", "UNKNOWN SYMBOLOGY"); resultListData.Add(item); listViewResultSelectedItem = resultListData.Count - 1; } else { resultList.Add(result); JavaDictionary item = new JavaDictionary(); item.Add("resultText", "NO READ"); item.Add("resultType", ""); resultListData.Add(item); listViewResultSelectedItem = resultListData.Count - 1; } if (result.Image != null) { ivPreview.SetImageBitmap(renderSvg(result.ImageGraphics, result.Image)); } else { if (result.ImageGraphics != null) { ivPreview.SetImageBitmap(renderSvg(result.ImageGraphics, ivPreview.Width, ivPreview.Height)); } else ivPreview.SetImageBitmap(null); } } isScanning = false; btnScan.Text = "START SCANNING"; resultListAdapter.NotifyDataSetChanged(); }
结果。图像是来自扫描过程的最后一帧,它将显示在ivPreviewImageView,而且结果。图像Graphics是SVG图像,定位条形码的图像。
在ScannerActivity我们重写OnPause和原事件,所以我们可以断开连接和StopAvailabilityListening当我们从该活动导航或销毁该活动时释放所有连接。
OnPause() {base.OnPause();if (readerDevice != null) {readerDevice. disconnect ();}} protected override void OnStop() {if (readerDevice != null) try {readerDevice. stopavailabilitylistening ();} catch(系统。异常e) {} listeningForUSB = false;base.OnStop ();}
请记住,可能会出现由于电池电量不足或手动断开电缆而导致设备断开的情况。
如果您计划使用cmbSDK使用智能手机或平板电脑(没有MX移动终端)进行移动扫描,SDK需要安装许可密钥。没有许可密钥,SDK仍将运行,尽管扫描结果将被模糊化(SDK将随机地将扫描结果中的字符替换为星号字符)。
请与您的康耐视销售代表联系,了解如何获取许可证密钥,包括可用于30天评估SDK的试用许可证。
获得许可密钥后,有两种方法可以在应用程序中添加许可密钥。
第一个是将它作为一个元标签添加到你的manifest文件中的application tag中:
.....
第二种方法是直接从代码实现激活。当你创建readerDevice时,在构造函数中设置许可密钥作为输入参数:
...readerDevice = GetPhoneCameraDevice(这个,CameraMode。NoAimer PreviewOption。违约,rlPreviewContainer,"YOUR_MX_MOBILE_LICENSE");
扫描成功后添加声音“哔”,请使用以下代码:
它在MX设备上播放音频信号。
连接和断开MX设备的过程是通过连接/断开方法完成的
将尝试连接到设备。当Connect ()执行时,我们得到动作的状态OnConnectionCompleted侦听器
OnConnectionCompleted(ReaderDevice reader,Throwable error){if(error != null){//处理错误readerDisconnected();}}
将与MX设备断开连接。
例子:
readerDevice = readerDevice . getmxdevice (mContext);readerDevice.StartAvailabilityListening ();readerDevice.SetReaderDeviceListener(这个);readerDevice.EnableImage(真正的);readerDevice.Connect(这个);...
public void OnAvailabilityChanged(ReaderDevice reader) {if (reader. getavailability () == availabilityavailable . available) {ReaderDevice . connect (this);}……
成功扫描的结果可以返回图像。这是在一次成功扫描中解析的最后一帧。要启用/禁用此功能,我们可以使用API方法:
readerDevice =读写设备。GetPhoneCameraDevice (mContext CameraMode。NoAimer PreviewOption。违约,rlMainContainer); readerDevice.EnableImage(true); readerDevice.Connect(this);
成功扫描的结果可以返回SVG图像图形。这是在一次成功扫描中解析的最后一帧。要启用/禁用此功能,我们可以使用API方法:
readerDevice =读写设备。GetPhoneCameraDevice (mContext CameraMode。NoAimer PreviewOption。违约,rlMainContainer); readerDevice.EnableImageGraphics(true); readerDevice.Connect(this);
在我们可以连接MX设备之前,我们需要知道是否有可用的MX设备来完成这项任务。
它返回可用性对象。可用,不可用或未知的
当有USB连接到我们的智能手机时,MX设备是可用的。
public void OnAvailabilityChanged(ReaderDevice reader) {if (reader. getavailability () == availabilityavailable . available) {ReaderDevice . connect (this);}……
如果我们想检查MX设备的电池电量,我们可以使用
中的输入参数检索读取器设备的当前电池百分比水平OnDeviceBatteryLevelReceived侦听器方法
公共无效OnConnectionStateChanged(ReaderDevice reader) {if(阅读器。ConnectionState == ConnectionState。连接){ reader.GetDeviceBatteryLevel(this); ......... } } public void OnDeviceBatteryLevelReceived(ReaderDevice p0, int p1, Throwable p2) { int batteryLevel = p1; }
如果我们想检查MX设备的所有灯是否都打开或关闭
检索阅读器设备的灯是否作为输入参数打开或关闭OnLightsOnCompleted侦听器方法
用来打开或关闭MX设备的灯
公共无效OnConnectionStateChanged(ReaderDevice reader) {if(阅读器。ConnectionState == ConnectionState。连接){ reader.IsLightsOn(this); ......... } } public void OnLightsOnCompleted(ReaderDevice p0, Java.Lang.Boolean p1, Throwable p2) { bool lightsON = p1.BooleanValue(); }
如果我们想检查一些符号是启用或禁用,我们可以使用
中启用或禁用符号作为输入参数时检索OnSymbologyEnabled侦听器方法
来启用我们使用的特定符号
公共无效OnConnectionStateChanged(ReaderDevice reader) {if(阅读器。ConnectionState == ConnectionState。连接){ reader.IsSymbologyEnabled(Symbology.Azteccode, this); ......... } } public void OnSymbologyEnabled(ReaderDevice p0, Symbology p1, Java.Lang.Boolean p2, Throwable p3) }
将MX设备配置设置重置为默认使用
在OnResetConfigCompleted我们可以通过检查Throwable输入参数error是否为null来检查重置是否成功
public void OnResetConfigCompleted(ReaderDevice p0, Throwable p1) {if (p1 != null)重置不成功。Error: " + p1.Message ";}
注册侦听器函数OnAvailabilityChanged,OnConnectionStateChanged而且OnReadResultReceived我们需要在尝试连接到阅读器设备之前调用这个方法
public void OnAvailabilityChanged(ReaderDevice reader) {if (reader. getavailability () == availabilityavailable . available) {ReaderDevice . connect (this);}}
公共无效OnConnectionStateChanged(ReaderDevice reader) {if(阅读器。ConnectionState == ConnectionState. connected) {} else if(读取器。ConnectionState == ConnectionState. disconnected) {}}
public void OnReadResultReceived(ReaderDevice阅读器,ReadResults结果){if(结果。Count > 0) {ReadResult result = results.GetResultAt(0);if (result.IsGoodRead){…
例子
readerDevice =读写设备。GetPhoneCameraDevice (mContext CameraMode。NoAimer PreviewOption。违约,rlMainContainer); readerDevice.SetReaderDeviceListener(this); readerDevice.Connect(this);
我们打完电话后readerDevice。SetReaderDeviceListener (IReaderDeviceListener listenerObject)方法和寄存器OnAvailabilityChanged监听器功能,我们可以启动/停止可用性监听
将开始监听阅读器设备的可用性,并将触发监听器功能,每当可用性发生变化
将停止监听阅读器设备的可用性
例子:
readerDevice = readerDevice . getmxdevice (mContext);readerDevice.StartAvailabilityListening ();readerDevice.SetReaderDeviceListener(这个);readerDevice.Connect(这个);
protected override void处置(bool处置){if (readerDevice != null && readerDevice. null)ConnectionState == ConnectionState。连接){ readerDevice.SetReaderDeviceListener(null); readerDevice.Disconnect(); } if (readerDevice != null) try { readerDevice.StopAvailabilityListening(); } catch (System.Exception e) { } base.Dispose(disposing); }
在我们连接和配置我们的阅读器设备,并设置我们需要的所有设置后,我们可以开始扫描过程。
开始扫描我们使用方法
当我们的阅读器成功扫描某些条形码时,扫描过程将停止,或者我们可以用这种方法手动停止扫描
当扫描停止时,无论是使用成功的扫描还是使用stopScanning()方法OnReadResultReceived监听器函数将被调用,我们可以检查扫描结果
public void OnReadResultReceived(ReaderDevice阅读器,ReadResults结果){if(结果。Count > 0) {ReadResult result = results.GetResultAt(0);if (result.IsGoodRead) {symm = result. symology;if (sym != null) {tvsymology。Text = symm . name;} else {tvsymology。文本= "未知的符号学";} tvCode。Text = result.ReadString;} else {tvsymology。Text = "NO READ";tvCode。Text = ""; } ivPreview.SetImageBitmap(result.Image); } }
在接下来的章节中,我们将解释如何一步一步地开发我们的示例应用程序。
打开Visual Studio,按照以下步骤操作:
1.去File ->新建->项目。
2.创建空白App (iPhone)。
加载新项目时,添加引用XamarinDataManLibrary.dll文件。
接下来打开你的Info.plist文件和设置一些项目属性为您的需要(应用程序名称,部署目标,主界面等)。
这里重要的是为这个应用程序添加相机权限。在Visual Studio中,没有从这里添加此权限的选项。你需要打开你的Info.plist在一些文本编辑器中文件并添加以下行:
NSCameraUsageDescription 用于扫描的摄像头
此外,如果你使用MX设备作为阅读器设备,请在Info.plist中添加以下协议:
UISupportedExternalAccessoryProtocols com.cognex。Dmcc com.demo.data . Dmcc com.demo.data
的ViewController将是我们的第一个控制器Main.storyboard.这里我们正在创建一些UI元素和变量,稍后将在该控制器中使用。
公共部分类ViewController: UIViewController, ICMBReaderDeviceDelegate {protected ViewController(IntPtr句柄):base(句柄){//注意:这个.ctor不应该包含任何初始化逻辑。} CMBReaderDevice阅读器设备;public bool isScanning = false;private NSMutableArray tableData;private MXResultsTableSource tableSource;public override void ViewDidLoad() {base.ViewDidLoad();...
lblConnection-为当前连接状态标记UI元素。
tableSource- UITableViewSource用于读取结果。
btnScan-按钮UI元素将触发StartScanning或StopScanning.
ivPreview-ImageViewUI元素,用于显示预览或扫描会话的最后一帧。
CMBReaderDevice- cmbSDK对象将显示MX设备或手机摄像头取决于我们的配置。
这里我们重写那些有点方法在此视图出现时配置读取器设备对象。
如果我们想使用MX设备进行扫描,我们正在使用
readerDevice = CMBReaderDevice.ReaderOfMXDevice();
MX设备的可用性可能会在设备打开或关闭时发生变化,或者如果USB电缆连接或断开,并由ICMBReaderDeviceDelegate接口。我们将此接口设置为阅读器设备的属性
readerDevice。WeakDelegate = this;
让我们听下面三个事件:
AvailabilityDidChangeOfReader(CMBReaderDevice reader) public void ConnectionStateDidChangeOfReader(CMBReaderDevice reader)
如果我们想将阅读器设备配置为移动摄像头。
readerDevice = CMBReaderDevice.ReaderOfDeviceCameraWithCameraMode(CDMCameraMode. readerofdevicecamerawithcameramode)NoAimer CDMPreviewOption。违约,ivPreview);
的CameraMode参数的类型CDMCameraMode,它接受以下值之一:
以上所有模式都为读者提供以下默认设置:
根据所选择的模式,将设置以下附加选项和行为:
的previewOptions参数(类型)CDMPreviewOption)用于更改读取器的默认值或覆盖从选定对象派生的默认值CameraMode.在传递参数时,可以通过OR-ing指定多个选项。可用的选项如下:
类型的最后一个参数UIView是可选的,用作相机预览的容器。如果参数为空,将使用全屏预览。
配置后ReaderDevice我们需要连接到设备上。
readerDevice.ConnectWithCompletion((error) => {if (error != null) {new UIAlertView("Failed to connect",错误。Description, null, "OK", null).Show();}});
如果在尝试连接时出现错误,则错误将作为回调函数中的参数抛出。如果一切正常,错误参数将为空。
这个函数将触发ConnectionStateDidChangeOfReader方法。如果连接成功读者。connect state == ConnectionState. connected。
连接成功后,我们可以为ReaderDevice设置一些设置。ReaderDevice设置可以通过已经封装的函数来设置,也可以直接通过向配置的设备发送命令来设置。
例如,如果移动相机被用作阅读器设备有默认情况下不启用任何符号.控件中要使用的符号必须启用SetSymbology包装的功能。
在这个例子中,我们启用了一些符号,并设置设置来获取扫描的最后一帧ivPreview ImageView.
readerDevice.SetSymbology (CMBSymbology。DataMatrix, true,(错误)=> {if(错误!= null) {System.Diagnostics.Debug。WriteLine(" failed TO ENABLE [DataMatrix], ", error.LocalizedDescription);}});readerDevice.SetSymbology (CMBSymbology。Qr, true,(错误)=> {if(错误!= null) {System.Diagnostics.Debug。WriteLine(" failed TO ENABLE [Qr], ", error.LocalizedDescription);}});readerDevice.SetSymbology (CMBSymbology。C128, true,(错误)=> {if(错误!= null) {System.Diagnostics.Debug。WriteLine(" failed TO ENABLE [C128], ", error.LocalizedDescription);}});readerDevice.SetSymbology (CMBSymbology。UpcEan, true, (error) => { if (error != null) { System.Diagnostics.Debug.WriteLine("FALIED TO ENABLE [UpcEan], ", error.LocalizedDescription); } }); readerDevice.ImageResultEnabled = true; readerDevice.SVGResultEnabled = true; readerDevice.DataManSystem.SendCommand("SET IMAGE.SIZE 0");
有了正确配置的读取器,现在就可以扫描条形码了。可以通过调用startScanning方法。ReaderDevice对象。
接下来会发生什么取决于阅读器设备的类型以及它的配置方式,但一般来说:
当满足下列条件之一时,扫描停止:
当条形码被成功解码(第一种情况)时,您将收到一个ReadResults中的可迭代结果集合对象ReaderDevice侦听器方法。
public void DidReceiveReadResultFromReader(CMBReaderDevice reader, CMBReadResults readResults) {btnScan. resultfromreaderSetTitle("START SCANNING", UIControlState.Normal);isScanning = false;tableData.RemoveAllObjects ();如果(readResults。SubReadResults != null && readResults.SubReadResults. length > 0) {tableData.AddObjects(readResults.SubReadResults);tvResults.ReloadData ();} else if (readResults.ReadResults. readresults .}长度> 0){tableData.Add(readResults.ReadResults[0]);} tableSource.SetItems (tableData);tableSource.displayResult (0); tvResults.ReloadData(); tvResults.SelectRow(NSIndexPath.FromRowSection(0,0), false, UITableViewScrollPosition.None); }
可能会出现由于电池电量不足或手动断开电缆而导致设备断开的情况。这些情况可以通过ConnectionStateDidChangeOfReader的回调ICMBReaderDeviceDelegate.
注意:的AvailabilityDidChangeOfReader方法也会在设备物理不可用时调用。这意味着(重新)连接是不可能的。属性的可用性属性ReaderDevice对象调用ConnectWithCompletion方法。
如果您计划使用cmbSDK在智能手机或平板电脑(没有MX移动终端)上进行移动扫描,那么SDK需要安装许可密钥。如果没有许可证密钥,SDK仍将运行,尽管扫描结果将被混淆(SDK将随机地用星号替换扫描结果中的字符)。
请与您的康耐视销售代表联系,了解如何获取许可证密钥,包括可用于30天评估SDK的试用许可证。
在获得许可密钥后,有两种方法可以在应用程序中添加许可密钥。
第一个方法是将其作为具有特定于项目的值的键添加Info.plist文件:
MX_MOBILE_LICENSE 您的license密钥 . key>MX_MOBILE_LICENSE
实现激活的第二种方法是直接从代码中创建readerDevice:
....readerDevice = CMBReaderDevice.ReaderOfDeviceCameraWithCameraMode(CDMCameraMode. readerofdevicecamerawithcameramode)NoAimer CDMPreviewOption。违约,ivPreview,"YOUR_MX_MOBILE_LICE");
在可移植项目中,我们创建一个页面(主页),我们为扫描页面和一个类(CameraPreview.cs)创建了一个布局,它将继承自View控件,并具有一些属性和事件。
CameraPreview控件添加到主页:
... …
在安卓而且iOS我们有特定平台的项目自定义渲染器(ScannerView.cs),这样我们就可以在可移植项目中使用本机元素。
ViewRenderer在Android平台的特定项目:
protected override void OnElementChanged(ElementChangedEventArgs e) {base.OnElementChanged(e);if (e.o oldelement != null || Element == null){返回;} rlMainContainer = new RelativeLayout(Context);rlMainContainer.SetMinimumHeight (50);rlMainContainer.SetMinimumWidth (100);rlMainContainer。LayoutParameters = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams. layoutparams)MatchParent RelativeLayout.LayoutParams.MatchParent);ivPreview = new ImageView(Context);ivPreview.SetMinimumHeight (50);ivPreview.SetMinimumWidth (100); ivPreview.LayoutParameters = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MatchParent, RelativeLayout.LayoutParams.MatchParent); ivPreview.SetScaleType(ImageView.ScaleType.FitCenter); rlMainContainer.AddView(ivPreview); if (Control == null) SetNativeControl(rlMainContainer); MainActivity.instance.setActiveReader(Control, Element); }
在MainActivity在Android平台特定的项目中,我们处理阅读器设备对象(几乎相同)ScannerActivity为Xamarin的。安卓),从自定义渲染器,我们只是调用setActiveReader方法和传递Control(原生RelativeLayout元素)和element (CameraPreview对象,从MainPage初始化)。
ViewRenderer在iOS平台的特定项目:
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e) {base.OnElementChanged(e);if (e.o oldelement != null || Element == null){返回;} container = new UIView();ivPreview = new UIImageView();ivPreview。ContentMode = UIViewContentMode.ScaleToFill;ivSVG = new UIImageView();ivSVG。ContentMode = UIViewContentMode.ScaleToFill;container.AddSubview (ivPreview); container.AddSubview(ivSVG); ivPreview.Frame = new CoreGraphics.CGRect(0, 0, container.Frame.Size.Width, container.Frame.Size.Height); ivPreview.AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth; ivSVG.Frame = new CoreGraphics.CGRect(0, 0, container.Frame.Size.Width, container.Frame.Size.Height); ivSVG.AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth; if (Control == null) SetNativeControl(container); AppDelegate.instance.setActiveReader(Control, Element); }
在AppDelegate在iOS平台的特定项目中,我们处理阅读器设备对象(几乎相同)视图控制器为Xamarin.iOS),从自定义渲染器,我们只是调用setActiveReader方法和传递Control(本地UIImageView元素)和element (CameraPreview对象,从MainPage初始化)。
配置阅读器设备,连接设备,扫描条形码而且断开设备连接都是一样的吗Xamarin的。安卓而且Xamarin.iOS部分。