Home » Android » xamarin.android – card.io Mono for Android (Xamarin Studio)

xamarin.android – card.io Mono for Android (Xamarin Studio)

Posted by: admin June 16, 2020 Leave a comment

Questions:

Has anybody successfully created a card.io wrapper they’re willing to share that can be used in a Mono for Android application or can somebody shed some light on what I’m doing wrong?

  1. Create a new Android Java Bindings Library Project
  2. Add the .jar and .so files from card.io SDK 3.0.3, be sure to use the existing folder structure
  3. Add the following to Transforms/EnumMethods.xml to resolve a compiler error:

    <mapping jni-class="io/card/payment/CardIOActivity">
        <method jni-name="onActivityResult" parameter="p1" clr-enum-type="Android.App.Result" />
    </mapping>
    
  4. Add a reference to the above Library in my main application

Everything compiles and I can access the card.io classes:

using IO.Card.Payment;

private void WireupScanCardButton()
{
    Log.Debug(this.GetType().Name, "WireupScanCardButton");

    this.ScanCardButton.Click += delegate 
    {
        Log.Debug(this.GetType().Name, "ScanCard.Click");

        var intent = new Intent(this, typeof(CardIOActivity));

        // Required for authentication with card.io
        intent.PutExtra(CardIOActivity.ExtraAppToken, "<MY PRIVATE TOKEN HERE>");

        // Customize these values to suit your needs.
        intent.PutExtra(CardIOActivity.ExtraNoCamera, false);
        intent.PutExtra(CardIOActivity.ExtraSuppressManualEntry, true);
        intent.PutExtra(CardIOActivity.ExtraRequireExpiry, false);
        intent.PutExtra(CardIOActivity.ExtraRequireCvv, false);
        intent.PutExtra(CardIOActivity.ExtraRequireZip, false);

        // Run the Activity
        this.StartActivityForResult(intent, 0);            
    };
}

However, I am always presented with the following error:

this device can not use camera to read card numbers

NOTES:

  • I have tried running on several different physical devices
  • the card.io.jar file has a Build Action of: EmbeddedJar
  • the .so files have a Build Action of: EmbeddedNativeLibrary
  • I’ve explicitly set the Abi for each .so file in the Project ItemGroup

I’m very new to Android/Xamarin, so spend more time researching than coding.

The .so files do not appear to be in the .apk file

Edit:

The .so files do seem to get picked up by the compiler.
After compilation, if I check the obj/Release/ folder there is a subfolder native_library_imports that contains the .so files in appropriate subfolders according to the supported Abi type.

However, the .so files still do not appear in the final .apk file.

logcat output:

04-18 08:12:20.462 D/ActivityAddPaymentSource( 5824): ScanCard.Click
04-18 08:12:20.472 E/ActivityManager(  191): exception bw.write()java.io.IOException: Transport endpoint is not connected
04-18 08:12:20.472 I/ActivityManager(  191): Starting: Intent { cmp=com.onetab.android/io.card.payment.CardIOActivity (has extras) } from pid 5824
04-18 08:12:20.472 D/PowerManagerService(  191): acquireWakeLock flags=0x1 tag=ActivityManager-Launch
04-18 08:12:20.492 D/ActivityAddPaymentSource( 5824): OnPause
04-18 08:12:20.492 E/Sensors (  191): GsSensor: line +83 ~~~handle===0~~en==1~~!n
04-18 08:12:20.502 E/Sensors (  191): GsSensor::setDelay: line +113 ~~~handle===0~~ns==1553152~~!n
04-18 08:12:20.502 E/Sensors (  191): GsSensor::setDelay: line +113 ~~~handle===0~~ns==-2135896001~~!n
04-18 08:12:20.542 W/card.io ( 5824): cardioScanErrorNoDeviceSupport: This device cannot use the camera to read card numbers.
04-18 08:12:20.572 E/ActivityManager(  191): exception bw.write()java.io.IOException: Transport endpoint is not connected
04-18 08:12:20.572 D/PowerManagerService(  191): acquireWakeLock flags=0x1 tag=ActivityManager-Launch
04-18 08:12:20.582 E/Sensors (  191): GsSensor: line +83 ~~~handle===0~~en==0~~!n
04-18 08:12:20.622 D/ActivityAddPaymentSource( 5824): OnResume

thanks

How to&Answers:

The Android logcat should show a more specific error message, but this problem is due to missing native libraries. (For normal Android projects these live in the /libs directory, with architecture specific subdirectories.)

These are the .so files that you mention are missing from the .apk. They contain all of the image processing logic, so card.io can’t scan if they are not there.

Answer:

Well, I finally resolved this after some experimentation.

  1. Follow the 4 steps in my original post
  2. Extract the card.io SDK to the root of the library project so you end up with a folder structure of: ProjectRoot/libs/<the sdk files and abi subfolders>
  3. Add the .jar file to the Project Jars folder (select the add a link option)
  4. Add the libs folder to the root of your project (excluding the .jar file)
  5. You may need to manually edit the .csproj file to add the Abi target of each .so file
  6. Ensure the .jar file has a Build action of EmbeddedJar
  7. Ensure the .so files have a Build action of EmbeddedNativeLibrary

@tomwhipple – thanks for the contribution. I tried to upvote your answer but apparently I don’t have enough reputation.