I'm looking for a solution to resolve .local host names with Android 4.0.4 (no NSD, due to API level 15). On the device I don't have any service to discover, just the hostname.
Could you please provide an example how to resolve? I integrated the jmDNS, but don't know how to use for host name resolving.
win-cmd:
ping kcmeasurement.local
Pinging kcmeasurement.local [10.202.0.29] with 32 bytes of data:
Reply from 10.202.0.29: bytes=32 time<1ms TTL=64
...
Thank you,
Daniel
I had almost the same requirements as your question, apart from the requirement to use jmDNS, so I solved it with NSD. I realize this doesn't address your question exactly, but thought it might still be somewhat helpful for yourself and others to see how I solved it.
I setup an NSD discovery listener and an NSD resolve listener, and within the discovery listener code, added a filter for the target host name (e.g. "kcmeasurement", or in my case, "garagedoor").
There is a blog post here which explains in detail how to do that. Refer to steps 3-4, which are dealing with the Android App code required.
http://www.dodgycoder.net/2015/02/setting-up-bonjourzeroconfmdnsnsd.html
For your case, I would imagine you would have to do the equivalent process but just using the jmDNS library instead of NSD.
You should be able to use the InetAddress class to resolve the hostname for a given IP address. For example, using the IP address provided in the original question, try the following:
try
{
String hostname = InetAddress.getByName("10.202.0.29").getHostName();
}
catch (UnknownHostException e)
{
Log.e("MyApplication", "Attempt to resolve host name failed");
}
Since this is a network operation, make sure that it is not performed on the UI thread.
EDIT
You should be able to resolve a local hostname with jmDNS as follows:
InetAddress localHost = InetAddress.getByName("10.202.0.29");
JmDNS jmdns = JmDNS.create(localHost);
String localHostName = jmdns.getHostName();
Related
I am running Django on my raspberry-pi, and I am using avahi-daemon to access my rpi on raspberrypi.local . On my Django I have made APIs for my android application to access via HTTP protocol. For example one of my http request url is: http://raspberrypi.local/api/getUserNames/
The problem is that android is not accessing this url on my local wifi network, i have confirmed that my android device and rpi are both connected to same wifi network, but still the http://raspberrypi.local is not working on android. While it works fine on my PC & MAC.
I tried to find the solution and went through many Q&A explaining about bonjour, mDNS, jmDNS, android-multicast. But all are either too confusing to implement or doesn't work. Please help me, I'm stuck for a while.
NOTE: on my Rpi the avahi-daemon is broadcasting itself as "_workstation._tcp." service-type
--
My Solution:
http://www.dodgycoder.net/2015/02/setting-up-bonjourzeroconfmdnsnsd.html
Android NSD (Network Service Discovery) solved my problem. I used only Discovery Listener and Resolve Listener to solve my purpose.
I specifically used SERVICE_TYPE = "_workstation._tcp."; in order to search for raspberrypi.local with avahi-daemon
Android NSD (Network Service Discovery) solved my problem. I used only Discovery Listener and Resolve Listener to solve my purpose.
NOTE- You'll have to use SERVICE_TYPE = "_workstation._tcp."; in order to search for raspberrypi.local with avahi-daemon
here's link to the solution - http://www.dodgycoder.net/2015/02/setting-up-bonjourzeroconfmdnsnsd.html
From old posts such as Android java.net.UnknownHostException: Host is unresolved (strategy question), it suggested to use the following code:
try {
InetAddress i = InetAddress.getByName(URLName);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
So does it mean when a DNS entry is not being cached in the device, e.g. after bootup, it will return java.net.UnknownHostException: Host for the 1st time, even for a valid DNS?
It depends on the version of android.
Provided you have an Internet connection and that your application declares that it needs Internet access in the manifest file, then the address should resolve without any problems.
http://developer.android.com/reference/java/net/InetAddress.html
In Android 4.0 (Ice Cream Sandwich) and earlier, DNS caching was performed both by
InetAddress and by the C library, which meant that DNS TTLs could not be honored
correctly. In later releases, caching is done solely by the C library and DNS TTLs
are honored.
So if the address you are asking for is not older than the time to live, the cache will answer. If it is not in the cache or has expired then the OS will try to find it by going to a DNS server. The exception is thrown only when your Internet connection is not up, or when there is no DNS response, not when the cache request fails.
That said, if you are writing your application for older androids, then this problem may pester you still.
There are ways to deal with it:
Android: Flush DNS
I need to get my app to play a video file located on my network. I know the url of the file is:
http://something.local/abc.mp4
Now, when I manually substitute "something.local" with its true ip address, the MediaPlayer has no problem playing it. Nonetheless, when I have the above address, the MediaPlayer errors out with error (1, -1007).
So I'm assuming this is because Android doesn't understand "something.local" as being correct.
My question is: How can I "translate" something.local into an ip myself, so that I can then pass it into MediaPlayer?
A small caveat: I believe that MediaPlayer does not work with IPv6 addresses, so please keep that in mind...
Just a side note, in case it makes my situation clearer: When I run ping something.local -4 in the Windows command prompt, it returns:
Pinging something.local [192.168.1.126] with 32 bytes of data:
Reply from 192.168.1.126: bytes=32 time=145ms TTL=64
Reply from 192.168.1.126: bytes=32 time=112ms TTL=64
Reply from 192.168.1.126: bytes=32 time=32ms TTL=64
Reply from 192.168.1.126: bytes=32 time=169ms TTL=64
That translation where windows went from something.local -> 192.168.1.126 is what I want to do in my Android app.
Firstly, you need read document about Bonjour (iOS term) or Zero Config (Linux term).
To understand what's something.local:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/NetServices/Articles/about.html#//apple_ref/doc/uid/TP40002458-SW1
For example, if a user types steve.local. into a Web browser, this
tells the system to multicast the request for steve on the local
network instead of sending it to the conventional DNS server. If a
Bonjour-enabled computer named steve is on the local network, the
user’s browser is sent the correct IP address for it. This allows
users to access local hosts and services without a conventional DNS
server.
For how to resolve it:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/NetServices/Articles/NetServicesArchitecture.html#//apple_ref/doc/uid/20001074-SW1
For java library, previous answers provided good enough example.
You should try this snippet with jmDNS library api.. may need some changes.
JmDNS jmdns = JmDNS.create();
DNSEntry addressEntry = jmdns.getCache().getDNSEntry(name, DNSRecordType.TYPE_A, DNSRecordClass.CLASS_ANY);
if (addressEntry instanceof DNSRecord) {
ServiceInfo cachedAddressInfo = ((DNSRecord) addressEntry).getServiceInfo(true);
if (cachedAddressInfo != null) {
for (Inet4Address address : cachedAddressInfo.getInet4Addresses()) {
// use the `address`
}
}
You have access to java,net APIS on android and can use them to resolve adresses.
http://docs.oracle.com/javase/1.4.2/docs/api/java/net/InetAddress.html
However, success will depend on network proper configuration. Your device receives DNS server setup via DHCP - so you are at mercy of network provider
I want to make use of my own DNS on Android in general. Whether the IP is static or taken via DHCP. So I put the
Settings.System.putString(getContentResolver(), Settings.System.WIFI_STATIC_DNS1, mIP);
But then I suppose it works only for static IP.
How can I override the DNS setting for every case?
Thanks in advance,
Mike
An alternate solution may be to have your application perform the DNS lookups itself using:
DNS Service Provider for the Java Naming Directory Interface™ (JNDI)
How do I get the MAC-Address of the network interface of an android device which doesn't have a Wifi-Interface (e.g. the android emulator)? WifiInfo obtained via the WifiManager returns null.
EDIT
To be more clear: I have to communicate with an existing network protocol (not designed by me) on the local network where I have to send the mac address of the communicating interface within the payload during a registration phase.
I'm going to take a leap and assume that you want this MAC address in order to establish a unique identifier for the device. Mac Addresses are not the way to do this.
There's an Android Developer Blog post titled "Identifying App Installations" which covers the topic of generating unique ID's fairly well, including the popular methods, and the pros/cons. It's definitely worth a read. Quite relevant to this post is the following quote:
It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address.
The options available to you instead include TelephonyManager.getDeviceId(), android.os.Build.SERIAL, and Settings.Secure.ANDROID_ID, all of which are covered in more detail in the linked post.
Read /sys/class/net/[something]/address as a text file
But it's unlikely to be useful in the way you think.
See this post where I have submitted Utils.java example to provide pure-java implementations.
Utils.getMACAddress("wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6
What is the network interface you want the MAC address of? If there's no wifi, you certainly can't get the wifi device's MAC address. It represents the physical hardware and if that's not present, it simply doesn't exist.
To get wifi MAC of android device using adb:
adb shell getprop ril.wifi_macaddr
Use the following code in Java to get it programmatically:
Process p = Runtime.getRuntime.exec("adb", "shell", "getprop", "ril.wifi_macaddr")
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream());
String macAddress = br.readLine();