如何在Titanium中分步实现跨Android/iOS的条码扫描器(基于ZXing等库)
Got it, let's walk through building a cross-platform barcode scanner for Android and iOS using Titanium (with ZXing under the hood) that can scan barcodes, capture the data, and bind it directly to a text field. I'll break this into straightforward steps so you can follow along without hassle.
First things first—make sure you have a Titanium project up and running (new or existing). We'll use the @titanium/zxing module: it's maintained, cross-platform, and built on ZXing, so it's perfect for our needs.
To install it, open your project folder in terminal and run:
npm install @titanium/zxing --save
Double-check your tiapp.xml to ensure the module is referenced (npm usually handles this automatically, but it's good to confirm):
<modules> <module>@titanium/zxing</module> </modules>
Let's create a simple UI with a text field to display scanned data and a button to trigger the scanner. I'll use Alloy for this example (it's cleaner for UI structure), but I'll also include a pure JS alternative if you prefer that.
Alloy XML (index.xml)
<Alloy> <Window class="container"> <TextField id="barcodeInput" hintText="Scanned barcode will appear here" editable="false" /> <Button id="scanButton" title="Scan Barcode" onClick="handleScan" /> </Window> </Alloy>
Alloy Controller (index.js)
Start by importing the ZXing module at the top:
const zxing = require('@titanium/zxing');
Now let's write the handleScan function that triggers the scanner, captures the result, and binds it to our text field. We'll also handle camera permissions first—this is critical for both platforms to avoid crashes.
Add this to your index.js:
function handleScan() { // Request camera permissions if not already granted Ti.Media.requestCameraPermissions(function(e) { if (e.success) { // Launch the barcode scanner zxing.scan({ formats: [zxing.FORMAT_ALL_CODE_TYPES], // Scan all barcode types (adjust if needed) showCancel: true, showFlipCamera: true, success: function(result) { // Bind scanned data to the text field $.barcodeInput.value = result.text; alert(`Scanned successfully: ${result.text}`); }, error: function(error) { if (error.code === zxing.CANCELLED) { alert("Scan cancelled"); } else { alert(`Scan error: ${error.message}`); } } }); } else { alert("Camera permission is required to scan barcodes"); } }); } $.index.open();
Pure JS Equivalent (No Alloy)
If you're working with plain Titanium JS, here's how to build the UI and logic:
const zxing = require('@titanium/zxing'); const win = Ti.UI.createWindow({ backgroundColor: '#fff' }); const barcodeInput = Ti.UI.createTextField({ hintText: 'Scanned barcode will appear here', editable: false, top: 50, left: 20, right: 20, height: 40 }); const scanButton = Ti.UI.createButton({ title: 'Scan Barcode', top: 110, left: 20, right: 20, height: 40 }); scanButton.addEventListener('click', function() { Ti.Media.requestCameraPermissions(function(e) { if (e.success) { zxing.scan({ formats: [zxing.FORMAT_ALL_CODE_TYPES], success: function(result) { barcodeInput.value = result.text; alert(`Scanned: ${result.text}`); }, error: function(error) { alert(error.code === zxing.CANCELLED ? "Cancelled" : `Error: ${error.message}`); } }); } else { alert("Need camera permission to scan"); } }); }); win.add(barcodeInput); win.add(scanButton); win.open();
You need to add permission declarations to tiapp.xml to avoid runtime errors on both platforms:
Android Permissions
Add these inside the <android> section:
<android xmlns:android="http://schemas.android.com/apk/res/android"> <manifest> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> </manifest> </android>
iOS Permissions
Add this inside the <ios> section to explain why you need camera access (required for iOS 10+):
<ios> <plist> <dict> <key>NSCameraUsageDescription</key> <string>We need access to your camera to scan barcodes</string> </dict> </plist> </ios>
- Android: You can test on an emulator (enable camera emulation in settings) or a physical device.
- iOS: Emulators don't have working cameras, so you'll need a physical iOS device to test the scanning functionality.
- Scanner won't launch? Double-check the module is installed correctly and permissions are set in
tiapp.xml. - Slow scanning? Try narrowing down barcode formats (e.g., use
zxing.FORMAT_QR_CODEinstead ofFORMAT_ALL_CODE_TYPESif you only need QR codes). - Permission errors? Don't skip the permission request step—modern OSes block camera access unless explicitly granted by the user.
内容的提问来源于stack exchange,提问作者faizal

