Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zxing integration into monodroid app

I'm trying to integrate ZXing's barcode scanner into a MonoDroid application. I see that normal Android (java) apps have IntentIntegration.java and IntentResult.java to include into their project to help. I was wondering if anyone has ported those to .NET (I didn't see them ported in the csharp project.)? I'm also wondering if anyone has implemented ZXing in another way to get to work with their app? If anyone has integrated with MonoDroid, what needs to be done to initiate a scan in a button click handler?

Also, if anyone has any other 3 party barcode scanner that could be implemented instead, put those suggestions in the comments.

like image 620
thames Avatar asked Apr 10 '11 21:04

thames


People also ask

What is this ZXing project?

The project is loosely based on the ZXing Android Barcode Scanner application, but is not affiliated with the official ZXing project. Can be used via Intents (little code required). Can be embedded in an Activity, for advanced customization of UI and logic. Scanning can be performed in landscape or portrait mode.

What are the minimum SDK versions supported by ZXing?

By default, only SDK 24+ will work, even though the library specifies 19 as the minimum version. For SDK versions 19+, one of the changes below are required. Some older SDK versions below 19 may work, but this is not tested or supported. Option 1. Downgrade zxing:core to 3.3.0

What version of ZXing core should I downgrade to?

Option 1. Downgrade zxing:core to 3.3.0 This option does not require changing library versions, but may complicate the build process. This requires Android Gradle Plugin version 4.0.0 or later. See Java 8+ API desugaring support. SDK 19+ additionally requires multiDex.


1 Answers

The first question is, do you actually need to port those files? :-)

You can include Java source code into a Mono for Android project; just set the Build action to AndroidJavaSource and the source will be compiled into the resulting .apk. This can also be done with .jar files.

Then comes the question of invoking the Java code from C#.

In the case of IntentIntegration.java and IntentResult.java, that may be enough, as those types don't support inheritance (they're final). Granted, using JNIEnv to invoke methods on them would be a PITA, but it can be done:

// Untested code, provided for demo purposes:

// Handle of the Java class we're invoking
IntPtr IntentResult = 
        JNIEnv.FindClass("com/google/zxing/integration/android/IntentIntegrator");
// Handle of the method to invoke
IntPtr IntentResult_initiateScan = 
        JNIEnv.GetMethodID(IntentResult, "initiateScan", 
            "(Landroid/app/Activity;)Landroid/app/AlertDialog;");
            // method signature can be obtained from `javap -s`
// Invoke the method; return value is an AlertDialog instance
IntPtr rAlertDialog = JNIEnv.CallStaticObjectMethod (
        IntentResult, IntentResult_initiateScan, new JValue (someActivity));
// ...and construct a nice managed wrapper over the Java instance.
AlertDialog alertDialog = new AlertDialog (rAlertDialog);

Furthermore, the IntentIntegrator docs mention that the Activity provided must override the Activity.OnActivityResult method.

All that said, porting IntentIntegrator.java shouldn't be that difficult, as most of it is a wrapper over Activity.StartActivityForResult with an appropriate intent and construction of an AlertDialog (which you may or may not need).

like image 121
jonp Avatar answered Sep 22 '22 06:09

jonp