Problem binding SamsungPay SDK to Android / Can't solve via Metadata.xml

Hello there,

I'm facing that good old "duplicated p0" problem when binding the SamsungPay SDK to Android and no matter what I put on the Metadata.xml file I always get the same error: <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.enrollment']/class[@name='EnrollmentManager.FailedEventArgs']/constructor[0]/parameter[0]"/> matched no nodes. (BG8A04)

I've binded several other libs and always managed to solve all the issues via Metadata but this case I can't seem to make it work.

I have 30 errors like this from the compiler:

Error CS0102: The type `Com.Samsung.Android.Sdk.Samsungpay.Enrollment.EnrollmentManager.FailedEventArgs' already contains a definition for `p0'

Here's the relevant code:

using System;
using System.Collections.Generic;
using Android.Runtime;

namespace Com.Samsung.Android.Sdk.Samsungpay.Enrollment {

    // Metadata.xml XPath class reference: path="/api/package[@name='com.samsung.android.sdk.samsungpay.enrollment']/class[@name='EnrollmentManager']"
    [global::Android.Runtime.Register ("com/samsung/android/sdk/samsungpay/enrollment/EnrollmentManager", DoNotGenerateAcw=true)]
    public partial class EnrollmentManager : global::Java.Lang.Object {

        public partial class FailedEventArgs : global::System.EventArgs {

            public FailedEventArgs (int p0)
            {
                this.p0 = p0;
            }

            int p0;
            public int P0 {
                get { return p0; }
            }
        }

        public partial class FailedEventArgs : global::System.EventArgs {

            public FailedEventArgs (int p0, string p1)
            {
                this.p0 = p0;
                this.p1 = p1;
            }

            int p0;
            public int P0 {
                get { return p0; }
            }

            string p1;
            public string P1 {
                get { return p1; }
            }
        }
    }
}

Any help is very appreciated.

Thank you

