Search code examples
c#androidxamarinxamarin.androidjmdns

Xamarin.Android JmDNS binding issues


I started work on a JmDNS bindings for Xamarin.Android. I managed to get the binding to build but I can not reference it from within my code. https://github.com/ytn3rd/monodroid-bindings/tree/master/JmDNS

First issue I had was there was no IDNSListener class to reference. So I added a partial interface in there for it. I have the function it needs void updateRecord(DNSCache dnsCache, long now, DNSEntry record); commented out as it would complain on not being able to reference DNSCache or DNSEntry. (I believe I removed DNSCache and thats why)

Not sure if some of the things I have done were bad, just removing nodes to get it to compile. For instnace. I added this to remove to following errors.

E:\Users\brads_000\Documents\GitHub\ytn3rd\monodroid-bindings\JmDNS\bindings\obj\Debug\generated\src\Javax.Jmdns.Impl.JmDNSImpl.cs(24,24): Error CS0738: 'Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry' does not implement interface member 'Java.Util.IMapEntry.Key'. 'Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry.Key' cannot implement 'Java.Util.IMapEntry.Key' because it does not have the matching return type of 'Java.Lang.Object'. (CS0738) (JmDNS-Bindings) E:\Users\brads_000\Documents\GitHub\ytn3rd\monodroid-bindings\JmDNS\bindings\obj\Debug\generated\src\Javax.Jmdns.Impl.JmDNSImpl.cs(24,24): Error CS0738: 'Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry' does not implement interface member 'Java.Util.IMapEntry.Value'. 'Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry.Value' cannot implement 'Java.Util.IMapEntry.Value' because it does not have the matching return type of 'Java.Lang.Object'. (CS0738) (JmDNS-Bindings)

Issue is from the Java.Util.IMapEntry class. I thought correct action would be to create my own parital SubEntryType and then override the string Key property but it would not pick it up. My next attempt was to do this.

Java.Lang.Object

Which would resolve that error, but would then cause an error with

E:\Users\brads_000\Documents\GitHub\ytn3rd\monodroid-bindings\JmDNS\bindings\obj\Debug\generated\src\Javax.Jmdns.Impl.JmDNSImpl.cs(12,12): Error CS1502: The best overloaded method match for 'Android.Runtime.JNIEnv.NewString(string)' has some invalid arguments (CS1502) (JmDNS-Bindings)

static IntPtr n_GetKey (IntPtr jnienv, IntPtr native__this)
{
    global::Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry __this = global::Java.Lang.Object.GetObject<global::Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
    return JNIEnv.NewString (__this.Key);
}
namespace Javax.Jmdns.Impl
{
    public partial class SubTypeEntry
    {
        static IntPtr n_GetKey (IntPtr jnienv, IntPtr native__this)
        {
            global::Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry __this = global::Java.Lang.Object.GetObject<global::Javax.Jmdns.Impl.JmDNSImpl.SubTypeEntry> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            return JNIEnv.NewString(__this.Key.ToString());
        }
    }
}

But again, it does not want to pick this new method up.

I removed javax.jmdns.impl.DNSCache because of same errors with Key/Value as above and,

E:\Users\brads_000\Documents\GitHub\ytn3rd\monodroid-bindings\JmDNS\bindings\obj\Debug\generated\src\Javax.Jmdns.Impl.DNSCache.cs(95,95): Error CS0508: 'Javax.Jmdns.Impl.DNSCache.EntrySet()': return type must be 'System.Collections.ICollection' to match overridden member 'Java.Util.AbstractMap.EntrySet()' (CS0508) (JmDNS-Bindings)

Which I seemed to have fixed with

System.Collections.ICollection

Even though it is what it was already returning.
public override global::System.Collections.Generic.ICollection EntrySet ()

Anyway, any help would be appreciated to get this awesome library up and running :)


Solution

  • I was able to build it the binding project correctly. To build it correct please try with the following approach.

    1.Rebuild the jar file from the jmdns-3.4.1 source. Make the DNSListener interface public. Remove the test packages. Then export the source to get the updated jar file.

    2.Update the jar file created from step 1. Make sure to update the build action to EmbededJar.

    3.EnumMethods.xml

    <enum-method-mappings>
      <mapping jni-class="javax/jmdns/impl/DNSCache">
        <method jni-name="entrySet" parameter="return" clr-enum-type="System.Collections.ICollection" />
      </mapping>
    
      <mapping jni-class="javax/jmdns/impl/DNSCache._CacheEntry">
        <method jni-name="getKey" parameter="return" clr-enum-type="Java.Lang.Object" />
      </mapping>
    
      <mapping jni-class="javax/jmdns/impl/DNSCache._CacheEntry">
        <method jni-name="getValue" parameter="return" clr-enum-type="Java.Lang.Object" />
      </mapping>
    
      <mapping jni-class="javax/jmdns/impl/JmDNSImpl.ServiceTypeEntry.SubTypeEntry">
        <method jni-name="getKey" parameter="return" clr-enum-type="Java.Lang.Object" />
      </mapping>
    
      <mapping jni-class="javax/jmdns/impl/JmDNSImpl.ServiceTypeEntry.SubTypeEntry">
        <method jni-name="getValue" parameter="return" clr-enum-type="Java.Lang.Object" />
      </mapping>
    
      <mapping jni-class="javax/jmdns/impl/JmDNSImpl.ServiceTypeEntry">
        <method jni-name="entrySet" parameter="return" clr-enum-type="System.Collections.ICollection" />
      </mapping>
    
    </enum-method-mappings>
    

    4.In your sample app you have to add one more permission as android.permission.ACCESS_WIFI_STATE.

    5.Also all the network operation should be performed from a background thread and notify UI in Main thread. So update your MainActivity class accordingly.

    Hope this will help you to create the build correctly. The working copy of the sample code is uploaded here https://github.com/Hitangshu/JmDNS_Xamarin_Library