Our thinking

How to Modify Ti.Barcode to Correct Two Annoying Behaviors in iOS and Android

8 July 2013

This blog post assumes that you know how to recompile a Titanium module.

Ti.Barcode Plugin is a great way to easily integrate barcode scanning into your application. We recently used it successfully in a project, after making a few tweaks to an orientation issue.

The Titanium plugin is open source and can be downloaded from github here.

Fix iOs Orientation Issue:

The plugin doesn’t support different device orientation but the view rotates with the device.

How to lock the screen orientation?

Download and open the barcode xcode project and locate the TiBarcodeModule.m file:

Simply add the following code wherever into the file:


- (BOOL) shouldAutorotate {
    return NO;
}

That’s it! The view won’t rotate anymore.

Detect Flash and Camera on iOs and Android

By default the module doesn’t detect if the current device has a camera or an LED flash. If you try to use those features on a device that doesn’t have camera/flash capability, the plugin will cause the app to crash instead of displaying an error to the user.

Here’s what I did to handle this problem, both for iOS and Android:

iOS

To fix this download and open the project in Xcode, open the TiBarcodeModule.m file and add:

-(id)hasCamera{
    return NUMBOOL([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]);
}

-(id)hasLED{
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        return NUMBOOL([device hasTorch] && [device hasFlash]);
    }else{
        return NUMBOOL(NO);
    }
}

then locate -(void)setUseLED:(id)arg and modify as the following

-(void)setUseLED:(id)arg
{
    led = [TiUtils boolValue:arg def:NO];

    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch] && [device hasFlash] && controller != nil){
            [controller setTorch:led];
        }
    }
}

Android

Open the project in the Titanium Studio and locate and open BarcodeModule.java in /src/ti/barcode, add the following code

@Kroll.method
@Kroll.getProperty
public boolean getHasCamera() {
return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}

@Kroll.method
@Kroll.getProperty
public boolean getHasLED() {
return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}

then locate the “public void setUseLED(boolean value)” method and modify as follow:

@Kroll.method
@Kroll.setProperty
public void setUseLED(boolean value) {
if(getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
		new CameraConfigurationManager(getActivity()).setTorch(null, value);
		if (CaptureActivity.getInstance() != null) {
			CaptureActivity.getInstance().reset();
		}
	}
}

The module will now check if an LED flash is present before trying to turning it on, preventing camera-related app crashes. Additionally, this provides you with two new properties in your code:

var Barcode = require('ti.barcode');
Barcode.hasCamera //returns true or false
Barcode.hasLED //returns true or false

You can now test if the current device has a camera or a flash through the plug-in, allowing you to hide or show a “Turn on Flash” button in the barcode scanning view.

Please feel free to contact me at pierre@exygy.com if you have any questions.

Thank you for reading!