Posts

  • RenatoTodorovRenatoTodorov BRMember

    Hey @JohnMiller, can you shed some light on this issue? There are several other unanswered questions regarding the same problem (Metadata.xml / can't find nodes / duplicated p0 etc). Don't know where to go from here.

    Thank you very much.

  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    @RenatoTodorov

    Can you please upload your current binding to this forum post? As you can see from the code, there are two definitions of int p0 in a class named FailedEventArgs. The best way we workaround this is by renaming the variables/constructor arguments. However your definition is not matching nodes and therefore seems incorrect off first glance.

  • RenatoTodorovRenatoTodorov BRMember

    Hi @JonDouglas , thanks for taking a look at it.

    You can see the project here: https://github.com/RTodorov/samsungpay-android-binding

    I can rename everything manually but I need to find a way to do it via Metadata.xml, right? This is where I'm stuck on because I cannot match any node.

    Thanks!

  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    @RenatoTodorov

    For example there are three duplicates of FailureEventArgs in the PaymentManager class. Then because this is a partial class, there are tons of duplicates everywhere else.

    However the reason this doesn't get picked up, is because it's a C# equivalent of the Java event listener. So there's no actual class inside this .jar for the EventArgs type.

    What you need to do instead is rename the following methods:

    <method abstract="true" deprecated="not deprecated" final="false" name="onFailure" native="false" return="void" static="false" synchronized="false" visibility="public">
    <parameter name="p0" type="int">
    </parameter>
    <parameter name="p1" type="java.lang.String">
    </parameter>
    </method>
    

    and

    <method abstract="true" deprecated="not deprecated" final="false" name="onFailure" native="false" return="void" static="false" synchronized="false" visibility="public">
    <parameter name="p0" type="int">
    </parameter>
    <parameter name="p1" type="android.os.Bundle">
    </parameter>
    </method>
    

    Notice the difference here is one takes a java.lang.String and the other takes a android.os.Bundle.

    You might ask "How the hell do I do that?". Well I would take a step back and look at this .jar. Most of these classes are deprecated. You should just be able to remove them.

    EX: PaymentManager, PaymentInfo, CardInfo, etc in the com.samsung.android.sdk.samsungpay.payment package are all deprecated as there are new ones in the com.samsung.android.sdk.samsungpay.v2.payment package. Thus you should remove these before applying anything. That could end up solving your problem!

  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    Just so you can start working on the other side, you would then need to apply the renames to the v2 package classes:

      <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CardInfoListener']/method[@name='onFailure']/parameter[@name='p0' and @type='int']" name="name">CardInfoListenerP0</attr>
      <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CardInfoListener']/method[@name='onFailure']/parameter[@name='p1' and @type='android.os.Bundle']" name="name">CardInfoListenerP1</attr>
    
  • RenatoTodorovRenatoTodorov BRMember

    Hey @JonDouglas, thank you very much for the help, I'll move forward and let you know if any problems. Otherwise I'll keep the project on Github since it might be useful for others as well.

  • RenatoTodorovRenatoTodorov BRMember
    edited April 2017

    So, I completed the Metadata.xml with all the duplicated classes and arguments and it looks like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <metadata>
    
        <remove-node path="/api/package[@name='com.samsung.android.sdk.samsungpay.enrollment']/class[@name='EnrollmentManager']" />
        <remove-node path="/api/package[@name='com.samsung.android.sdk.samsungpay.payment']/class[@name='PaymentManager']" />
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.card']/interface[@name='GetCardListener']/method[@name='onFail']/parameter[@name='p0' and @type='int']" name="name">GetCardListenerP0</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.card']/interface[@name='GetCardListener']/method[@name='onFail']/parameter[@name='p1' and @type='android.os.Bundle']" name="name">GetCardListenerP1</attr>
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.card']/interface[@name='GetCardListener']/method[@name='onSuccess']/parameter[@name='p0' and @type='java.util.List&lt;com.samsung.android.sdk.samsungpay.v2.card.Card&gt;']" name="name">GetCardSuccessP0</attr>
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CardInfoListener']/method[@name='onFailure']/parameter[@name='p0' and @type='int']" name="name">CardInfoListenerP0</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CardInfoListener']/method[@name='onFailure']/parameter[@name='p1' and @type='android.os.Bundle']" name="name">CardInfoListenerP1</attr>
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.TransactionInfoListener']/method[@name='onCardInfoUpdated']/parameter[@name='p0' and @type='com.samsung.android.sdk.samsungpay.v2.payment.CardInfo']" name="name">TransactionListenerCardInfoUpdatedP0</attr>
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onSuccess']/parameter[@name='p0' and @type='com.samsung.android.sdk.samsungpay.v2.payment.CustomSheetPaymentInfo']" name="name">TransactionListenerSuccessP0</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onSuccess']/parameter[@name='p1' and @type='java.lang.String']" name="name">TransactionListenerSuccessP1</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onSuccess']/parameter[@name='p2' and @type='android.os.Bundle']" name="name">TransactionListenerSuccessP2</attr>
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onCardInfoUpdated']/parameter[@name='p0' and @type='com.samsung.android.sdk.samsungpay.v2.payment.CardInfo']" name="name">CustomSheetListenerCardInfoUpdatedP0</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onCardInfoUpdated']/parameter[@name='p1' and @type='com.samsung.android.sdk.samsungpay.v2.payment.sheet.CustomSheet']" name="name">CustomSheetListenerCardInfoUpdatedP1</attr>
    
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onFailure']/parameter[@name='p0' and @type='int']" name="name">CustomSheetListenerFailureP0</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CustomSheetTransactionInfoListener']/method[@name='onFailure']/parameter[@name='p1' and @type='android.os.Bundle']" name="name">CustomSheetListenerFailureP1</attr>
    
    </metadata>
    

    The thing is, the compiler is still complaining about duplicated parameters because Xamarin named both the private and the public properties the same:

            int GetCardListenerP0;
            public int GetCardListenerP0 {
                get { return GetCardListenerP0; }
            }
    

    What's the trick here to set a different name for the private property?

  • RenatoTodorovRenatoTodorov BRMember

    Nevermind, I renamed all the event args and it worked!

    Here's the final file:

    <?xml version="1.0" encoding="UTF-8"?>
    <metadata>
    
        <!-- Removed deprecated v1 api -->
        <remove-node path="/api/package[@name='com.samsung.android.sdk.samsungpay.enrollment']/class[@name='EnrollmentManager']" />
        <remove-node path="/api/package[@name='com.samsung.android.sdk.samsungpay.payment']/class[@name='PaymentManager']" />
    
        <!-- Renamed EventArgs for all necessary classes -->
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.card']/interface[@name='GetCardListener']/method[@name='onFail' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='android.os.Bundle']]" name="argsType">GetCardListenerFailEventArgs</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.card']/interface[@name='GetCardListener']/method[@name='onSuccess' and count(parameter)=1 and parameter[1][@type='java.util.List&lt;com.samsung.android.sdk.samsungpay.v2.card.Card&gt;']]" name="argsType">GetCardListenerSuccessEventArgs</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CardInfoListener']/method[@name='onFailure' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='android.os.Bundle']]" name="argsType">CardInfoListenerFailEventArgs</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.CardInfoListener']/method[@name='onResult' and count(parameter)=1 and parameter[1][@type='java.util.List&lt;com.samsung.android.sdk.samsungpay.v2.payment.CardInfo&gt;']]" name="argsType">CardInfoListenerResultEventArgs</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.TransactionInfoListener']/method[@name='onCardInfoUpdated' and count(parameter)=1 and parameter[1][@type='com.samsung.android.sdk.samsungpay.v2.payment.CardInfo']]" name="argsType">TransactionCardInfoUpdatedEventArgs</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.TransactionInfoListener']/method[@name='onFailure' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='android.os.Bundle']]" name="argsType">TransactionInfoListenerFailEventArgs</attr>
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2.payment']/interface[@name='PaymentManager.TransactionInfoListener']/method[@name='onSuccess' and count(parameter)=3 and parameter[1][@type='com.samsung.android.sdk.samsungpay.v2.payment.PaymentInfo'] and parameter[2][@type='java.lang.String'] and parameter[3][@type='android.os.Bundle']]" name="argsType">TransactionInfoListenerSuccessEventArgs</attr>
    
        <!-- Changed the visibility of the class "BindRetry" to public so the type is available in the binding -->
        <attr path="/api/package[@name='com.samsung.android.sdk.samsungpay.v2']/class[@name='BindRetry']" name="visibility">public</attr>
    
    </metadata>
    

    Or here: https://github.com/RTodorov/samsungpay-android-binding

    Thanks for the help!

  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    No problem, I suppose I should've sent you my guide earlier!

    https://gist.github.com/JonDouglas/dda6d8ace7d071b0e8cb#common-names

    Glad it all worked out!

  • PeterKerrPeterKerr USMember ✭✭

    @RenatoTodorov did you happen to do the same for Google Pay SDK? Specially for their In-App Provisioning TapAndPay.jar? I have similar errors and not sure what I need to added to the metadata to make it work

Sign In or Register to comment.